测试点%eax %eax

< p > 可能的重复: < br > x86汇编- ' testl ' eax对eax? < / p >

我对汇编语言编程非常非常陌生,我目前正在尝试阅读由二进制文件生成的汇编语言。我遇到过

 test   %eax,%eax

test %rdi, %rdi,等等。我很困惑这是做什么的。%eax, %eax中的值不是相同的吗?它在测试什么?我在某处读到,它正在做AND操作.....但由于它们是相同的值,它不会只是返回%eax吗?

以下是我发现这种用法的一个例子:

   400e6e:       85 c0                   test   %eax,%eax
400e70:       74 05                   je     400e77 <phase_1+0x23>

我认为je跳转,如果正在比较的两个值相等......因为%eax是well,本身,在什么情况下我们不会跳转?

一般来说,我是一个编程初学者,所以如果有人能给我解释一下,我会非常感激。谢谢!

244766 次浏览

这个函数检查EAX是否为零。指令test在参数之间按位执行AND,如果EAX包含0,则结果设置ZF或ZeroFlag。

CMP减去操作数并设置标志。也就是说,如果差值为零(操作数相等),则设置零标志。

当AND操作的结果为零时,TEST设置零标志ZF。如果两个操作数相等,当它们都为零时,它们的位与为零。TEST还设置了符号标志SF,当结果中设置最高有效位时,设置奇偶标志PF,当设置位的数量为偶数时。

JE[如果等于则跳转]测试零标志,如果设置了标志则跳转。JEJZ [Jump if 0]的别名,因此反汇编程序不能根据操作码选择一个。JE之所以这样命名,是因为如果CMP的参数相等,则设置0标志。

所以,

TEST %eax, %eax
JE   400e77 <phase_1+0x23>

如果%eax为零,则跳转。

你是对的,test "和"是两个操作数。但是结果被丢弃了,唯一留下来的,也是最重要的部分,是标志。它们被设置了,这就是为什么test指令被使用(并且存在)的原因。

JE在相等时不会跳转(当之前的指令是比较时,它有此含义),它真正的作用是在设置ZF标志时跳转。由于它是由test设置的标志之一,该指令序列(test x,x;Je…)的意思是当x为0时,它会被跳转。

对于这样的问题(以及更多细节),我可以推荐一本关于x86指令的书,例如,即使它真的很大,英特尔的文档也非常好和精确。

test是一个非破坏性的and,它不返回操作的结果,但它相应地设置标志寄存器。要了解它真正测试的是什么,您需要检查以下说明。out通常用于检查寄存器是否为0,可能与jz条件跳转相结合。

一些x86指令被设计成保留操作数(寄存器)的内容,只是设置/取消设置特定的内部CPU标志,如零标志(ZF)。您可以将ZF视为驻留在CPU内部的true/false布尔标志。

在这种特殊情况下,TEST指令执行一个按位逻辑与,丢弃实际结果,并根据逻辑与的结果设置/取消设置ZF:如果结果为零,则设置ZF = 1,否则设置ZF = 0。

像JE这样的条件跳转指令是设计来查看ZF是否跳跃的,所以同时使用TEST和JE相当于基于特定寄存器的值执行条件跳转:

例子:

< / p >
TEST EAX,EAX
JE some_address
< p >

当且仅当ZF = 1时,CPU将跳转到“some_address”,换句话说,当且仅当and (EAX,EAX) = 0,当且仅当EAX == 0时,它才会发生

等价的C代码是:

< / p >
if(eax == 0)
{
goto some_address
}