“将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???]
答案 0 :(得分:4)
您可以将NEG a
视为等同于SUB 0, a
。如果a
非零,那么这将设置进位标志(因为这将始终导致无符号溢出)。
答案 1 :(得分:0)
首先,我们知道a < b
,a - b
何时可以生成carry(Borrow)。
其次,让我们理解为什么x86在减去时会反转进位标志
第一点是人类如此明显,但计算机却不是这样。 (假设计算机使用a + (~b+1)
替换a - b
进行计算。)计算机如何计算借用?我们可以将2的补码作为时钟。(顺时针方向表示原始数字 - a
,逆时针表示反转 - ~b+1
)
因此,对于计算机,它可以告诉(对于减法)a > b
,a + ~b + 1
是否有进位(图片中重叠);如果a < b
,a + ~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