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零标志,并在标志置位时跳转。 JE
是JZ
一个别名[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指令的书,例如,即使它非常大,英特尔文档也非常精确。