进位标志何时设置?

时间:2013-07-21 19:22:41

标签: assembly carryflag

“将NEG指令应用于非零指示”是什么意思 操作数总是设置Carry标志。“

Why does substracting 2 from 1 set the carry flag?

           00000001 (1)
 +         11111110 (-2) [in 2-complement form]
 ---------------------
CF:1       11111111 (-1) [ why is the carry flag set here???]

4 个答案:

答案 0 :(得分:4)

您可以将NEG a视为等同于SUB 0, a。如果a非零,那么这将设置进位标志(因为这将始终导致无符号溢出)。

答案 1 :(得分:0)

  • 首先,我们知道a < ba - b何时可以生成carry(Borrow)

  • 其次,让我们理解为什么x86在减去时会反转进位标志 第一点是人类如此明显,但计算机却不是这样。 (假设计算机使用a + (~b+1)替换a - b进行计算。)计算机如何计算借用?我们可以将2的补码作为时钟。(顺时针方向表示原始数字 - a,逆时针表示反转 - ~b+1
    enter image description here
    因此,对于计算机,它可以告诉(对于减法)a > ba + ~b + 1是否有进位(图片中重叠);如果a < ba + ~b + 1带有(图片中的差距)。

  • 结论:
    因此对于减法,如果没有进位意味着有借款; 如果有进位意味着没有借用,即反转进位。

顺便说一句,据我所知,没有溢出(OF未设置 1 - 2。)我不认为@奥利弗在这一点上是正确的。

答案 2 :(得分:0)

只要结果无法用无符号二进制数表示,就会设置减法中的进位标志。无符号数始终被视为正数。

1 - 2给出的结果为-1,但-1无法以无符号8位格式表示,因此,进位标志已设置。

即使减法算法的结果符合8位,即使该结果可以被解释为具有正确结果的2补码二进制数,也会发生这种情况。

NEG指令用于与将被解释为2补码数的数字一起使用,因为指令所做的正是对该数字进行2补码,即改变其符号。符号是2补码数的属性,而不是无符号数。

NEG n与计算0-n相同,唯一符合无符号8位数的结果是00000000。其他结果将不是一个正确的无符号数。

答案 3 :(得分:0)

目前还不清楚是否会读取CF标志的定义方式。英特尔CPU文档手册说:

If the result of an arithmetic operation is treated as an unsigned integer, 
the CF flag indicates an out-of-range condition

否定被视为无符号的任何内容显然都是无效的,因为没有无符号值可以使其符号翻转并仍然保持无符号(除非它为零)。 因此,尽管使用铅笔和纸张方法,你得到完全相反的结果:'否则为零时铅笔进位= 1',否定任何其他位模式时'铅笔进位= 0'。

这可能就是为什么我们在标志寄存器中有'携带FLAG '而不是'携带BIT '。 再次 - 进位标志在那里表示对操作数(被视为无符号)的操作结果超出特定位数的允许'无符号范围'。

如果您否定的值被视为已签名 - 您应该查看溢出标记。

这里的关键点是:'携带FLAG'不是'携带BIT'。它有时会像一个人一样,但并非总是如此。

顺便说一句:并非只有x86 / 64才能做到这一点。例如,在Atmel的AVR中也是如此。

ARM可能会这样做,因为他们的手册说:

For a subtraction, including the comparison instruction CMP and the negate 
instructions NEGS and NGCS, C is set to 0 if the subtraction produced a 
borrow (that is, an unsigned underflow), and to 1 otherwise.

一般来说,ARM的doc调用Carry Flag - 一个进位/借用标志所以它不应该被视为携带 BIT