Chapter 6

Assembly - Flow Control

Jumps, conditions, loops, and function calls

🔀 Jumps

📖 Definition: Jump

An instruction that changes EIP (the next instruction pointer) - causes the code to "jump" to another location.

JMP

Unconditional jump - always jumps.

JMP label       ; Jump to label (symbolic name)
JMP 0x00401050  ; Jump to specific address
JMP EAX         ; Jump to address stored in EAX register

⚖️ Comparison and Flag Effects

CMP

Compare - compares two values (subtracts without saving the result).
Updates flags based on the result.

CMP EAX, EBX    ; Compare EAX to EBX (subtract without saving)
                ; If EAX == EBX: ZF = 1
                ; If EAX < EBX:  CF = 1 (unsigned), SF != OF (signed)
                ; If EAX > EBX:  CF = 0 and ZF = 0
TEST

Does AND without saving result. Used to check if a value is 0.

TEST EAX, EAX   ; Check if EAX equals 0
                ; If EAX == 0: ZF = 1
                ; If EAX != 0: ZF = 0

🚦 Conditional Jumps

Jump only if a certain condition is met (usually after CMP or TEST):

Instruction Meaning Condition
JE / JZ Jump if Equal / Zero ZF = 1
JNE / JNZ Jump if Not Equal / Not Zero ZF = 0
JG / JNLE Jump if Greater (signed) ZF=0 AND SF=OF
JGE / JNL Jump if Greater or Equal (signed) SF = OF
JL / JNGE Jump if Less (signed) SF ≠ OF
JLE / JNG Jump if Less or Equal (signed) ZF=1 OR SF≠OF
JA / JNBE Jump if Above (unsigned) CF=0 AND ZF=0
JAE / JNB Jump if Above or Equal (unsigned) CF = 0
JB / JNAE Jump if Below (unsigned) CF = 1
JBE / JNA Jump if Below or Equal (unsigned) CF=1 OR ZF=1
💡 Signed vs Unsigned - What's the Difference?

Signed = numbers that can be positive or negative (-128 ... -1, 0, 1 ... 127)
Unsigned = numbers that can be only positive (0, 1, 2 ... 255)

Type Jump Instructions Memory Trick
Signed (pos/neg) JG, JGE, JL, JLE Greater / Less
Unsigned (only pos) JA, JAE, JB, JBE Above / Below
⚠️ Why does this matter?

The same bits can be interpreted differently:

0xFFFFFFFF:
  As Unsigned = 4,294,967,295 (biggest number!)
  As Signed   = -1
                

If comparing 0xFFFFFFFF to 1:
JA (unsigned) → will jump! (4 billion > 1)
JG (signed) → won't jump! (-1 < 1)

📝 Example: if-else Condition

C code:
if (a == 5) {
    b = 10;
} else {
    b = 20;
}
Assembly:
    mov eax, [ebp-4]        ; Load 'a' into EAX
    cmp eax, 5              ; Compare a to 5
    jne else_branch         ; If not equal, jump to else

    ; IF BLOCK (a == 5)
    mov dword [ebp-8], 10   ; b = 10
    jmp end_if              ; Skip else block

else_branch:
    ; ELSE BLOCK (a != 5)
    mov dword [ebp-8], 20   ; b = 20

end_if:
    ; Continue...
CMP a, 5 a == 5? Yes b = 10 No (JNE) b = 20 Continue

🔄 Loops

while Loop

C code:
while (i < 10) {
    sum += i;
    i++;
}
Assembly:
loop_start:
    cmp dword [ebp-4], 10   ; Check: is i < 10?
    jge loop_end            ; If i >= 10, exit loop

    ; LOOP BODY
    mov eax, [ebp-4]        ; EAX = i
    add [ebp-8], eax        ; sum += i
    inc dword [ebp-4]       ; i++

    jmp loop_start          ; Jump back to start

loop_end:

for Loop with LOOP

LOOP

Decreases ECX by 1 and jumps if ECX ≠ 0. Useful for loops!

💡 Understanding the LOOP example
    mov ecx, 10         ; ECX = 10 (put 10 into ECX, NOT subtract!)

loop_start:             ; ← LABEL: a name/bookmark for this location
    ; loop body here    ;   (the code that repeats)

    loop loop_start     ; Does TWO things automatically:
                        ;   1. ECX = ECX - 1
                        ;   2. If ECX != 0, jump to loop_start
                

Step-by-step execution (with ECX = 3):

Iteration ECX before LOOP LOOP does ECX-- ECX after Jump?
1 3 3 - 1 2 ✅ Yes → loop_start
2 2 2 - 1 1 ✅ Yes → loop_start
3 1 1 - 1 0 ❌ No → continue

Result: The loop body runs 3 times!

📞 Function Calls

CALL

Calls a function: saves the return address on the Stack and jumps to the function.

RET

Returns from a function: takes an address from the Stack and jumps to it.

Calling a function:
CALL my_function    ; = PUSH EIP (save return addr), then JMP my_function
The function itself:
my_function:
    push ebp            ; Save old EBP
    mov ebp, esp        ; Set up stack frame
    ; ... code ...
    pop ebp             ; Restore old EBP
    RET                 ; = POP EIP (get return addr and jump to it)
main() ... CALL func ← returns here ... CALL func() push ebp mov ebp, esp ; code... pop ebp RET RET

🎯 Identifying Patterns in RE

📌 Common Patterns

if-else pattern:
CMP ...             ; Compare
Jxx else_label      ; Conditional jump
; if code
JMP end_label       ; Skip else
else_label:
; else code
end_label:
; Pattern: CMP -> conditional jump -> JMP (to skip else)
while loop pattern:
loop_start:
CMP ...             ; Check condition
Jxx loop_end        ; Exit if condition false
; loop body
JMP loop_start      ; Jump back to start
loop_end:
; Pattern: CMP at start -> exit jump -> JMP back to start
for loop pattern:
; init (i=0)
loop_start:
CMP ECX, limit      ; Check condition
Jxx loop_end        ; Exit if done
; loop body
INC ECX             ; i++ (or DEC)
JMP loop_start      ; Jump back
loop_end:
; Pattern: init -> CMP -> body -> INC/DEC -> JMP back

📋 Chapter Summary