7

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

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

我假设n%edx.

产生的汇编代码是:

testl %edx, %edx 
jle .L5

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

4

2 回答 2

14

其中一些已经涵盖,但我将填写更多细节。

test reg,mask指令的一般用途是根据掩码测试寄存器值(寄存器值在内部与掩码进行与运算),然后根据结果设置状态标志 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

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

于 2013-06-30T19:05:50.333 回答
1

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

所以SF会反映是否n为负,ZF会反映是否n为零。

它将 OF 设置为零。

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

于 2013-06-30T12:34:13.767 回答