如果我错了请纠正我。
这是我对JNZ
和CMP
的理解。JNZ
-如果Z
标志不为零(1),则将发生跳转CMP
-如果两个值相等,则设置Z
标志(1),否则不设置(0)
这是我正在看的flash教程。它是教一个简单的CrackMe的解决方案。
正如您所看到的,前面的指令将AL
与47h
进行了比较。设置Z
标志的它们是相等的。(您可以在右侧的“寄存器”窗口中看到它)
下一条指令是JNZ
。我的理解是,如果设置了Z
标志,则会发生跳转。Z
标志已设置,但跳转未发生!
为什么?
5条答案
按热度按时间sg3maiej1#
JNZ是“Jump if not zero(ZF = 0)”和NOT“Jump if the ZF is set”的缩写。
如果更容易记住的话,可以考虑JNZ和JNE(不相等则跳转)是等效的。因此,当你做
cmp al, 47
和AL
的内容等于47时,ZF被设置,因此不应该进行跳转(如果不等于- JNE)。bd1hkmkf2#
我在这里会给出一个更广泛的答案。
一般来说,x86中有两种类型的条件跳转:
1.算术跳跃-如JZ(零时跳跃)、JC(进位时跳跃)、JNC(进位时跳跃)等。
1.比较跳转-JE(如果相等则跳转)、JB(如果低于则跳转)、JAE(如果高于或等于则跳转)等。
因此,仅在算术或逻辑指令之后使用第一种类型:
仅在CMP说明后使用第二组:
这样,程序变得更可读,你永远不会感到困惑。
请注意,有时这些指令实际上是同义词。JZ == JE; JC == JB; JNC == JAE等等。完整的表格如下。正如你所看到的,只有16条条件跳转指令,但有30个助记符-它们被提供来允许创建更可读的源代码:
| 助记法|测试条件|说明|
| - -----|- -----|- -----|
| 乔|OF = 1|溢流|
| 日诺|OF = 0|不溢出|
| jc,jb,jnae| CF = 1|进位/低于/既不高于也不相等|
| jnc,jnb,jae| CF = 0|不进位/不低于/高于或相等|
| 耶,耶|ZF = 1|等于/零|
| jne,jnz| ZF = 0|不等于/不为零|
| 杰贝岛|(CF或ZF)= 1|低于或等于/不高于|
| 是啊|(CF或ZF)= 0|高于/不低于或相等|
| js| SF = 1|符号|
| jns| SF = 0|不签名|
| jp,jpe| PF = 1|奇偶校验|
| 联合国发展计划|PF = 0|非奇偶校验/奇偶校验奇数|
| 杰勒河|(SF xor OF)= 1|小于/不大于也不等于|
| JGE|(SF xor OF)= 0|大于或等于/不小于|
| jle,jng|((SF xor OF)或ZF)= 1|小于或等于/不大于|
| jg,jnle|((SF xor OF)or ZF)= 0|大于/不小于或等于|
rn0zuynd3#
起初,JNZ似乎意味着如果非零(0)则跳转,如在跳转中如果零标志为1/设置。
但实际上,这意味着跳转(如果)不是零(设置)。
如果0 =未设置,1 =已设置,请记住:
如果未设置零标志,则JNZ跳转(0)
mrfwxfqh4#
的确,这是令人困惑的权利。
为便于理解,将【非零】替换为【未设置】。(请注意,这是为了您自己的理解)
因此,
未设置意味着标志Z = 0。因此跳转(未设置则跳转)
置位意味着标志Z = 1。不要跳
vql8enpb5#
您可以将JNE/Z读为 *
Equal/Zero标志上的状态为“Not set”,则Jump
**“未设置”**是CPU中的“equal/zero flag”设置为0时的状态,仅当条件满足或相等匹配时才会出现。