简而言之,给出相同结果的操作并不总是等价的操作。因此,您的假设 0011 - 0011 = 0011 + 1100 + 0001 并且将具有相同的进位标志值 - 是错误的
虽然 A + (~B + 1) 给您的结果与 A - B 相同,但它并不相同,并且不会以相同的方式更新标志。
事实上,你忘记了一件事。在你的例子中:
0011 + 1100 + 0001 = 0000 - 错了。因为 0011 + 1100 + 0001 = 10000
在考虑二进制补码溢出时,您忘记了 A + (~B + 1) 仅等于 A - B。
现在您可以看到进位标志在这两种操作中是非常相反的。事实上,当 A - B 没有借位(下溢)时,A + ~B + 1 才会出现溢出(在第一次或第二次加法中)。
进行加法C标志时表示溢出发生,即从最左边的位开始执行。
即如果要添加:
0110
+ 1101
----
10011
^^^^ the result
^ the carry flag
也就是说,如果你对一个较长的数字进行加法,由几个寄存器组成,你必须在较高的部分加一。例如
add r16, r18 // adds r18 to r16, C flag is set only when overflow happened
adc r17, r19 // adds r19 to r18, and add one if C flag is set. updates the C flag by the overflow again
// in result r17:r16 = r17:r16 + r19:r18
减法时,C标志表示从最左边的位开始借位,因此数字的高位应减一
* * - borrow positions
0110
- 1101
----
0001
^ carry flag is set when borrowed at left from the leftmost positions.
在汇编程序中你有 sbc 指令,它将减法作为 sub 指令,但如果设置了进位标志,则结果减一
sub r16, r18 // subtracts r18 from r16, C flag is set only when underflow happened
sbc r17, r19 // subtracts r19 from r18, and subtracts one more if C flag is set. updates the C flag by the underflow again
// in result r17:r16 = r17:r16 - r19:r18
所以,回答你的问题:当你从自身减去数字时,进位标志的值被清除,因为没有发生下溢。
AVR 架构具有简单的分支机制。它有 8 个标志位,每个分支指令只根据其中一位的值进行分支。
所以,BRLO 和 BRCS 都是相同机器码的助记符,如果设置了进位标志,则会进行分支。仅当您从较低的无符号值中减去较高的无符号值时,才会设置进位标志。
如果要进行有符号比较,则必须使用BRLT 指令,该指令查看S 标志,等于标志N 和V 的异或。 N 标志在运算结果为负符号数时设置(设置高位)。 V 标志表示已发生签名溢出。它们的异或组合表示从较小的数字中减去较大的有符号数。