Corrigez-moi si je me trompe.
Ceci est ma compréhension de JNZ
et CMP
.
JNZ
- Le saut aura lieu si le drapeau Z
n'est PAS zéro (1)
CMP
- Si les deux valeurs sont égales, l'indicateur Z
est défini (1) sinon, il n'est pas défini (0)
Ceci est un tutoriel flash que je regarde. Il enseigne la solution à un simple CrackMe.
Comme vous pouvez le constater, l'instruction précédente a comparé AL
avec 47h
. Ils étaient égaux, ce qui positionne le drapeau Z
. (Vous pouvez le voir dans les fenêtres des registres sur le côté droit)
L'instruction suivante est une JNZ
. Je croyais comprendre que le saut aurait lieu si le drapeau Z
était activé. L'indicateur Z
IS est activé, mais le saut n'a pas lieu!
Pourquoi?
JNZ est l'abréviation de "Jump if not zero (ZF = 0)" etNOT"Jump si le ZF est défini".
Si c'est plus facile à retenir, considérez que JNZ et JNE (jump sinon égal) sont équivalents. Par conséquent, lorsque vous utilisez cmp al, 47
et que le contenu de AL
est égal à 47, le facteur ZF est défini, mais le saut (si Non égal - JNE) ne doit pas être pris.
Je vais apporter une réponse un peu plus large ici.
Il y a généralement deux types de sauts conditionnels dans x86:
Sauts arithmétiques - comme JZ (saut si zéro), JC (saut si reporté), JNC (saut si non reporté), etc.
Sauts de comparaison - JE (saut si égal), JB (saut si inférieur), JAE (saut si supérieur ou égal), etc.
Donc, utilisez le premier type seulement après des instructions arithmétiques ou logiques:
sub eax, ebx
jnz .result_is_not_zero
and ecx, edx
jz .the_bit_is_not_set
Utilisez le deuxième groupe uniquement après les instructions du CPM:
cmp eax, ebx
jne .eax_is_not_equal_to_ebx
cmp ecx, edx
ja .ecx_is_above_than_edx
De cette façon, le programme devient plus lisible et vous ne serez jamais confus.
Notez que parfois ces instructions sont en fait des synonymes. JZ == JE; JC == JB; JNC == JAE et ainsi de suite. Le tableau complet suit. Comme vous pouvez le constater, il n'y a que 16 instructions de saut conditionnel, mais 30 mnémoniques - elles sont fournies pour permettre la création de code source plus lisible:
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
Au début, il semble que JNZ signifie saut si pas zéro (0), comme dans saut si le drapeau zéro est 1/défini.
Mais en réalité, cela signifie Sauter (si) pas Zéro (est défini).
Si 0 = non défini et 1 = défini, rappelez-vous simplement:
JNZ Saute si l'indicateur zéro n'est pas défini (0)
JNZ Jump if Not Zero ZF=0
En effet, c'est déroutant à droite.
Pour faciliter la compréhension, remplacez pas de zéro par non défini . (Veuillez prendre note que ceci est pour votre propre compréhension)
Par conséquent,
JNZ Jump if Not Set ZF=0
Non défini signifie que le drapeau Z = 0. So Jump (saut si non défini)
Set signifie flag Z = 1. Alors, ne sautez PAS