Assembly 什么时候设置进位标志?
“将NEG指令应用于非零”是什么意思 操作数始终设置进位标志。“ 为什么从1中减去2会设置进位标志? 00000001 (1) +11111110(-2)[以2-补语形式] --------------------- CF:11111111(-1)[为什么在这里设置进位标志??]Assembly 什么时候设置进位标志?,assembly,x86,carryflag,eflags,Assembly,X86,Carryflag,Eflags,“将NEG指令应用于非零”是什么意思 操作数始终设置进位标志。“ 为什么从1中减去2会设置进位标志? 00000001 (1) +11111110(-2)[以2-补语形式] --------------------- CF:11111111(-1)[为什么在这里设置进位标志??] 您可以将NEG a视为等同于SUB 0,a。如果a为非零,则将设置进位标志(因为这将始终导致无符号溢出)。 首先,我们知道当aab,a+~b+1将有进位(在图片中重叠);如果a
您可以将
NEG a
视为等同于SUB 0,a
。如果a
为非零,则将设置进位标志(因为这将始终导致无符号溢出)。- 首先,我们知道当a
时,a
总是能产生aa-b
- 其次,让我们了解为什么x86在进行减法运算时会反转进位标志。
对人类来说,第一点是显而易见的,但对计算机来说就不是这样了。(假设计算机使用
来代替a+(~b+1)
来进行计算。)计算机是如何计算出有一个借来的?我们可以将2的补码作为时钟。(顺时针表示原始数字--a-b
,逆时针表示反转--a
)~b+1
因此,对于计算机来说,它可以判断(对于减法)如果
,a>b
将有进位(在图片中重叠);如果a+~b+1
,a
将不带进位(图片中的间隙)a+~b+1
- 结论:
所以对于减法,如果没有进位,就意味着有借入; 如果有进位,则表示没有借用(反转进位)
顺便说一句,据我所知,没有溢出(即,
1-2
时不设置OF
),我认为@Oliver在这一点上是不对的。当结果不能用无符号的二进制数表示时,就会设置减法中的进位标志。无符号数字始终被视为正数
1-2
给出的结果将是-1
,但-1
不能以无符号8位格式表示,因此,设置进位标志
即使减法算法的结果适合8位,并且即使该结果可以解释为具有正确结果的2补二进制数,也会发生这种情况
NEG
指令用于将被解释为2-补码的数字,因为指令所做的正是对该数字进行2-补码,即改变其符号。符号是2-补数的属性,而不是无符号数的属性
NEG n
与计算0-n
相同,这里唯一适合无符号8位数字的结果是00000000
。其他结果将不是一个正确的无符号数。直到我们了解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的AVRs中的示例相同
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调用进位标志-进位/借位标志,因此不应将其视为进位位,因为规范规定它是这样做的。(您正在做的是从零减去1。这会导致高阶位中出现“借用”。借用和进位是相同的,只是不同。)当操作结果太大而无法放入您正在使用的寄存器时,会设置进位标志。我不明白为什么在这种情况下它太大。“您正在做的是从零减去1。”我在零上加1,最后得到八个1;)对于减法,进位标志充当借用标志。由于
1-2
为负数,因此会产生借阅-因此,设置进位标志。为什么这样做有意义?@user2453180:您熟悉进位标志的用途吗?你熟悉减法时的设置吗?我不明白为什么'11111111'(8个数字)不能放在8位寄存器中。进位标志是按定义反转的。在x86上使用减法时?arm和mips如何?@user2453180:在您的1-2示例中,只要您调整进位标志的计算方式,可以将其建模为1+(-2)的假设是有效的。请记住,如果您执行了长减法(即0001-0010),您将生成一个借阅。所以从这个意义上说,是的,它是反向的。在x86上,CF是来自CMP/SUB的借用输出。在ARM上,它是反向的:它设置为“无借用”,在借用传播到顶部位时清除。因此,ARM在设置减法进位标志的方式上与x86完全不同。请注意,x86sub
标志设置并不完全等同于add
with-src
。例如,将子a、b
模拟为负b
/添加a、b
/cmc
不适用于b=0
sub a,0
总是清除CF,但添加a,0也会清除CF,因此反转CF结果是错误的。(即,~0+1
包装回0是一种特殊情况,您必须处理该操作。)请参阅
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.