CodeToLive

Control Flow in Assembly

Control flow in assembly language is managed through jumps, conditional branches, and loops. Unlike high-level languages that have structured control statements, assembly uses simple jump instructions to alter program flow.

Unconditional Jumps

The JMP instruction transfers control to another part of the program unconditionally.


section .text
    global _start

_start:
    mov eax, 10
    jmp skip        ; Jump to 'skip' label
    mov eax, 20     ; This instruction is skipped

skip:
    ; EAX contains 10 here
      

Conditional Jumps

Conditional jumps transfer control based on the state of processor flags. These are typically used after comparison (CMP) or test (TEST) instructions.

Common Conditional Jumps

Instruction Description Condition
JE/JZ Jump if equal/zero ZF = 1
JNE/JNZ Jump if not equal/not zero ZF = 0
JG/JNLE Jump if greater/not less or equal ZF = 0 and SF = OF
JGE/JNL Jump if greater or equal/not less SF = OF
JL/JNGE Jump if less/not greater or equal SF ≠ OF
JLE/JNG Jump if less or equal/not greater ZF = 1 or SF ≠ OF
JC/JB/JNAE Jump if carry/borrow/not above or equal CF = 1
JNC/JNB/JAE Jump if no carry/not borrow/above or equal CF = 0

Conditional Jump Example


section .text
    global _start

_start:
    mov eax, 15
    mov ebx, 20
    cmp eax, ebx        ; Compare EAX and EBX
    jg greater          ; Jump if EAX > EBX
    ; Else case
    mov ecx, ebx        ; ECX = EBX
    jmp end

greater:
    mov ecx, eax        ; ECX = EAX

end:
    ; ECX contains the larger value
      

Loops

Loops in assembly are implemented using conditional jumps. The LOOP instruction provides a convenient way to implement counted loops.

Simple Loop


section .text
    global _start

_start:
    mov ecx, 5          ; Loop counter
    xor eax, eax        ; Clear EAX (sum = 0)

loop_start:
    add eax, ecx        ; Add counter to sum
    dec ecx             ; Decrement counter
    jnz loop_start      ; Jump if not zero

    ; EAX now contains 5+4+3+2+1 = 15
      

LOOP Instruction


section .text
    global _start

_start:
    mov ecx, 5          ; Loop counter
    xor eax, eax        ; Clear EAX (sum = 0)

loop_start:
    add eax, ecx        ; Add counter to sum
    loop loop_start     ; Decrement ECX and loop if not zero

    ; EAX now contains 5+4+3+2+1 = 15
      

Nested Loops

Nested loops require saving and restoring the outer loop counter.


section .text
    global _start

_start:
    mov ecx, 3          ; Outer loop counter

outer_loop:
    push ecx            ; Save outer counter
    mov ecx, 2          ; Inner loop counter

inner_loop:
    ; Do something here
    loop inner_loop

    pop ecx             ; Restore outer counter
    loop outer_loop
      

Flags Register

Conditional jumps depend on the flags register (EFLAGS). Important flags include:

Comparison Instructions

These instructions set flags without modifying operands.

CMP - Compare


cmp eax, ebx     ; Sets flags as if (EAX - EBX)
      

TEST - Logical Compare


test eax, eax    ; Sets ZF if EAX is zero
test ebx, 1      ; Check if least significant bit is set
      

Conditional Move

Modern x86 processors support conditional move instructions that can avoid branches.


section .text
    global _start

_start:
    mov eax, 15
    mov ebx, 20
    cmp eax, ebx
    cmovg ecx, eax   ; Move EAX to ECX if greater
    cmovle ecx, ebx  ; Move EBX to ECX if less or equal
      

Switch/Case Implementation

Switch statements can be implemented using a jump table.


section .data
    jump_table dd case0, case1, case2, case3

section .text
    global _start

_start:
    mov eax, 2          ; Case selector
    cmp eax, 3
    ja default          ; Jump if above 3
    jmp [jump_table + eax*4]

case0:
    ; Case 0 code
    jmp end

case1:
    ; Case 1 code
    jmp end

case2:
    ; Case 2 code
    jmp end

case3:
    ; Case 3 code
    jmp end

default:
    ; Default case code

end:
    ; Continue execution
      

Practical Examples

Example 1: Finding Maximum Value


section .data
    numbers dd 10, 20, 15, 25, 5
    count equ 5

section .text
    global _start

_start:
    mov esi, numbers        ; Pointer to array
    mov ecx, count          ; Number of elements
    mov eax, [esi]          ; Initialize max with first element

find_max:
    cmp eax, [esi]          ; Compare current max with array element
    jge not_greater         ; Jump if current max is greater or equal
    mov eax, [esi]          ; Update max

not_greater:
    add esi, 4              ; Move to next element
    loop find_max           ; Repeat until ECX = 0

    ; EAX now contains the maximum value (25)
      

Example 2: Count Even Numbers


section .data
    numbers dd 11, 22, 33, 44, 55
    count equ 5

section .text
    global _start

_start:
    mov esi, numbers        ; Pointer to array
    mov ecx, count          ; Number of elements
    xor ebx, ebx            ; EBX = even count (0)

count_evens:
    test dword [esi], 1     ; Test least significant bit
    jnz odd                 ; Jump if odd
    inc ebx                 ; Increment even count

odd:
    add esi, 4              ; Move to next element
    loop count_evens        ; Repeat until ECX = 0

    ; EBX now contains the count of even numbers (2)
      

Optimization Tips

Next Steps

Now that you understand control flow, you can learn about: