What The Comparison Flags Mean, and How to Use Them

CS 301 Lecture, Dr. Lawlor

OK, so you want to know how some number A relates to some other number B.  So you subtract them.

If A-B = 0, then A=B.
If A-B > 0, then A > B.
If A-B < 0, then A < B.

Yup, so "cmp eax,10" actually internally subtracts 10 from the value in eax.  If the difference is zero, the CPU sets flag ZF (the Zero Flag).  If the difference is positive or negative, the CPU sets some other hideous flags to indicate this (the CPU sets various flags for both the signed and unsigned comparisons).

Turns out, "sub eax,10" actually sets all the same flags.  So you can compare two numbers with "cmp A,B" or "sub A,B", and you'll get the same result (but they're not totally interchangeable: "cmp" won't change A!). 

So then, you want to jump if the previous comparison came out equal.  You use the "je" instruction (Jump if Equal). 
Or you want to jump if the previous subtraction came out zero.  You use the "jz" instruction (Jump if Zero).

Turns out, "je" and "jz" are the same machine language instruction, because they both do entirely the same thing.

The bottom line is to do comparisons in assembly, you first do either a cmp or sub instruction, and then:
English
Less Than
Less or Equal
Equal
Greater or Equal
Greater Than
Not Equal
C/C++
<
<=
==
>=
>
!=
Assembly
  (signed)
jl
jle
je or jz
jg
jge
jne or jnz
Assembly
  (unsigned)
jb
jbe
je or jz
ja
jae
jne or jnz
The "b" in the unsigned comparison instructions stands for "below", and the "a" for "above". 

In C/C++, the compiler can tell whether you want a signed and unsigned comparison based on the variable's types.  There aren't any types in assembly, so it's up to you to pick the right instruction!

Examples

Subtract sets all the same comparison flags as "cmp".  So this code returns 1, because 5 < 7.
mov ecx,5

sub ecx,7
jl yes_it_jumped
; ... else no, it didn't jump: return 0
mov eax,0
ret

yes_it_jumped: ; ... so return 1
mov eax,1
ret
(executable NetRun link)

Subtract also sets the zero flag, so here's a very small downward-counting loop:
mov edx,5
mov eax,0

loop_start:
add eax,7
sub edx,1
jnz loop_start ; Jumps if edx is still nonzero

ret
(executable NetRun link)