测试和je / j如何工作

时间:2015-07-01 20:45:03

标签: debugging assembly x86 lldb

好的,所以我开始使用装配工作。我从以下说明开始:

test       al, al
jne        0x1000bffcc

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

expr $al = 1

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

test       al, al
je         0x1000bffcc

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

  • 为什么在第一个示例中反转al寄存器有帮助?
  • 为什么它在第二个例子中不起作用?
  • 如何在第二个示例中使用调试器使代码不跳转?

非常感谢你的帮助!

1 个答案:

答案 0 :(得分:6)

test    al, al
jne     0x1000bffcc

test指令执行两个操作数的逻辑,并根据结果设置the CPU flags register(不存储在任何地方)。如果al为零,则anded结果为零,并设置Z标志。如果al非零,则清除Z标志。 (其他标志,例如 C arry,o V erflow, S ign, P arity等等也受影响,但是这段代码没有测试它们的指令。)

如果未设置Z标志,jne指令会改变EIP。另一个名为jnz的操作的助记符。

如果让test指令执行,然后在条件跳转指令之前更改al,则条件跳转仍然会在更改al之前执行任何操作。这是因为al的值不再影响条件跳转。如果在测试之前更改了值,那么它将按预期工作。

至于为什么更改它有时会产生影响:必须是因为al的修订值正在影响其他逻辑。

要使用调试器使指令不跳转,请更改标志以便设置Z标志。它可能被称为ZF,或者您可能必须修改EFLAGS寄存器中的位。如何做到这一点因调试器和可能的修订版而异。