Detailed Explanation of Conditional Execution in Assembly Language

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:

  1. Unconditional Jump – Uses the JMP instruction to always jump
  2. 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

  1. Flag Register: Conditional jumps depend on the state of the flag register
  2. Signed vs Unsigned: Choosing the correct conditional jump instruction is important
  3. Performance Optimization: Properly arranging code order can reduce jump frequency
  4. Label Naming: Use meaningful label names to improve code readability
  5. 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.

Leave a Comment