ChatGPT解决这个技术问题 Extra ChatGPT

测试点 %eax %eax [重复]

这个问题在这里已经有了答案:9 年前关闭。

可能重复: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 本身很好,在什么情况下我们不会跳转?

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

由于有些答案似乎有点不清楚,所以让我指出 TEST 还会更新除 ZF 之外的其他标志。请参阅指令集参考。
@Jester 已修复(在我的回答中),抱歉。
另一个可能的重复项:What does the test instruction do?

J
John Dvorak

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

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

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

所以,

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

如果 %eax 为零,则跳转。


我在哪里可以找到这样的信息?
即? x86 指令列表 is on Wikipedia,它还链接了 spec by Intelanother (quite readable) reference on wayback machineA tutorial 也可在 Wikibooks 上找到。
是的,这是我正在寻找的信息
如果 %eax 为零,则跳转,这就是我想要的。
G
Gianluca Ghettini

一些 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
}

p
ppeterka

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


这是执行此操作的标准方法。也可以为“初学者清晰”执行 cmp %eax, 0 (立即),但这会编码为更长的指令(也就是效率较低)。
J
Jens Björnhager

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


f
flolo

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

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

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