31

Correct me if I am wrong.

This is my understanding of JNZ and CMP.

JNZ - The jump WILL take place if the Z Flag is NOT zero (1)

CMP - If the two values are equal, the Z Flag is set (1) otherwise it is not set (0)

Olly DBG

This is a flash tutorial I am watching. It is teaching the solution to a simple CrackMe.

As you can see, the previous instruction compared AL with 47h. They were equal which set the Z flag. (You can see it in the Registers windows on the right side)

The next instruction is a JNZ. My understanding was that the jump will take place if the Z flag is set. The Z flag IS set, but the jump doesn't take place!

Why?

nrz
  • 10,435
  • 4
  • 39
  • 71
43.52.4D.
  • 950
  • 6
  • 14
  • 28
  • 1
    @nrz Your comment is not very clear - is the OP expected to realise the mistake by looking at the statement really, really hard? – Michael Foukarakis Feb 12 '13 at 20:47
  • @nrz Jeez man are you trying to confuse me even more?!?! From the other answers, now I know that with JNZ, the jump only takes place if the zero flag is NOT set (0) – 43.52.4D. Feb 12 '13 at 23:04
  • 2
    @43.52.4D. Sorry, I misread the sentence "JNZ - The jump WILL take place if the Z Flag is NOT zero (1)" in your question, and as a result my comment was possibly confusing, so I deleted it now. [Intel x86 JUMP quick reference](http://www.unixwiz.net/techtips/x86-jumps.html) has a useful table for checking the conditions of branching of different x86 conditional jumps. – nrz Feb 13 '13 at 00:09

5 Answers5

46

JNZ is short for "Jump if not zero (ZF = 0)", and NOT "Jump if the ZF is set".

If it's any easier to remember, consider that JNZ and JNE (jump if not equal) are equivalent. Therefore, when you're doing cmp al, 47 and the content of AL is equal to 47, the ZF is set, ergo the jump (if Not Equal - JNE) should not be taken.

Michael Foukarakis
  • 39,737
  • 6
  • 87
  • 123
30

I will make a little bit wider answer here.

There are generally speaking two types of conditional jumps in x86:

  1. Arithmetic jumps - like JZ (jump if zero), JC (jump if carry), JNC (jump if not carry), etc.

  2. Comparison jumps - JE (jump if equal), JB (jump if below), JAE (jump if above or equal), etc.

So, use the first type only after arithmetic or logical instructions:

sub  eax, ebx
jnz  .result_is_not_zero 

and  ecx, edx
jz   .the_bit_is_not_set

Use the second group only after CMP instructions:

cmp  eax, ebx
jne  .eax_is_not_equal_to_ebx

cmp  ecx, edx
ja   .ecx_is_above_than_edx

This way, the program becomes more readable and you need never be confused.

Note, that sometimes these instructions are actually synonyms. JZ == JE; JC == JB; JNC == JAE and so on. The full table is following. As you can see, there are only 16 conditional jump instructions, but 30 mnemonics - they are provided to allow creation of more readable source code:

Mnemonic Condition tested Description
jo OF = 1 overflow
jno OF = 0 not overflow
jc, jb, jnae CF = 1 carry / below / neither above nor equal
jnc, jnb, jae CF = 0 not carry / not below / above or equal
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 or ZF) = 0 above / neither below nor 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 / neither 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 / neither less nor equal
Sep Roland
  • 33,889
  • 7
  • 43
  • 76
johnfound
  • 6,857
  • 4
  • 31
  • 60
3

At first it seems as if JNZ means jump if not Zero (0), as in jump if zero flag is 1/set.

But in reality it means Jump (if) not Zero (is set).

If 0 = not set and 1 = set then just remember:
JNZ Jumps if the zero flag is not set (0)

Michael Myers
  • 188,989
  • 46
  • 291
  • 292
43.52.4D.
  • 950
  • 6
  • 14
  • 28
0
JNZ     Jump if Not Zero    ZF=0

Indeed, this is confusing right.

To make it easier to understand, replace Not Zero with Not Set. (Please take note this is for your own understanding)

Hence,

JNZ     Jump if Not Set     ZF=0

Not Set means flag Z = 0. So Jump (Jump if Not Set)

Set means flag Z = 1. So, do NOT Jump

CinCout
  • 9,486
  • 12
  • 49
  • 67
Charlotte Russell
  • 1,355
  • 1
  • 13
  • 16
  • There are multiple condition bits in FLAGS, ZF being only one of them. (Others are CF, OF, SF, PF, and also AF but you can't branch on AF directly). If you want to be explicit, "Jump if ZF Not Set". Or Jump if `!ZF`" – Peter Cordes Oct 18 '20 at 16:19
0

You can read JNE/Z as *

Jump if the status is "Not set" on Equal/Zero flag

"Not set" is a status when "equal/zero flag" in the CPU is set to 0 which only happens when the condition is met or equally matched.

  • `cmp same, same` *sets* ZF, because `x - x == 0`. The semantic meaning of `jne` is to jump if the two things you compared were *not* equal. The last sentence of your answer sounds like it's saying that ZF=0 when you compare two equal things, which is backwards. Maybe you meant to say "ZF would only be set when a compare is equally matched"? But you were just talking about `0`, and then went on to say "... which only happens", giving that phrase an implicit subject of `ZF=0`. – Peter Cordes Oct 18 '20 at 16:13
  • Also note that most ALU instructions set FLAGS, so for example `inc eax` will clear ZF when the output EAX value is non-zero. IDK if that's what you mean by "the condition is met". An instruction commonly used before `jnz` is `test eax,eax` (or any other register); I guess you could call non-zero EAX a "condition". Anyway, I don't think your answer is very clear for anyone who doesn't already know how FLAGS work, unfortunately. – Peter Cordes Oct 18 '20 at 16:17