0Pricing
Assembly Language & x86 Low-Level Systems Programming · Lesson

Conditional Jumps and Loops

Implement decision-making and repetitive tasks using comparison instructions (CMP, TEST) and conditional jump instructions (JMP, JE, JNE, JL, JG, etc.).

Conditional Jumps and Loops is a free Assembly Language & x86 Low-Level Systems Programming lesson on CoddyKit — lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Assembly Language & x86 Low-Level Systems Programming learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

Guiding Program Flow

Programs rarely run straight through. We need to make decisions and repeat actions. This is called control flow.

Assembly language provides special instructions to change the order in which instructions are executed. This allows your programs to be dynamic and respond to different conditions.

Think of it like a choose-your-own-adventure story: you decide which path to take next!

Always Taking the Jump

The simplest way to change program flow is with an unconditional jump using the JMP instruction. It always transfers control to a specified label.

This is like a "goto" statement in higher-level languages. The program will immediately execute instructions starting from the target label.

section .data
    msg1 db "Hello!", 0xA
    len1 equ $ - msg1
    msg2 db "Skipped!", 0xA
    len2 equ $ - msg2
    msg3 db "End.", 0xA
    len3 equ $ - msg3

section .text
    global _start

_start:
    mov rax, 1           ; syscall write
    mov rdi, 1           ; stdout
    mov rsi, msg1
    mov rdx, len1
    syscall              ; Print "Hello!"

    jmp skip_message     ; Unconditional jump

    mov rax, 1
    mov rdi, 1
    mov rsi, msg2
    mov rdx, len2
    syscall              ; This part is skipped!

skip_message:
    mov rax, 1
    mov rdi, 1
    mov rsi, msg3
    mov rdx, len3
    syscall              ; Print "End."

    mov rax, 60          ; syscall exit
    mov rdi, 0
    syscall

Making Comparisons (CMP)

Before we can make decisions, we need to compare values. The CMP instruction does this for us.

CMP destination, source works like SUB destination, source, but it discards the result. Instead, it only updates the CPU flags based on the comparison.

This is crucial for conditional jumps!

; Compare AX with BX
cmp ax, bx

; Compare value in memory with 10
cmp [my_var], 10

; Compare AL with 0
cmp al, 0

The CPU Flags Register

After a CMP instruction (or most arithmetic/logic ops), special bits in the Flags Register are updated. These bits tell us about the result of the operation.

  • ZF (Zero Flag): Set if the result was zero (or operands were equal).
  • SF (Sign Flag): Set if the result was negative.
  • CF (Carry Flag): Set if an unsigned overflow occurred.
  • OF (Overflow Flag): Set if a signed overflow occurred.

Conditional jumps check these flags!

Jumping on Equality (JE, JNE)

Once CMP sets the flags, we can use conditional jump instructions. Two common ones are JE (Jump if Equal) and JNE (Jump if Not Equal).

  • JE label: Jumps if the Zero Flag (ZF) is set (meaning operands were equal).
  • JNE label: Jumps if the Zero Flag (ZF) is clear (meaning operands were not equal).

Let's see an example.

section .data
    eq_msg db "Numbers are equal!", 0xA
    eq_len equ $ - eq_msg
    ne_msg db "Numbers are not equal!", 0xA
    ne_len equ $ - ne_msg

section .text
    global _start

_start:
    mov rax, 10
    mov rbx, 10          ; Try changing this to 5

    cmp rax, rbx         ; Compare RAX and RBX

    je  are_equal        ; If equal, jump to are_equal

    ; Else (not equal)
    mov rax, 1
    mov rdi, 1
    mov rsi, ne_msg
    mov rdx, ne_len
    syscall
    jmp end_program

are_equal:
    mov rax, 1
    mov rdi, 1
    mov rsi, eq_msg
    mov rdx, eq_len
    syscall

end_program:
    mov rax, 60
    mov rdi, 0
    syscall

Greater or Lesser (Signed)

For signed numbers, we use different conditional jumps to check for greater than or less than relationships.

  • JG label: Jump if Greater (ZF=0 and SF=OF)
  • JGE label: Jump if Greater or Equal (SF=OF)
  • JL label: Jump if Less (SF!=OF)
  • JLE label: Jump if Less or Equal (ZF=1 or SF!=OF)

These rely on combinations of the Sign Flag (SF), Overflow Flag (OF), and Zero Flag (ZF).

section .data
    gt_msg db "RAX is greater!", 0xA
    gt_len equ $ - gt_msg
    lt_msg db "RAX is less!", 0xA
    lt_len equ $ - lt_msg
    eq_msg db "RAX is equal!", 0xA
    eq_len equ $ - eq_msg

section .text
    global _start

_start:
    mov rax, 5
    mov rbx, 10          ; Compare 5 with 10

    cmp rax, rbx

    jg  is_greater       ; If RAX > RBX
    jl  is_less          ; If RAX < RBX

    ; Else, they must be equal
    mov rsi, eq_msg
    mov rdx, eq_len
    jmp print_msg

is_greater:
    mov rsi, gt_msg
    mov rdx, gt_len
    jmp print_msg

is_less:
    mov rsi, lt_msg
    mov rdx, lt_len
    jmp print_msg

print_msg:
    mov rax, 1
    mov rdi, 1
    syscall

    mov rax, 60
    mov rdi, 0
    syscall

Unsigned Comparisons (JA, JB)

When dealing with unsigned numbers, the flags are interpreted differently. The Carry Flag (CF) is key here.

  • JA label: Jump if Above (unsigned greater than) (CF=0 and ZF=0)
  • JAE label: Jump if Above or Equal (unsigned greater than or equal) (CF=0)
  • JB label: Jump if Below (unsigned less than) (CF=1)
  • JBE label: Jump if Below or Equal (unsigned less than or equal) (CF=1 or ZF=1)

Always be mindful if you're comparing signed or unsigned values!

Building an IF-ELSE Block

We can combine CMP and conditional jumps to create if-else logic, just like in high-level languages.

The general pattern is: compare, jump if condition is FALSE to the "else" block, execute "if" block, then jump past "else" block.

section .data
    if_msg db "Condition is TRUE!", 0xA
    if_len equ $ - if_msg
    else_msg db "Condition is FALSE!", 0xA
    else_len equ $ - else_msg

section .text
    global _start

_start:
    mov rax, 20
    mov rbx, 10

    cmp rax, rbx         ; Is RAX > RBX?
    jle else_block       ; If not (less or equal), jump to else

    ; IF block (RAX > RBX)
    mov rsi, if_msg
    mov rdx, if_len
    jmp print_and_exit

else_block:
    ; ELSE block (RAX <= RBX)
    mov rsi, else_msg
    mov rdx, else_len

print_and_exit:
    mov rax, 1
    mov rdi, 1
    syscall

    mov rax, 60
    mov rdi, 0
    syscall

Creating Loops with Jumps

Loops are fundamental for repeating code. In assembly, we combine a label, a comparison, and a conditional jump to create them.

A common pattern involves: initializing a counter, defining a loop label, performing operations, decrementing/incrementing the counter, comparing, and jumping back to the label if the condition is met.

section .data
    msg db "Looping... ", 0xA
    len equ $ - msg

section .text
    global _start

_start:
    mov rcx, 3           ; Initialize loop counter

loop_start:
    cmp rcx, 0           ; Check if counter is 0
    je  loop_end         ; If it is, exit loop

    ; Print message
    mov rax, 1
    mov rdi, 1
    mov rsi, msg
    mov rdx, len
    syscall

    dec rcx              ; Decrement counter
    jmp loop_start       ; Jump back to start of loop

loop_end:
    mov rax, 60
    mov rdi, 0
    syscall

Jump Condition Check

Consider the following assembly snippet. What will be printed if RAX holds the value 5 and RBX holds 10?

section .data
    msg_a db "Result A", 0xA
    len_a equ $ - msg_a
    msg_b db "Result B", 0xA
    len_b equ $ - msg_b

section .text
    global _start

_start:
    ; Assume RAX = 5, RBX = 10
    cmp rax, rbx
    jg  print_a
    jmp print_b

print_a:
    mov rax, 1
    mov rdi, 1
    mov rsi, msg_a
    mov rdx, len_a
    syscall
    jmp end_program

print_b:
    mov rax, 1
    mov rdi, 1
    mov rsi, msg_b
    mov rdx, len_b
    syscall

end_program:
    mov rax, 60
    mov rdi, 0
    syscall

Recap: Jumps and Loops

Great job! You've learned how to control your program's flow in assembly!

  • JMP is for unconditional jumps.
  • CMP compares values and updates the CPU's flags register.
  • Conditional jumps (like JE, JNE, JG, JL, JA, JB) check these flags to decide whether to jump.
  • By combining these, you can create powerful if-else statements and loops.

Next, we'll dive into procedures and stack management to organize your code even further!

Frequently asked questions

Is the “Conditional Jumps and Loops” lesson free?

Yes — the full text of “Conditional Jumps and Loops” is free to read here on the web, and the Assembly Language & x86 Low-Level Systems Programming course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Assembly Language & x86 Low-Level Systems Programming course, upgrade to CoddyKit PRO.

What will I learn in “Conditional Jumps and Loops”?

Implement decision-making and repetitive tasks using comparison instructions (CMP, TEST) and conditional jump instructions (JMP, JE, JNE, JL, JG, etc.). You practise Assembly Language & x86 Low-Level Systems Programming with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start Assembly Language & x86 Low-Level Systems Programming?

No prior experience is required. Assembly Language & x86 Low-Level Systems Programming on CoddyKit is structured for beginners through advanced learners; this is — lesson 3 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Conditional Jumps and Loops” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this Assembly Language & x86 Low-Level Systems Programming lesson?

Yes. Every Assembly Language & x86 Low-Level Systems Programming lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. Data Movement Instructions (MOV, PUSH, POP)
  2. Arithmetic and Logic Operations
  3. Conditional Jumps and Loops
  4. Bitwise and Shift Instructions
← Back to Assembly Language & x86 Low-Level Systems Programming