这是一些C,在我正在学习的教科书中找到:
...
do {
...
n--;
} while (n > 0)
...
我认为n
位于%edx
。
产生的汇编代码是:
testl %edx, %edx
jle .L5
我理解jle
测试小于或等于(SF ^ OF) | ZF
。但是我不确定该指令如何与n > 0
对应。谁能解释一下呢?
答案 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是循环后的标签,而不是循环前面的标签。