Part 8: Conditional Branching, Jump Instructions & Fast Loops in Assembly
Lesson Overview & Control Flow
At the hardware level, processors execute instructions sequentially unless directed otherwise by control-flow instructions. In assembly language, high-level constructs like if-else, switch-case, while, and for loops dissolve into comparisons, flag evaluations, and conditional jump instructions. In Part 8, we master the CMP instruction, dissect signed vs. unsigned conditional jumps, construct robust loop structures, explore CPU branch prediction mechanics, and utilize branchless conditional moves (CMOV).
1. The CMP Instruction and Flag Evaluation
The primary comparison instruction is CMP operand1, operand2. Mechanically, CMP performs an internal subtraction: temp = operand1 - operand2. It updates the condition flags (ZF, CF, SF, OF) identically to SUB, but discards the numerical result, leaving the destination operand unmodified.
2. Signed vs. Unsigned Conditional Jumps
A critical distinction in x86-64 assembly is choosing the correct jump instruction based on whether your data represents signed (two's complement) or unsigned integers:
| Category | Jump Mnemonic | Condition | Tested Flags |
|---|---|---|---|
| Equality (Universal) | JE / JZ JNE / JNZ | Jump if Equal (Zero) Jump if Not Equal (Not Zero) | ZF = 1 ZF = 0 |
| Signed Comparison | JG / JNLE JGE / JNL JL / JNGE JLE / JNG | Jump if Greater (>) Jump if Greater or Equal (≥) Jump if Less (<) Jump if Less or Equal (≤) | ZF = 0 and SF = OF SF = OF SF ≠ OF ZF = 1 or SF ≠ OF |
| Unsigned Comparison | JA / JNBE JAE / JNB JB / JNAE JBE / JNA | Jump if Above (> unsigned) Jump if Above or Equal (≥) Jump if Below (< unsigned) Jump if Below or Equal (≤) | CF = 0 and ZF = 0 CF = 0 CF = 1 CF = 1 or ZF = 1 |
3. Writing Efficient Loop Structures: Why Avoid LOOP?
Historically, x86 featured the LOOP target instruction, which decremented RCX and jumped if RCX != 0. However, on modern out-of-order processors, LOOP has high micro-op decode latency and poor silicon execution port dispatch.
Modern assembly engineers and optimizing compilers construct loops using standard decrement and jump instructions:
; High-performance 64-bit loop: Sum elements from 100 down to 1
mov rcx, 100 ; Iteration counter
xor rax, rax ; Accumulated sum
.loop_body:
add rax, rcx ; sum += counter
sub rcx, 1 ; Decrement counter and update ZF
jnz .loop_body ; Jump back if RCX != 0
4. Branch Prediction & Branchless CMOV (Conditional Move)
CPUs use speculative execution and branch predictors to guess whether a jump will occur before the condition flag is even computed. When a branch predictor mispredicts, the entire instruction pipeline must be flushed, costing 15 to 20 clock cycles of latency!
To eliminate branch penalties for simple assignments (such as min(a, b) or abs(x)), modern processors provide the Conditional Move (CMOVcc) instruction:
; Branchless Minimum: RAX = min(RAX, RBX)
cmp rax, rbx
cmovg rax, rbx ; If RAX > RBX (signed), overwrite RAX with RBX without jumping!
Summary & Next Step
With conditional jumps and loops mastered, we can process large data structures. In Part 9, we explore array indexing patterns, multidimensional matrix stride math, and hardware-accelerated block memory primitives (REP MOVSB, STOSB, LODSB).
Related reading
Part 11: Linux 64-Bit System Calls, NASM Macros & Dynamic Memory Allocation
Learn low-level systems programming: Linux 64-bit SYSCALL table, multi-argument NASM %macro directives, file I/O operations, and sys_mmap memory allocation.
By Md. Harun-Or-Roshid
Part 10: Stack Frames, Procedures & The System V AMD64 ABI in Assembly
Master assembly subroutines: CALL, RET, stack frames, RBP base pointers, 16-byte stack alignment, and the official System V AMD64 ABI calling convention.
By Md. Harun-Or-Roshid
Part 9: Assembly Arrays, String Primitives & Hardware Streaming (REP MOVSB)
Master memory buffers and strings in x86-64 assembly: arrays, strides, and hardware block primitives including MOVSB, LODSB, STOSB, SCASB, and REP.
By Md. Harun-Or-Roshid
Part 7: Bitwise Logic, Masking, and Shift/Rotate Instructions in x86-64
Explore bitwise operations in x86-64 assembly: AND, OR, XOR, NOT, TEST, alongside logical shifts (SHL/SHR), arithmetic shifts (SAR), and rotations.
By Md. Harun-Or-Roshid