Condition: jumps if CF = 1. After CMP a, b, a borrow out of a − b means a < b as unsigned numbers. As JC it asks the general question "did a carry or borrow come out?": after ADD the unsigned sum did not fit, after SUB it went below zero, after a shift or rotate the bit pushed out was 1.
| After CMP a, b | Unsigned | Signed |
|---|---|---|
| a = b | JE (ZF = 1) | JE (ZF = 1) |
| a ≠ b | JNE (ZF = 0) | JNE (ZF = 0) |
| a > b | JA (CF = 0 and ZF = 0) | JG (ZF = 0 and SF = OF) |
| a ≥ b | JAE (CF = 0) | JGE (SF = OF) |
| a < b | JB (CF = 1) | JL (SF ≠ OF) |
| a ≤ b | JBE (CF = 1 or ZF = 1) | JLE (ZF = 1 or SF ≠ OF) |
MOV AX, 1CMP AX, 0FFFFh ; 1 < 65535 unsigned; as signed, FFFFh is -1MOV DL, "Y" ; MOV leaves the flags aloneJB SHOW1 ; taken: DL stays "Y"MOV DL, "N"SHOW1:MOV AH, 02h ; DOS: print the character in DLINT 21h
Idioms
DOS signals an error by returning CF = 1 with an error code in AX, so calls are followed by JC FAIL1. SHR AL, 1 / JC ODD1 tests and removes the low bit in one go. STC and CLC set CF by hand, which lets a procedure of your own return yes or no in the carry flag.
Range
On the 8086 JB exists only in the SHORT form: two bytes, opcode 72h and a signed 8-bit displacement counted from the end of the instruction. The target must lie within −128..+127 bytes of that point. To go farther, invert the test and hop over an unconditional JMP, which can reach the whole segment. MASM 6 makes this rewrite itself when it finds the target out of range (its default OPTION LJMP), so the listing may show two instructions where you wrote one.
JAE SKIP1 ; the opposite test, a short hopJMP FARAWAY ; any distance in the segmentSKIP1:
Later CPUs
The 80386 added a near form of every conditional jump, 0Fh 82h followed by a 16-bit displacement (32-bit in 32-bit code), so from the 386 on JB can reach anywhere in the segment. Code for the 8086 must stay with the short form.