Assembly has no if. Instead, CMP compares two values and conditional jumps go to a label or carry on, depending on the flags CMP set.
CMP a, b works out a − b like SUB, sets the flags, and throws the answer away: a does not change.
The jumps
| Jump | Jumps if | Reads |
|---|---|---|
JMP L | always | |
JE L / JZ L | equal / zero | ZF = 1 |
JNE L / JNZ L | not equal | ZF = 0 |
JG L / JGE L | greater / greater or equal, signed | ZF, SF, OF |
JL L / JLE L | less / less or equal, signed | SF, OF, ZF |
JA L / JAE L | above / above or equal, unsigned | CF, ZF |
JB L / JBE L | below / below or equal, unsigned | CF, ZF |
A label is a name followed by a colon, marking an instruction: BIGGER:.
if and if-else
An if-else becomes: compare, jump over the "then" part when the condition is false, and after the "then" part jump over the "else" part:
; Read two digits and print the larger one.
.MODEL SMALL
.STACK 100H
.DATA
SAY DB 0DH, 0AH, 'Larger: $'
.CODE
MAIN PROC
MOV AX, @DATA
MOV DS, AX
MOV AH, 1
INT 21H
MOV BL, AL ; first digit (as a character)
MOV AH, 1
INT 21H
MOV BH, AL ; second digit
LEA DX, SAY
MOV AH, 9
INT 21H
CMP BL, BH ; if BL >= BH ...
JAE FIRST ; ... the first is the larger
MOV DL, BH ; else: the second
JMP SHOWIT ; skip the 'then' part
FIRST:
MOV DL, BL
SHOWIT:
MOV AH, 2
INT 21H
MOV AH, 4CH
INT 21H
MAIN ENDP
END MAINInput used: 48
The CPU view shows CMP's flags, and the explanation under the code says why each jump was taken or not.
Signed or unsigned?
The bits FFh are 255 unsigned but −1 signed, so whether FFh is "greater" than 1 depends on the jump you choose. JA/JB treat values as unsigned (they read CF), JG/JL as signed (they read SF and OF):
; The same bits compared as unsigned and as signed numbers.
.MODEL SMALL
.STACK 100H
.CODE
MAIN PROC
MOV AL, 0FFH ; 255 unsigned, -1 signed
MOV BL, 1
MOV DL, 'n'
CMP AL, BL
JA ABOVE ; unsigned: 255 > 1, so it jumps
JMP TEST2
ABOVE:
MOV DL, 'A'
TEST2:
MOV AH, 2
INT 21H ; prints A
MOV DL, 'n'
CMP AL, BL
JG GREATER ; signed: -1 > 1 is false, so no jump
JMP DONE
GREATER:
MOV DL, 'G'
DONE:
MOV AH, 2
INT 21H ; prints n
MOV AH, 4CH
INT 21H
MAIN ENDP
END MAINUse JA/JB for codes, counts and addresses, and JG/JL for numbers that may be negative.
Common mistakes
- Forgetting the jump over the else part, so both parts run.
- Using JG for characters or other unsigned values above 127; use JA.
- Writing the label without a colon where it is defined (
BIGGERinstead ofBIGGER:). - Putting an instruction that changes the flags (ADD, INC, ...) between CMP and the jump that reads them. MOV does not change flags.
Quick check
Practice problems for this lesson
My notes
Write down what you want to remember from this lesson. Notes are saved on this device as you type, and appear on your dashboard.