Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Assembly 什么时候设置进位标志?_Assembly_X86_Carryflag_Eflags - Fatal编程技术网

Assembly 什么时候设置进位标志?

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指令应用于非零”是什么意思 操作数始终设置进位标志。“

为什么从1中减去2会设置进位标志? 00000001 (1) +11111110(-2)[以2-补语形式] --------------------- CF:11111111(-1)[为什么在这里设置进位标志??]

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

  • 首先,我们知道当a
    a
    时,
    a-b
    总是能产生a

  • 其次,让我们了解为什么x86在进行减法运算时会反转进位标志。
    对人类来说,第一点是显而易见的,但对计算机来说就不是这样了。(假设计算机使用
    a+(~b+1)
    来代替
    a-b
    来进行计算。)计算机是如何计算出有一个借来的?我们可以将2的补码作为时钟。(顺时针表示原始数字--
    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完全不同。请注意,x86
sub
标志设置并不完全等同于
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.