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

dga*_*ma3 7 x86 assembly instructions x86-16

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

...
do {
    ...
    n--;
} while (n > 0)
...
Run Code Online (Sandbox Code Playgroud)

我假设n是在%edx.

生成的汇编代码是:

testl %edx, %edx 
jle .L5
Run Code Online (Sandbox Code Playgroud)

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

lur*_*ker 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)
Run Code Online (Sandbox Code Playgroud)

在这个具体的例子(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
Run Code Online (Sandbox Code Playgroud)

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

  • 一个关键的附加事实是`test`指令无条件地清除O和C标志.没有它,它对零的比较是没有用的. (2认同)