testing点%eax%eax

可能重复:
x86汇编 – 'testl'eax反对eax?

我对汇编语言编程非常新,而且我正在尝试读取二进制生成的汇编语言。 我跑过了

test %eax,%eax 

或者test %rdi, %rdi等等。我很困惑这是干什么的。 %eax, %eax的值是不是相同? 什么是testing? 我读了一个地方,它正在做AND操作…..但由于它们是相同的价值,不是它只是返回%eax

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

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

如果这两个值相比较的话,我认为是跳跃的……好吧,因为%eax本身是好的,在什么情况下我们不会跳跃?

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

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

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

JE [Jump if Equals]testing零标志,并在标志置位时跳转。 JEJZ一个别名[Jump if Zero],所以反汇编器不能根据操作码select一个。 JE是这样命名的,因为如果CMP的参数相等,则设置零标志。

所以,

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

如果%eax为零则跳转。

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

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

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

例:

testingEAX,EAX
JE some_address

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

等效的C代码是:

 if(eax == 0) { goto some_address } 

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

test是一个非破坏性的,它不返回操作的结果,但它相应地设置标志寄存器。 要知道它的真正testing你需要检查下面的指令。 经常用来检查一个寄存器0,可能加上一个jz条件跳转。

你是对的,那个test “和”两个操作数“。 但是结果被抛弃了,唯一留下来的,那就是重要的一面,就是旗帜。 它们被设置,这就是test指令被使用(和存在)的原因。

JE不等于(当前的指令是比较的时候有意义),它确实做了什么,它在ZF标志被设置时跳转。 由于它是通过test设置的标志之一,所以这个指令序列(test x,x; je …)具有当x为0时被跳转的含义。

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