如果我错了,请纠正我。
这是我对JNZ
和CMP
的理解。
JNZ
-如果Z
标志不为零(1),将发生跳转
CMP
- 如果两个值相等,则设置 Z
标志 (1),否则不设置 (0)
这是我正在看的一个flash教程。它正在教一个简单的CrackMe的解决方案。
如您所见,前面的指令将AL
与47h
。设置Z
标志的值相等。(您可以在右侧的Registers窗口中看到它)
下一条指令是JNZ
。我的理解是,如果设置了Z
标志,则会发生跳转。Z
标志已设置,但不会发生跳转!
为什么?
乍一看,JNZ似乎意味着如果不是零(0)则跳转,就像在跳转中如果零标志是1/set。
但实际上,这意味着跳(如果)不是零(设置)。
如果0=未设置,1=设置,那么请记住:
JNZ跳转,如果零标志未设置(0)
我将在这里给出一个更广泛的答案。
一般来说,x86中有两种类型的条件转移:
>
算术跳转-如JZ(如果为零则跳转)、JC(如果进行则跳转)、JNC(如果不进行则跳转)等。
比较跳转-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 == 新山;金纳克 == 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
JNZ是“非零时跳转(ZF=0)”和“设置ZF时跳转”的缩写。
如果更容易记住的话,可以认为JNZ和JNE(不相等就跳)是等价的。因此,当您执行< code>cmp al,47且< code>AL的内容等于47时,ZF被设置,因此不应执行跳转(如果不等于- JNE)。