28

如果我错了,请纠正我。

这是我对JNZ和的理解CMP

JNZZ- 如果标志不为零 (1) ,将发生跳转

CMP- 如果两个值相等,Z则设置标志 (1),否则不设置 (0)

奥利 DBG

这是我正在观看的 Flash 教程。它正在教一个简单的 CrackMe 的解决方案。

如您所见,前面的指令AL47h. 他们是平等的,树立了Z旗帜。(您可以在右侧的寄存器窗口中看到它)

下一条指令是JNZ. Z我的理解是,如果设置了标志,就会发生跳跃。设置了Z标志,但没有发生跳转!

为什么?

4

5 回答 5

41

JNZ 是“如果不为零则跳转 (ZF = 0)”的缩写,而不是“如果设置了 ZF 则跳转”。

如果更容易记住,请考虑 JNZ 和 JNE(如果不相等则跳转)是等价的。因此,当你在做cmp al, 47并且 的内容AL等于 47 时,ZF 已设置,因此不应进行跳转(如果 Not Equal - JNE)。

于 2013-02-12T20:40:14.483 回答
26

我会在这里做一个更广泛的答案。

在 x86 中,一般来说有两种类型的条件跳转:

  1. 算术跳转 - 如 JZ(如果为零则跳转)、JC(如果进位则跳转)、JNC(如果不进位则跳转)等。

  2. 比较跳跃 - JE(如果相等则跳跃)、JB(如果低于则跳跃)、JAE(如果高于或相等则跳跃)等。

因此,仅在算术或逻辑指令之后使用第一种类型:

sub  eax, ebx
jnz  .result_is_not_zero 

and  ecx, edx
jz   .the_bit_is_not_set

仅在 CMP 指令后使用第二组:

cmp  eax, ebx
jne  .eax_is_not_equal_to_ebx

cmp  ecx, edx
ja   .ecx_is_above_than_edx

这样,程序变得更具可读性,您将永远不会感到困惑。

请注意,有时这些说明实际上是同义词。JZ == 乙脑;JC == JB; JNC == JAE 等等。完整的表格如下。如您所见,只有 16 个条件跳转指令,但有 30 个助记符 - 提供它们以允许创建更具可读性的源代码:

Mnemonic        Condition tested  Description  

jo              OF = 1            overflow 
jno             OF = 0            not overflow 
jc, jb, jnae    CF = 1            carry / below / not above nor equal
jnc, jae, jnb   CF = 0            not carry / above or equal / not below
je, jz          ZF = 1            equal / zero
jne, jnz        ZF = 0            not equal / not zero
jbe, jna        CF or ZF = 1      below or equal / not above
ja, jnbe        CF and ZF = 0      above / not below or equal
js              SF = 1            sign 
jns             SF = 0            not sign 
jp, jpe         PF = 1            parity / parity even 
jnp, jpo        PF = 0            not parity / parity odd 
jl, jnge        SF xor OF = 1     less / not greater nor equal
jge, jnl        SF xor OF = 0     greater or equal / not less
jle, jng    (SF xor OF) or ZF = 1 less or equal / not greater
jg, jnle    (SF xor OF) or ZF = 0 greater / not less nor equal 
于 2013-02-12T21:26:38.593 回答
3

起初,JNZ 似乎意味着如果不是零 (0) 则跳转,就像在零标志为 1/set 时跳转一样。

但实际上它意味着跳转(如果)不是零(设置)。

如果 0 = 未设置且 1 = 已设置,请记住:
如果未设置零标志 (0),则 JNZ 跳转

于 2013-02-12T23:14:01.757 回答
0

您可以将 JNE/Z 解读为 *

如果E qual / Z ero 标志上的状态为“未设置”,则跳转

“未设置”是 CPU 中的“相等/零标志”设置为 0 时的状态,仅在满足条件或相等匹配时才会发生。

于 2020-10-18T13:49:49.883 回答
0
JNZ     Jump if Not Zero    ZF=0

确实,这很令人困惑。

为了更容易理解,将Not Zero替换为Not Set。(请注意这是为了您自己的理解)

因此,

JNZ     Jump if Not Set     ZF=0

未设置意味着标志 Z = 0。所以跳转(如果未设置则跳转)

设置意味着标志 Z = 1。所以,不要跳转

于 2017-05-26T03:37:29.280 回答