测试点%eax%eax

时间:2012-10-25 08:43:27

标签: assembly x86 att

  

可能重复:
  x86 Assembly - ‘testl’ eax against eax?

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

 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本身很好,在什么情况下我们不跳?

我是编程的初学者,所以如果有人能向我解释这一点,我会非常感激。谢谢!

5 个答案:

答案 0 :(得分:128)

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

当AND操作的结果为零时,

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

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

所以,

TEST %eax, %eax
JE   400e77 <phase_1+0x23>
如果%eax为零,则

跳转。

答案 1 :(得分:45)

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

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

像JE这样的条件跳转指令用于查看ZF的跳转/不跳跃,因此使用TEST和JE相当于根据特定寄存器的值执行条件跳转:

例:

测试EAX,EAX
JE some_address

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

等效的C代码是:

if(eax == 0)
{
    goto some_address
}

答案 2 :(得分:11)

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

答案 3 :(得分:3)

你是对的,test“和两个操作数。但结果被抛弃了,唯一保留的东西,也就是重要的部分,就是旗帜。它们已设置,这就是使用test指令(并且存在)的原因。

JE在相等时不跳转(它具有前面指令作为比较时的含义),它实际上是什么,它在设置ZF标志时跳转。由于它是由test设置的标志之一,因此该指令序列(test x,x; je ...)具有在x为0时跳转的含义。

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

答案 4 :(得分:3)

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