【问题标题】:x86 assembly Language - TEST operation and its effect on flagsx86 汇编语言 - 测试操作及其对标志的影响
【发布时间】:2013-10-12 23:13:44
【问题描述】:

我正在处理 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>

【问题讨论】:

标签: assembly x86 flags


【解决方案1】:

正如您所写,x86 TEST 操作执行按位 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 的位才会在结果中变为 100001111b &amp; 00000010b 只会给出 @987654328 @。

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

顺便说一句,TEST 在操作过程中非常便宜,因此您可能会注意到它经常被用作简单的零校验 - TEST RAX, RAX 将与 RAX 注册自身(当然会产生相同的值),所以你有一个很好的方法来检查 RAX 是否为零(例如,由 je 分支之后立即使用)或负数(通过使用带有 js 分支的 SF)

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

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

  • 第二个将计算00000101b - 00000111b = 111111105 - 7 = -2 的二进制补码表示),ZF 仍然是 0,但这次你会看到 SF=1,因为我们得到了一个否定的结果,所以 MSB 是on,并且 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)

【讨论】:

  • 好吧,在所有这些例子中,不是所有的标志都设置为 0 吗?每个中的 MSB 将为 0,因此 SF 在所有 3 中均为 0。在第一个示例中,结果为 +2,因此不应设置进位或零标志。在第二个示例中,结果将是 00000100b,即 +4,同样,没有进位或零标志。最后,第三个示例是 00000101,即 +5,并且不会设置任何标志。我错过了什么吗?这似乎太简单了。
  • 哦,我什至没有注意到在最后两个示例中它是 CMP 而不是测试
  • 对不起,从这里“明显”的标志和携带标志的语义如何?
  • @KerrekSB:嗯,他似乎知道如何计算它们,他只需要正确的 AND 操作。他没有要求我们为他做整个练习。即使是作业题,您认为应该添加吗?
  • @Leeor:不了解 OP,但我知道我个人会欢迎在打开带有此标题的帖子时提供完整的解释。
猜你喜欢
  • 1970-01-01
  • 2023-03-25
  • 1970-01-01
  • 1970-01-01
  • 2015-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-11-06
相关资源
最近更新 更多