与布尔和比较指令混淆

时间:2014-04-13 06:02:15

标签: assembly x86 boolean flags

如果EAX(32位)中的有符号整数是偶数且大于100,我试图设置零标志,否则清零标志。

这是我到目前为止所做的:

TEST EAX, 1 ; test to see if number is even - sets ZF if even
CMP EAX, 100 ; compares eax with 100

对于cmp eax, 100,问题是如果eax大于100,它将清除零标志,而不是设置它。如果EAX大于100,我该如何设置零标志?

2 个答案:

答案 0 :(得分:1)

有指示会影响标志。不仅仅是Zero Flag,还有其他的,取决于他们的继承人设计。如果你有影响相同标志的连续指令,就像在你的例子中那样,那么标志将始终反映最后一条指令的状态。在您的情况下,test eax, 1的结果将丢失。

如果您需要多个测试,那么您通常必须分支到一些代码,这些代码将处理它,然后继续。另一种方法是使用pushf; pop eax存储标志并稍后处理。

 test eax, 1
 je doSomething
 cmp eax, 100
 je doSomethingElse

如果是零标志,还有一条指令可以将状态设置为寄存器:

 test eax, 1
 setz bl

要查看哪些标志受各个指令的影响,您应下载英特尔开发人员手册第3卷。

答案 1 :(得分:1)

基本上,你没有。作为一般规则,标志被覆盖(但有时仅部分地,例如dec不会影响进位标志)而不是组合。您可以使用setcc实现布尔值并执行此类操作:

test eax, 1
setz dl
cmp eax, 100
setg dh
and dl, dh
jnz somewhere  ; will go there if eax was even and greater than 100

使用两个分支更简单:

test eax, 1
jnz odd      ; go away if eax is odd
cmp eax, 100
jg somewhere