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".
| Relation | Unsigned | Signed |
|---|---|---|
| a = b | JE | JE |
| a ≠ b | JNE | JNE |
| a > b | JA | JG |
| a ≥ b | JAE | JGE |
| a < b | JB | JL |
| a ≤ b | JBE | JLE |
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 signedMOV DL, '<'CMP BL, 1JB PUT1MOV DL, '>' ; unsigned: 254 > 1PUT1:MOV AH, 02hINT 21hMOV DL, '<' ; signed: -2 < 1CMP BL, 1JL PUT2MOV DL, '>'PUT2:MOV AH, 02hINT 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.