0

我正在处理 x86 汇编语言作业,但不明白测试操作究竟如何影响进位、零和符号标志。据我了解,我们正在AND对两个操作数进行按位比较。在第一个示例中,位 1、2、3、4 和 7 匹配。这是否意味着结果AND是11110010?这会将符号标志设置为负值吗?不会设置零标志,因为这个二进制结果不是 0。进位标志呢?我不确定如何进行。谢谢您的帮助。

mov al,00001111b
test al,00000010b ; a. CF= ZF= SF=<br><br>

mov al,00000110b
cmp al,00000101b  ; b. CF= ZF= SF=<br><br>

mov al,00000101b
cmp al,00000111b  ; c. CF= ZF= SF=<br><br>
4

1 回答 1

4

正如您所写,x86TEST操作执行按位AND操作。您应该再次检查 AND 的真值表:

INPUT   OUTPUT
A   B   A AND B
0   0       0
0   1       0
1   0       0
1   1       1

TEST将对 src 和 dst 操作数中的每 2 个对应位执行此操作,因此只有1两者中的位才会成为1结果:00001111b & 00000010b将简单地给出00000010b.

对标志的影响现在很容易看到 - ZF=0 因为结果非零,SF=0 因为结果 MSB 关闭,CF=0 因为 TEST 不会设置它(这是一个逻辑操作,不是算术的)。

顺便说一句,TEST随着操作的进行,它非常便宜,所以你可能会注意到它经常被用作简单的零检查 -TEST RAX, RAX会和 RAX 对自身进行注册(当然会产生相同的值),所以你有一个很好的方法来检查是否RAX 为零(例如,je紧随其后的分支使用)或负数(通过将 SF 与js分支一起使用)

现在,其他 2 个问题处理另一个操作 -CMP进行实际减法(它与 做相同的事情SUB,但也丢弃结果,仅更新标志)。

  • 第一个将计算00000110b - 00000101b = 00000001bZF=SF=0(出于与上述相同的原因)和 CF=0,因为我们不需要进位/借位。

  • 第二个将计算00000101b - 00000111b = 11111110(对于 的二进制补码表示5 - 7 = -2),如上所述,ZF 仍然为 0,但这次你会看到 SF=1,因为我们得到了一个否定的结果,所以 MSB 开启,CF=1,因为计算做了一个“借”给MSB。

这里有一点关于 CF 及其对应的 OF(溢出标志)的要点 - 数字只是数字,它们并不意味着有符号或无符号值,直到您决定使用它们。然而 x86 必须为任何可能性维护正确的标志,所以它基本上使用 CF 进行无符号操作,实际上意味着最后一个操作5 - 7 = 254就像你“借”了一个额外的位到 MSB(这就是 CF=1 标记在这里)。OF 不会被设置,因为如果您将这些完全相同的操作视为有符号算术,那么您确实已经完成了5 - 7 = -2完全合法的操作并且没有上溢/下溢。

另一方面,像这样的操作127 + 127 = 254会做相反的事情,它不会切换 CF(因为如果您将其视为无符号算术,则不会发生任何坏事),但 OF 将被设置,因为如果这些是有符号值,您我刚刚说过127 + 127 = -2这显然是错误的,因为溢出超过了一个字节可以存储的最大有符号值 (127)

于 2013-10-12T23:33:51.057 回答