2012-10-25 69 views
76

可能重复:
x86 Assembly - ‘testl’ eax against eax?测试的关键%EAX%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很好,本身,在什么情况下我们不会跳?

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

+4

由于有些答案看起来有点不清楚,让我指出'TEST'除了'ZF'外还更新了其他标志。请参阅指令集参考。 – Jester

+0

@Jester修复了(在我的回答中),对不起。 –

+0

另一个可能的重复:?什么是'test'指令做(http://stackoverflow.com/q/6002079) – jww

回答

95

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

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

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

所以,

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

跳转如果%eax为零。

+3

我在哪里可以找到这样的信息? –

+5

即? x86指令列表[位于维基百科](http://en.wikipedia.org/wiki/X86_instruction_listings),它也链接[英特尔规格](http://www.intel.com/content/www/) (http://web.archive.org/web/20100407092131/http://home.com/us/en/developers/architecture-software- developer-manuals.html)以及[另一个可读的参考资料] .comcast.net /〜fbui/intel.html)。 [教程](http://en.wikibooks.org/wiki/X86_Assembly)也可在Wikibooks上找到。 –

+0

没错,这就是如果'%eax'为零,我一直在寻找 –

9

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

+3

这是做它的标准方式。对于“初学者清晰”,也可以使用cmp%eax,0(立即数),但是这会编码为更长的指令(即效率较低)。 –

2

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

JE当不相等时跳转(它具有以前的指令是比较时的含义),它确实做了什么,它会在设置标志ZF时跳转。因为它是由test设置的标志之一,所以该指令序列(测试x,x; je ...)具有当x为0时跳跃的含义。

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

3

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

32

一些x86指令被设计成离开操作数(寄存器),因为它们是与只设置/复位具体的内部CPU标志像零标志(ZF)的含量。您可以将ZF视为驻留在CPU内的真/假布尔标志。根据逻辑和的结果

在此特定情况下 ,TEST指令按位进行逻辑AND,丢弃该实际结果和设置/取消设置ZF:如果结果是零它设置ZF = 1,否则它设置ZF = 0

像JE 条件跳转指令被设计来看看ZF跳跃/ notjumping所以使用TEST和JE一起相当于基于特定寄存器的值来执行一个条件跳转:

例如:

TEST EAX,EAX
JE some_address

CPU将跳转到 “some_address” 当且仅当ZF = 1,换言之当且仅当AND(EAX,EAX)= 0,这在转当且仅当EAX == 0

等效C代码是它可以发生:

if(eax == 0) 
{ 
    goto some_address 
}