test 和 je/jne 是如何工作的

How does test and je/jne work

好吧,我开始做一些汇编工作。我从以下说明开始:

test       al, al
jne        0x1000bffcc

使用调试器,我希望代码不跳转到地址 0x1000bffcc,所以我在 jne 指令上设置了一个断点,然后使用以下 lldb 命令反转 al 寄存器:

expr $al = 1

这很好用,所以我继续操作,直到偶然发现以下非常相似的指令对:

test       al, al
je         0x1000bffcc

虽然这看起来很相似,但反转 al 寄存器似乎没有影响。它不断跳转到地址 0x1000bffcc。所以我做了一些研究,发现测试运行逻辑 ANDal 本身,然后相应地设置零标志或 ZF。这就引出了两个问题:

非常感谢您的帮助!

test    al, al
jne     0x1000bffcc

test指令对两个操作数执行逻辑,并根据结果(不存储在任何地方)设置the CPU flags register。如果 al 为零,则与运算结果为零并设置 Z 标志。如果 al 不为零,则清除 Z 标志。 (其他flags,比如Carry,oVerflow,Sign,Parity 等也受到影响,但此代码没有指令测试它们。)

如果未设置 Z 标志,jne 指令会更改 EIP。对于相同的操作,还有另一个助记符,称为 jnz

如果你让test指令执行然后在条件跳转指令之前改变al,条件跳转仍然会做它在改变[=12=之前要做的事情].那是因为 al 的值不再影响条件跳转。如果您在测试前更改值,那么它将按预期工作。

至于为什么改有时会有效果: 肯定是al的修改值影响了其他逻辑

要使用调试器使指令不跳转,请更改标志以设置 Z 标志。它可能称为 ZF,或者您可能必须修改 EFLAGS 寄存器中的位。如何执行此操作因调试器及其修订版本而异。