Assembly 相等数字的AVR减法是否设置SREG C标志?

Assembly 相等数字的AVR减法是否设置SREG C标志?,assembly,avr,integer-arithmetic,Assembly,Avr,Integer Arithmetic,简短背景: BRLO(如果较低,则为分支)指令声明为 1.如果C-flag==1,则执行分支; 2.如果Rd

简短背景: BRLO(如果较低,则为分支)指令声明为 1.如果C-flag==1,则执行分支; 2.如果Rd 我的问题: 我将使用4位数字进行演示。假设Rd=Rs=3=0011。从上面的第2点来看,分支不应该发生。CP指令执行Rd-Rr。如果我们用2的补码做减法,我们就有了 0011 - 0011 = 0011 + 1100 + 0001 = 0000 使用C标志=1。因此,上文第1点与第2点相矛盾

假设我错了:我在哪里搞砸了


谢谢

简而言之,给出相同结果的操作并不总是等价的操作。因此,您的假设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+1将有溢出(在第一次或第二次加法中),并且只有在A-B没有借用(下溢)时才会有溢出

执行加法时,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标志表示从最左边的位的左边借用,因此,数字的较高部分应减少1

 *  *  - borrow positions
  0110
- 1101
  ----
  0001
 ^ carry flag is set when borrowed at left from the leftmost positions.
在汇编程序中,有
sbc
指令,它将减法作为
sub
指令,但如果设置了进位标志,则将结果减少1

 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
标志表示已发生签名溢出。它们的异或组合表示从较小的有符号数中减去较大的有符号数。

x-x
不设置
CF
,因为没有溢出。是的,加法将设置它,并且有一些体系结构,其中
CF
的含义确实与减法相反。AVR不是其中之一。另请参阅指令集参考,其中指出“[CF]如果Rr内容的绝对值大于Rd的绝对值,则设置;否则清除。”