我一直在阅读并使用8086指令集,它说CMP(比较)可以设置进位标志。我知道比较会减去两个操作数,但我想知道是否有人可以提供一个例子。
我只是无法掌握添加数字和负数的想法会设置进位标志。我已经阅读了借旗,但我只需要一个例子来澄清我对比较指令的理解。
另外,据我所知,如果3 - 5 = -2会设置负标志...何时进位设置?
答案 0 :(得分:6)
答案 1 :(得分:2)
使用无符号算术时,通常会设置进位标志。例如,添加两个无符号(其结果不适合寄存器)数字不会引发溢出标志但只携带标志。但是,使用带符号算术时,会在这种情况下设置溢出标志。
答案 2 :(得分:1)
您可以找到在this answer中将{{3}}中的整数加到或减去相关问题后,进位和溢出标志设置为0和1的示例。
您还可以找到样本C代码,使用进位和减法来模拟带有8位数字的借位指令的加法,您可以使用它,也许可以获得更多示例。
输出格式如下:
127( 127) - 255( -1) - 1 = 127( 127) CY=1 OV=0
其中每个数字都表示为无符号和带括号的括号(2的补码)。 =
之前的数字是ADC / SBB之前的进位标志。 CY=
和OV=
显示ADC / SBB后的进位和溢出标志。
比较与没有借位的减法几乎完全相同,除了它只影响进位,溢出,符号和零标志(以及奇偶校验和辅助进位,但它们在这里不重要)而不修改寄存器中的任何数字/存储器中。
答案 3 :(得分:0)
https://www.hellboundhackers.org/articles/read-article.php?article_id=729
作为一个简短的总结,我写这篇文章有两个目的。首先,它很有趣,而且对计算机工作原理的更多了解总是有帮助的。其次,总会有程序直接操作标志,并且知道它们对跳跃的影响是有帮助的。例如,简单的事情 CMP eax,ebx JC某处 可能会混淆大多数开始的反向者,但希望不会在本文之后。享受:)
[重要说明:当我写出二进制数字时,我将使用8位整数作为我的例子。请记住,虽然8位整数在编程中并不常用,但我讨论的相同规则适用于具有更多位的整数]
CMP指令:
CMP指令通过执行两个操作数的隐含减法来操作。这意味着结果不会存储在内存中。减去它们之后,它会做一些快速测试,更新Z,O,C,S和P标志。 P或奇偶校验标志很少使用,因此为了简洁起见,我们将在本文中忽略它。
通过从第一个操作数添加第二个操作数的否定版本来执行二进制减法。这就像你在中学学到的那样,关于4 + 3 = 4 - ( - 3),反之亦然。 在文章的最后,我将解释如何完成这项工作,但我现在将转向更重要的事项,因为破解或编码并不真正需要这些知识。
签名和零旗:
CMP指令可以设置的四个标志--Z,O,C和S分别称为零,溢出,进位和符号标志。只要减法的结果等于零,就设置零标志。当然,这仅在操作数相等时才会发生。当减法的结果为负时,设置符号标志。虽然我们倾向于认为这意味着符号标志与零标志组合足以测试所有> > =<并且< =,这不是真的,因为即使第一个数大于第二个数,结果也可能是负的。这是因为溢出。
溢出标志:
有符号整数用二进制表示,其位数与无符号整数相同。当然,这意味着必须在整数的一个位中设置符号。有符号整数将符号存储在MSB中(最重要的位)。这意味着,当00000001以十进制转换为1时,10000001转换为-127。我将在文章中讨论为什么它是-127而不是-1或-2。 当处理器执行减法时,如果减法低于00000000或高于11111111,它会回绕。因此,如果从正数减去负数,或从负数减去正数,则答案可能会溢出边界。例如,100 - (-100)等于200,但8位有符号整数的最高值可以是127,因此200将通过上边界并最终作为负数,即使它应该是正数。 -100 - 100会出现同样的问题;当它应该为负时,它会穿过低端并最终为正,导致下溢。请注意,下溢也设置溢出标志,溢出将引用文章中的进一步溢出和下溢。 CPU检查这一点,并设置溢出标志(如果发生)。
携带旗帜:
当两个操作数被解释为无符号整数时,第一个更大,则设置进位标志。这很容易确定,因为每当减法通过00000000进入更高范围(11111111)时就会发生这种情况。 例如,00000001 - 00000010 = 11111111,因此设置了进位。但是,00000010 - 00000001 = 00000001,因此未设置进位。