188

可能重复:
x86 程序集 - 针对 eax 的“testl”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

5 回答 5

215

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

TESTZF当 AND 运算的结果为零时,设置零标志。如果两个操作数相等,则当两者都为零时,它们的按位与为零。当在结果中设置最高有效位时,TEST还设置符号标志 ,当设置的位数为偶数时,还设置奇偶校验标志 。SFPF

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

所以,

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

%eax如果为零,则跳转。

于 2012-10-25T08:53:58.903 回答
62

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

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

像 JE 这样的条件跳转指令旨在查看 ZF 的跳转/不跳转,因此同时使用 TEST 和 JE 等效于根据特定寄存器的值执行条件跳转:

示例:

TEST EAX,EAX
JE some_address



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

,等效的 C 代码是:

if(eax == 0)
{
    goto some_address
}
于 2012-10-25T09:02:49.530 回答
18

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

于 2012-10-25T08:53:39.937 回答
5

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

于 2012-10-25T08:59:26.763 回答
4

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

JE相等时不跳转(它在之前的指令是比较时具有含义),它的真正作用ZF是在设置标志时跳转。并且由于它是由 设置的标志之一,因此test该指令序列(test x,x; je...)具有当 x 为 0 时跳转的含义。

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

于 2012-10-25T08:54:03.953 回答