FREE COURSE / REAL PRACTICE
x86-64
Read x86-64 registers, calling conventions, stack frames and optimized compiler output before working with SIMD and memory ordering.
What you’ll work toward
Connect C++ behavior to machine instructions and investigate generated code with the supplied toolchain.
Read an explanation, inspect the diagrams and work through the available checks, debugging exercises and builds. Feedback and prerequisite links guide the next step.
Before you start
This course builds on these skills:
Individual lessons can add prerequisites. The course map shows your actual readiness.
A look inside the first lesson
x86-64 registers and data movement
#include <cstdio>
extern "C" unsigned long write32();
extern "C" unsigned long write16();
asm(R"(
.text
.intel_syntax noprefix
.globl write32
write32:
mov rax, -1 # all 64 bits set
mov eax, 1 # 32-bit write: upper half cleared
ret
.globl write16
write16:
mov rax, -1
mov ax, 1 # 16-bit write: upper 48 bits untouched
ret
.att_syntax prefix
)");
int main() {
std::printf("%016lx\n%016lx\n", write32(), write16());
}Your course outline
Follow the lessons in curriculum order. Open a unit to preview the ideas you’ll work with.
x86-64: reading the machine
- LESSON 01.01
x86-64 registers and data movement
Read and write the instructions that move data: the sixteen registers and their sub-registers, zero- and sign-extension, lea as arithmetic, and every addressing mode the compiler uses for arrays, structs and globals.
Open lesson - LESSON 01.02
The System V calling convention
Where arguments and return values live on x86-64 Linux: integer and floating-point argument registers, stack arguments, structs in registers or behind a hidden pointer, callee-saved registers and the 16-byte stack alignment rule.
Open lesson - LESSON 01.03
x86-64 control flow: flags, jumps, setcc and cmov
Read and write the instructions behind every if, loop and switch: cmp/test and the flags, signed versus unsigned condition codes, setcc and cmov for branch-free code, rotated loops and jump tables.
Open lesson - LESSON 01.04
x86-64 stack frames and calls
What call and ret really do, prologues and epilogues, frame pointers, locals, spills and the red zone, 16-byte alignment, stack arguments, tail calls, and how -O0 and -O2 frames differ.
Open lesson
x86-64: what the compiler does
- LESSON 02.01
Reading optimised code
Recognise what -O2 did to your code: inlining, folding, strength reduction, division by magic numbers, dead stores, hoisting, devirtualisation, and the optimisations undefined behaviour licenses.
Open lesson - LESSON 02.02
Writing functions in assembly
Write whole functions in x86-64 assembly (GAS, Intel syntax): loops over arrays and strings, pointer walking, conditional moves, and calling back into C++ while keeping the ABI's promises.
Open lesson - LESSON 02.03
Inline assembly, builtins and barriers
GNU extended asm done right — outputs, inputs, constraints, clobbers, earlyclobbers, volatile and asm goto — and why builtins and intrinsics are usually the better tool. Plus rdtsc, cpuid, and compiler barriers versus CPU fences.
Open lesson - LESSON 02.04
Branchless code and bit tricks
cmov, setcc and sbb; when a branch beats a select and when it loses badly; and the bit-manipulation instructions behind std::popcount, countl_zero, rotl and pext.
Open lesson
x86-64: SIMD, memory order, the core
- LESSON 03.01
SSE and AVX2 intrinsics
Program the vector unit directly: xmm/ymm lanes, unaligned loads, compare masks and movemask, the 128-bit lane trap in shuffles, horizontal reductions and exact tails, with AVX2 enabled per function.
Open lesson - LESSON 03.02
Auto-vectorization: reading and steering it
Read the compiler's vector code, know exactly why a loop wasn't vectorized (aliasing, dependencies, float reductions, early exits, strides), and rewrite it so it is — checked against the real codegen.
Open lesson - LESSON 03.03
The x86-64 memory model (TSO)
What x86 hardware actually reorders (only a store followed by a load, through the store buffer), what each std::atomic order compiles to, and why the compiler can still break code the hardware wouldn't.
Open lesson - LESSON 03.04
The core underneath: latency, throughput, caches
How an out-of-order x86 core actually runs your loop: uops and ports, latency versus throughput, dependency chains and multiple accumulators, llvm-mca, cache lines, false sharing, store forwarding — and why microbenchmarks lie.
Open lesson