6

“将 NEG 指令应用于非零操作数始终设置进位标志”是什么意思。

为什么从 1 中减去 2 会设置进位标志?

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

4 回答 4

5

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

于 2013-07-21T19:26:43.810 回答
1
  • 首先,我们知道什么时候a < ba - b总是可以产生一个进位(

  • 其次,让我们了解为什么x86在减法时会反转进位标志。
    第一点对于人类来说是如此明显,但对于计算机而言并非如此。(假设用电脑a + (~b+1)来代替a - b做计算。)电脑怎么算出有借?我们可以将 2 的补码作为时钟。(顺时针表示原数 -- a,逆时针表示倒数 -- ~b+1
    在此处输入图像描述
    所以对于计算机来说,它可以告诉(用于减法)如果a > ba + ~b + 1将有进位(图中重叠);如果a < b,a + ~b + 1没有进位(图中的间隙)。

  • 结论:
    所以对于减法,如果没有进位,则表示有借位;如果有进位意味着没有借位,即反转进位位。

顺便说一句,据我尝试,没有溢出(OF未设置when 1 - 2。)我不认为@Oliver 在这一点上是正确的。

于 2015-03-29T13:30:06.383 回答
1

在阅读 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”。

可能这就是为什么我们在标志寄存器中有“进位标志”而不是“进位位”的原因。再次 - 进位标志表明操作数(视为无符号)的操作结果超出特定位数的允许“无符号范围”。

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

这里的关键点是:'carry FLAG' 不是 'carry 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 的文档调用进位标志 -进位/借位标志,因此不应将其视为进位位

于 2017-05-18T12:19:38.407 回答
0

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

1 - 2给出的结果将以无符号 8 位格式表示-1-1不能表示,因此设置了进位标志。

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

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

NEG n与计算相同0-n,这里唯一适合无符号 8 位数的结果是00000000. 任何其他结果都不是正确的无符号数。

于 2015-03-29T13:46:07.603 回答