CMP a, b subtracts b from a exactly like SUB, sets the six flags from the difference, and discards the difference. Both operands keep their values. The operand rules are those of SUB: same sizes, no two memory operands, a size keyword for memory compared with an immediate (CMP BYTE PTR [SI], 0).

Choosing the jump

The flags hold enough to answer both signed and unsigned questions; the jump you write after CMP decides which. Read them as "jump if a is ... b".

RelationUnsignedSigned
a = bJEJE
a ≠ bJNEJNE
a > bJAJG
a ≥ bJAEJGE
a < bJBJL
a ≤ bJBEJLE

The unsigned jumps look at CF and ZF ("above" and "below"); the signed jumps look at SF, OF and ZF ("greater" and "less"). The same bits can compare differently: FEh is 254 unsigned but −2 signed. The example prints ><: above 1 as unsigned, less than 1 as signed.

MOV BL, 0FEh ; 254 unsigned, -2 signed
MOV DL, '<'
CMP BL, 1
JB PUT1
MOV DL, '>' ; unsigned: 254 > 1
PUT1:
MOV AH, 02h
INT 21h
MOV DL, '<' ; signed: -2 < 1
CMP BL, 1
JL PUT2
MOV DL, '>'
PUT2:
MOV AH, 02h
INT 21h

Pitfalls

The order matters: CMP AX, BX followed by JA jumps if AX is above BX, not the other way round. Put the conditional jump right after the CMP, or at least make sure nothing in between changes the flags; MOV and the jumps themselves do not, but arithmetic, logic and DOS calls may. To test bits rather than compare values, use TEST. The 8086 conditional jumps reach only −128..127 bytes; for a farther target, jump over a JMP with the opposite condition.