繁体   English   中英

为什么CMP(比较)有时会在8086汇编中设置进位标志?

[英]Why does CMP (compare) sometimes sets a Carry Flag in 8086 assembly?

我一直在阅读并使用8086指令集,它说CMP(比较)可以设置进位标志。 我知道比较会减去两个操作数,但我想知道是否有人可以在这种情况下提供一个例子。

我只是无法掌握添加数字和负数的想法会设置进位标志。 我已经阅读了借旗,但我只需要一个例子来澄清我对比较指令的理解。

另外,据我所知,如果3 - 5 = -2会设置负标志...何时进位?

  • 进位标志在导致下溢或溢出的操作之后设置。 例如,从6减去10将导致下溢并设置进位标志。 类似地,将1添加到寄存器的最大值将导致溢出并设置进位标志。
  • 进位标志也在移位操作期间被修改,它被设置为从目标寄存器移出的最后一位的值。
  • 位测试将测试位的值放入进位标志。 执行此操作的操作码:BT,BTC,BTR和BTS。
  • 直接影响Carry Flag的说明:CLC,CMC和STC。
  • 在比较期间,进位标志被设置,就好像已经减去了两个操作数一样。
  • 在否定(NEG)期间,除非操作数为零,否则设置进位标志,在这种情况下它被清除。

通常在使用无符号算术时设置进位标志。 例如,添加两个无符号(其结果不适合寄存器)数字不会引发溢出标志但只携带标志。 但是,使用带符号算术时,会在这种情况下设置溢出标志。

您可以在相关问题的答案中找到有关何时将进位和溢出标志设置为0和1的示例,其中加上或减去整数。
你也可以找到样本C代码,用8位数字的借位指令模拟带有进位和减法的加法,你可以使用它,也许可以得到更多的例子。

输出格式有这样的:
127( 127) - 255( -1) - 1 = 127( 127) CY=1 OV=0
其中每个数字都表示为无符号和带括号的括号(2的补码)。 =之前的数字是ADC / SBB之前的进位标志。 CY=OV=显示AD​​C / SBB后的进位和溢出标志。

比较与没有借位的减法几乎完全相同,除了它只影响进位,溢出,符号和零标志(以及奇偶校验和辅助进位,但它们在这里不重要)而不修改寄存器/存储器中的任何数字。

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,因此未设置进位。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM