使用具有相同寄存器的TEST指令

时间:2013-06-30 12:02:41

标签: assembly x86 x86-16 instructions

这是一些C,在我正在学习的教科书中找到:

...
do {
    ...
    n--;
} while (n > 0)
...

我认为n位于%edx

产生的汇编代码是:

testl %edx, %edx 
jle .L5

我理解jle测试小于或等于(SF ^ OF) | ZF。但是我不确定该指令如何与n > 0对应。谁能解释一下呢?

2 个答案:

答案 0 :(得分:13)

其中一些内容已经涉及,但我会详细介绍一下。

test reg,mask指令的一般用途是针对掩码测试寄存器值(寄存器值在内部与掩码进行AND运算),然后根据结果设置状态标志SF,ZF和PF。 [来自@ChrisDodd的评论编辑]它还无条件地清除O(溢出)和C(进位)状态位。[/ EDIT]

SF = sign flag (1 if sign bit is set (a 2's complement negative value))
ZF = zero flag (1 if result is 0)
PF = parity flag (1 if result has an even number of 1 bits)

在此特定示例(test eax,eax)中,指令正在eax AND eax。完成后,这些位将是:

SF = 1 if EAX has a negative value (since sign bit will not change when ANDed with itself)
ZF = 1 if EAX is zero (the only value that yields a zero when ANDed with itself is zero)
PF = 1 if EAX has an even number of 1 bits

换句话说,它是零或负的简单测试。这是编译器代码生成中非常常见的模式。

答案 1 :(得分:1)

TEST“根据结果设置SF,ZF和PF状态标志。” (英特尔手册,关于TEST)。

因此,SF会反映n是否为否定,而ZF会反映n是否为零。

将OF设置为零。

因此(SF ^ OF)|ZF简化为SF | ZF,因此最后,如果n <= 0将进行跳转。这似乎是错误的方式,所以希望.L5是循环后的标签,而不是循环前面的标签。