What are the common conditional-jump instructions and how do you read their conditions after a cmp?
Each j<cc> jumps based on the flags from the preceding cmp/test; signed comparisons use g/l (greater/less), unsigned use a/b (above/below).
* Conditional jumps after cmp fall into signed, unsigned, and equality families; seeing ja/jb signals an unsigned type. *
After cmp b, a (which computes a - b in AT&T order), the jump describes the relationship of a to b:
| Instruction | Flags | After cmp b, a means… |
|---|---|---|
je / jz |
ZF=1 | a == b |
jne / jnz |
ZF=0 | a != b |
js |
SF=1 | result negative |
jns |
SF=0 | result non-negative |
jg / jnle |
~(SF^OF)&~ZF | a > b (signed) |
jge / jnl |
~(SF^OF) | a >= b (signed) |
jl / jnge |
SF^OF | a < b (signed) |
jle / jng |
(SF^OF)|ZF | a <= b (signed) |
ja / jnbe |
~CF&~ZF | a > b (unsigned) |
jae / jnb |
~CF | a >= b (unsigned) |
jb / jnae |
CF | a < b (unsigned) |
jbe / jna |
CF|ZF | a <= b (unsigned) |
The crucial signed/unsigned split: g/l = greater/less interpret operands as signed (using SF/OF); a/b = above/below interpret them as unsigned (using CF). Picking the wrong family is a classic bug — and seeing ja/jb in disassembly tells you the underlying C type was unsigned.
Tip: This is exactly why the switch range-check uses ja (unsigned): a single unsigned > 6 test catches both negative and too-large indices at once.
Go deeper:
Jcc — x86 conditional-jump reference — the full Jcc condition table.
FLAGS register (Wikipedia) — the flags each jump reads.