Conditional execution in assembly language is implemented through jump instructions, which can alter the program’s execution flow based on specific conditions. Conditional execution is fundamental to program control flow.
Overview of Conditional Execution
Two Types of Conditional Execution:
- Unconditional Jump – Uses the JMP instruction to always jump
- Conditional Jump – Decides whether to jump based on specific conditions
CMP Instruction
The CMP instruction compares two operands, sets the flag register, but does not change the values of the operands.
Syntax:
CMP destination, source
Example:
section .text
global _start
_start:
mov dx, 5
cmp dx, 0 ; Compare DX with 0
je equal_zero ; Jump if equal to 0
; Handling when DX is not equal to 0
mov eax, 4
mov ebx, 1
mov ecx, not_zero_msg
mov edx, not_zero_len
int 0x80
jmp exit_prog
equal_zero:
; Handling when DX is equal to 0
mov eax, 4
mov ebx, 1
mov ecx, zero_msg
mov edx, zero_len
int 0x80
exit_prog:
mov eax, 1
int 0x80
section .data
zero_msg db 'DX is zero!', 0xA
zero_len equ $ - zero_msg
not_zero_msg db 'DX is not zero!', 0xA
not_zero_len equ $ - not_zero_msg
Loop Counter Example:
section .text
global _start
_start:
mov edx, 0 ; Initialize counter
loop_start:
inc edx ; Increment counter by 1
cmp edx, 10 ; Compare counter with 10
jle loop_start ; If less than or equal to 10, continue loop
; Handling after loop ends
mov eax, 1
int 0x80
Unconditional Jump (JMP)
The JMP instruction unconditionally jumps to the specified label.
Syntax:
JMP label
Example: Infinite Loop
section .text
global _start
_start:
mov ax, 0 ; Initialize AX to 0
mov bx, 0 ; Initialize BX to 0
mov cx, 1 ; Initialize CX to 1
l20:
add ax, 1 ; Increment AX by 1
add bx, ax ; Add AX to BX
shl cx, 1 ; Shift CX left by 1 (double the value)
jmp l20 ; Unconditionally jump, creating an infinite loop
Conditional Jump Instructions
Signed Conditional Jumps (for arithmetic operations)
| Instruction | Description | Test Flags |
|---|---|---|
| JE/JZ | Jump if Equal/Zero | ZF |
| JNE/JNZ | Jump if Not Equal/Not Zero | ZF |
| JG/JNLE | Jump if Greater/Not Less Than or Equal | OF, SF, ZF |
| JGE/JNL | Jump if Greater Than or Equal/Not Less | OF, SF |
| JL/JNGE | Jump if Less/Not Greater Than or Equal | OF, SF |
| JLE/JNG | Jump if Less Than or Equal/Not Greater | OF, SF, ZF |
Unsigned Conditional Jumps (for logical operations)
| Instruction | Description | Test Flags |
|---|---|---|
| JE/JZ | Jump if Equal/Zero | ZF |
| JNE/JNZ | Jump if Not Equal/Not Zero | ZF |
| JA/JNBE | Jump if Above/Not Below or Equal | CF, ZF |
| JAE/JNB | Jump if Above or Equal/Not Below | CF |
| JB/JNAE | Jump if Below/Not Above or Equal | CF |
| JBE/JNA | Jump if Below or Equal/Not Above | AF, CF |
Special Purpose Conditional Jumps
| Instruction | Description | Test Flags |
|---|---|---|
| JXCZ | Jump if CX is Zero | None |
| JC | Jump if Carry | CF |
| JNC | Jump if No Carry | CF |
| JO | Jump if Overflow | OF |
| JNO | Jump if No Overflow | OF |
| JP/JPE | Jump if Parity | PF |
| JNP/JPO | Jump if No Parity | PF |
| JS | Jump if Sign | SF |
| JNS | Jump if No Sign | SF |
Complete Code Examples
Example 1: Find the Maximum of Three Numbers
section .text
global _start
_start:
mov ecx, [num1] ; Load num1 into ECX
cmp ecx, [num2] ; Compare num1 and num2
jg check_third_num ; If num1 > num2, check the third number
mov ecx, [num2] ; Otherwise, take num2 as the current maximum
check_third_num:
cmp ecx, [num3] ; Compare current maximum with num3
jg _exit ; If current maximum > num3, jump to exit
mov ecx, [num3] ; Otherwise, take num3 as the maximum
_exit:
mov [largest], ecx ; Save the maximum value
; Display message
mov eax, 4
mov ebx, 1
mov ecx, msg
mov edx, msg_len
int 0x80
; Display maximum value (needs conversion to ASCII)
mov eax, [largest]
add eax, '0' ; Convert to ASCII
mov [largest_ascii], eax
mov eax, 4
mov ebx, 1
mov ecx, largest_ascii
mov edx, 2
int 0x80
; New line
mov eax, 4
mov ebx, 1
mov ecx, newline
mov edx, 1
int 0x80
; Exit program
mov eax, 1
int 0x80
section .data
msg db "The largest digit is: "
msg_len equ $ - msg
newline db 0xA
num1 dd 4 ; Number 4
num2 dd 7 ; Number 7
num3 dd 3 ; Number 3
section .bss
largest resd 1
largest_ascii resb 2
Example 2: String Comparison
section .text
global _start
_start:
; Compare two strings
mov esi, str1 ; Address of string 1
mov edi, str2 ; Address of string 2
mov ecx, str_len ; Length of strings
compare_loop:
mov al, [esi] ; Load character from str1
mov bl, [edi] ; Load character from str2
cmp al, bl ; Compare characters
jne strings_different ; If not equal, jump
inc esi ; Next character
inc edi
loop compare_loop ; Continue loop
; If loop completes, strings are equal
mov eax, 4
mov ebx, 1
mov ecx, equal_msg
mov edx, equal_len
int 0x80
jmp exit_prog
strings_different:
mov eax, 4
mov ebx, 1
mov ecx, different_msg
mov edx, different_len
int 0x80
exit_prog:
mov eax, 1
int 0x80
section .data
str1 db "Hello", 0
str2 db "Hello", 0
str_len equ 5
equal_msg db "Strings are equal", 0xA
equal_len equ $ - equal_msg
different_msg db "Strings are different", 0xA
different_len equ $ - different_msg
Example 3: Value Range Check
section .text
global _start
_start:
mov eax, [number] ; Load the number to check
; Check if within range 1-100
cmp eax, 1
jl too_small ; If less than 1
cmp eax, 100
jg too_large ; If greater than 100
; Number is within valid range
mov eax, 4
mov ebx, 1
mov ecx, valid_msg
mov edx, valid_len
int 0x80
jmp exit_prog
too_small:
mov eax, 4
mov ebx, 1
mov ecx, small_msg
mov edx, small_len
int 0x80
jmp exit_prog
too_large:
mov eax, 4
mov ebx, 1
mov ecx, large_msg
mov edx, large_len
int 0x80
exit_prog:
mov eax, 1
int 0x80
section .data
number dd 75
valid_msg db "Number is in valid range (1-100)", 0xA
valid_len equ $ - valid_msg
small_msg db "Number is too small (< 1)", 0xA
small_len equ $ - small_msg
large_msg db "Number is too large (> 100)", 0xA
large_len equ $ - large_msg
Example 4: Loop and Conditional Branching
section .text
global _start
_start:
mov ecx, 10 ; Loop counter
mov ebx, 0 ; Accumulator
loop_start:
; Check if current number is even
mov eax, ecx
and eax, 1 ; Check least significant bit
jz even_number ; If 0, it's even
; Odd number handling
add ebx, ecx ; Accumulate odd numbers
jmp next_iteration
even_number:
; Even number handling - other operations can be added here
nop
next_iteration:
dec ecx ; Decrement counter
jnz loop_start ; If not 0, continue loop
; Loop ends, display result
; Code to display accumulated result can be added here...
mov eax, 1
int 0x80
Example 5: Flag Testing
section .text
global _start
_start:
; Test carry flag
mov al, 0FFh
add al, 1 ; This will produce a carry
jc carry_occurred ; Jump if carry occurs
mov eax, 4
mov ebx, 1
mov ecx, no_carry_msg
mov edx, no_carry_len
int 0x80
jmp test_overflow
carry_occurred:
mov eax, 4
mov ebx, 1
mov ecx, carry_msg
mov edx, carry_len
int 0x80
test_overflow:
; Test overflow flag
mov al, 127 ; Maximum signed positive number
add al, 1 ; This will produce an overflow
jo overflow_occurred ; Jump if overflow occurs
mov eax, 4
mov ebx, 1
mov ecx, no_overflow_msg
mov edx, no_overflow_len
int 0x80
jmp exit_prog
overflow_occurred:
mov eax, 4
mov ebx, 1
mov ecx, overflow_msg
mov edx, overflow_len
int 0x80
exit_prog:
mov eax, 1
int 0x80
section .data
carry_msg db "Carry occurred", 0xA
carry_len equ $ - carry_msg
no_carry_msg db "No carry occurred", 0xA
no_carry_len equ $ - no_carry_msg
overflow_msg db "Overflow occurred", 0xA
overflow_len equ $ - overflow_msg
no_overflow_msg db "No overflow occurred", 0xA
no_overflow_len equ $ - no_overflow_msg
Important Notes
- Flag Register: Conditional jumps depend on the state of the flag register
- Signed vs Unsigned: Choosing the correct conditional jump instruction is important
- Performance Optimization: Properly arranging code order can reduce jump frequency
- Label Naming: Use meaningful label names to improve code readability
- Loop Design: Ensure loops have correct exit conditions
Conditional execution is a core concept in assembly language programming, and mastering these instructions is crucial for writing efficient and fully functional assembly programs.