我正在研究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>
答案 0 :(得分:4)
正如您所写,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操作数中的每两个相应位执行此操作,因此在结果中只有1
的位将成为1
:{{ 1}}只会给00001111b & 00000010b
。
现在很容易看到对标志的影响 - ZF = 0,因为结果是非零,SF = 0,因为结果MSB关闭,CF = 0,因为TEST不会设置它(这是合乎逻辑的)操作,而非算术操作。)
顺便说一句,00000010b
随着操作的进行而非常便宜,所以您可能会注意到它经常被用作简单的零检查 - TEST
会和RAX注册自身(导致相同的值)当然),所以你得到一个很好的方法来检查RAX是否为零(例如,紧接着被TEST RAX, RAX
分支使用),或者是否定的(通过使用带有je
分支的SF)
现在,另外两个问题涉及另一个操作 - js
进行实际的减法(它与CMP
做同样的事情,但也丢弃结果,只更新标志)。
第一个会计算SUB
,ZF = SF = 0(原因与上述相同),CF = 0,因为我们不需要进位/借用。
第二个会计算00000110b - 00000101b = 00000001b
(00000101b - 00000111b = 11111110
的两个补码表示),ZF仍然是0,但是这次你看到SF = 1,因为我们得到了一个否定的结果所以MSB打开,CF = 1,因为计算是“借用”到MSB。
关于CF及其对应的OF(溢出标志),这里有一点好处 - 数字只是数字,它们并不意味着有符号或无符号值,直到您决定使用它们为止。然而,x86必须为任何可能性维护正确的标志,因此它基本上使用CF进行无符号运算,实际上意味着最后一个操作是5 - 7 = -2
,好像你向MSB“借”了一个额外的位(这就是CF = 1标记在这里)。 OF不会被设置,因为如果你考虑这些与带符号算术完全相同的操作,你真的完成了5 - 7 = 254
这是完全合法的并且没有溢出/下溢。
另一方面,诸如5 - 7 = -2
之类的操作会反过来,它不会切换CF(因为如果你认为这是无符号算术没有发生任何不好的事情),但OF会因为设置因为如果这些是有符号值,你刚才说127 + 127 = 254
这显然是错误的,因为超过了一个字节可以存储的最大有符号值(127)