Korrigiere mich, wenn ich falsch liege.
Dies ist mein Verständnis von JNZ
und CMP
.
JNZ
- Der Sprung erfolgt, wenn das Z
-Flag NICHT Null ist (1)
CMP
- Wenn die beiden Werte gleich sind, wird das Flag Z
gesetzt (1), andernfalls nicht (0).
Dies ist ein Flash-Tutorial, das ich mir anschaue. Es lehrt die Lösung für ein einfaches CrackMe.
Wie Sie sehen, verglich der vorherige Befehl AL
mit 47h
. Sie waren gleich, wodurch das Flag Z
gesetzt wurde. (Sie können es in den Registern auf der rechten Seite sehen)
Die nächste Anweisung ist eine JNZ
. Meines Wissens nach wurde der Sprung durchgeführt, wenn das Flag Z
gesetzt ist. Das Z
-Flag IS ist gesetzt, aber der Sprung findet nicht statt!
Warum?
JNZ ist die Abkürzung für "Jump wenn nicht Null (ZF = 0)" undNICHT"Jump wenn der ZF gesetzt ist".
Wenn es einfacher ist, sich daran zu erinnern, bedenken Sie, dass JNZ und JNE (Sprung, falls nicht gleich) gleichwertig sind. Wenn Sie also cmp al, 47
ausführen und der Inhalt von AL
gleich 47 ist, wird der ZF-Wert gesetzt, dh der Sprung (falls nicht gleich - JNE) sollte nicht genommen werden.
Ich werde hier eine etwas breitere Antwort geben.
Im Allgemeinen gibt es zwei Arten von bedingten Sprüngen in x86:
Arithmetische Sprünge - wie JZ (Sprung wenn Null), JC (Sprung, wenn Übertragen), JNC (Sprung, wenn nicht Übertragen) usw.
Vergleichssprünge - JE (Sprung, wenn gleich), JB (Sprung, wenn unten), JAE (Sprung, wenn darüber oder gleich), usw.
Verwenden Sie den ersten Typ also nur nach arithmetischen oder logischen Anweisungen:
sub eax, ebx
jnz .result_is_not_zero
and ecx, edx
jz .the_bit_is_not_set
Verwenden Sie die zweite Gruppe nur nach CMP-Anweisungen:
cmp eax, ebx
jne .eax_is_not_equal_to_ebx
cmp ecx, edx
ja .ecx_is_above_than_edx
Auf diese Weise wird das Programm lesbarer und Sie werden nie verwirrt.
Beachten Sie, dass diese Anweisungen manchmal tatsächlich Synonyme sind. JZ = JE; JC == JB; JNC == JAE und so weiter. Die vollständige Tabelle folgt. Wie Sie sehen, gibt es nur 16 bedingte Sprungbefehle, aber 30 Mnemonik - sie werden zur Verfügung gestellt, um die Erstellung von besser lesbarem Quellcode zu ermöglichen:
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
Zunächst scheint es, als ob JNZ Sprung bedeutet, wenn nicht Null (0), wie im Sprung, wenn das Null-Flag 1/ist.
In der Realität bedeutet es jedoch Jump (wenn), nicht Null (gesetzt).
Wenn 0 = nicht gesetzt und 1 = gesetzt ist, denken Sie daran:
JNZ Springt, wenn das Null-Flag nicht gesetzt ist (0)
JNZ Jump if Not Zero ZF=0
In der Tat ist dies ein verwirrendes Recht.
Um es verständlicher zu machen, ersetzen Sie Not Zero durch Not Set . (Bitte beachten Sie, dies ist zu Ihrem eigenen Verständnis)
Daher,
JNZ Jump if Not Set ZF=0
Nicht gesetzt bedeutet Flag Z = 0. Also springen (springen, wenn nicht gesetzt)
Set bedeutet Flag Z = 1. Springen Sie NICHT