Sign up to track your progress

Create an account to save your progress, complete exercises, and earn achievements.

Back to Courses Intermediate

Reading C++ Assembly

Learn to read the x86-64 assembly your C++ compiles into. Understand registers, the stack, calling conventions, control flow, how C++ features like virtual functions look at machine level, and what the optimizer really does to your code.

50 lessons 26 hours

Support Free C++ Education

Help us keep this platform free for everyone! Your support enables us to create more high-quality lessons, exercises, and interactive content.

Become a Patron

Course Curriculum

From C++ to Assembly (8 lessons)

What assembly is, why reading it is a superpower, how your code becomes machine instructions, how to read your very first listing, and how to generate assembly yourself.

1
What Is Assembly, and Why Read It?

Understand the difference between high-level code, assembly, and machine code, and why being able to read assembly makes you a better C++ programmer.

25 minutes

2
The Vocabulary of Assembly

A plain-language glossary of the core terms used throughout the course: instruction, mnemonic, operand, register, memory, immediate, label, and address.

15 minutes

3
The Compilation Pipeline

Follow your source code through preprocessing, compilation, assembly, and linking, and see exactly where assembly fits in.

25 minutes

4
Reading Your First Assembly Listing

Walk through the assembly of a tiny function line by line and learn the anatomy of an instruction.

35 minutes

5
The Common Instructions

Meet the dozen instructions that make up most assembly: mov and lea, the arithmetic ops, cmp and test, the jumps, and the function-call quartet push/pop/call/ret.

25 minutes

6
Two Dialects: Intel vs AT&T Syntax

The same instructions can be written two ways. Learn to recognise both and understand why this course uses Intel syntax.

20 minutes

7
Generating Assembly Yourself

Produce your own listings with g++ -S and objdump, explore Compiler Explorer, and use the in-editor assembly panel to inspect any code you write on this site.

25 minutes

8
Chapter 1 Summary and Quiz

Review the three levels of a program, the compilation pipeline, the anatomy of an instruction, the common instructions, and the two assembly dialects.

20 minutes

x86-64 Foundations: Registers and Instructions (7 lessons)

The general-purpose registers and their sub-register names, the core data-movement and arithmetic instructions, operands, addressing modes, and the lea instruction.

1
The General-Purpose Registers

Meet the 16 general-purpose registers, their conventional roles, and how to recognise them in a listing.

25 minutes

2
Register Sizes and Sub-Registers

How rax, eax, ax, and al name the same register at 64, 32, 16, and 8 bits, and why writing eax clears the upper half of rax.

25 minutes

3
Moving Data with mov

The mov instruction in its three forms: register to register, immediate to register, and loads and stores to memory.

25 minutes

4
Arithmetic Instructions

How add, sub, imul, inc, dec, and neg implement C++ arithmetic.

30 minutes

5
Operands and Addressing Modes

Immediate, register, and memory operands, and the displacement[base + index*scale] addressing form.

30 minutes

6
lea: The Address Calculator

How lea computes an address without touching memory, and why compilers use it for fast arithmetic.

25 minutes

7
Chapter 2 Summary and Quiz

Review the register file, sub-register naming, mov, the arithmetic instructions, addressing modes, and lea.

20 minutes

References (1 resources)

Additional reference materials for this chapter

x86-64 Quick Reference

A cheat sheet of the general-purpose registers, the common instructions, the condition codes and their flags, and the System V argument registers. Keep it open while you read listings.

Control Flow in Assembly (6 lessons)

Comparisons and the flags register, conditional and unconditional jumps, and how if/else, loops, and switch statements compile.

1
cmp and the Flags Register

How cmp and test set the flags (ZF, SF, OF, CF) without storing a result.

25 minutes

2
Unconditional and Conditional Jumps

jmp versus je, jne, jl, jg and the rest, and which flags each one reads.

25 minutes

3
How if/else Compiles

Translating an if/else into a compare followed by a conditional jump over a block.

30 minutes

4
How Loops Compile

How for and while loops become a label, a body, and a back-edge jump.

30 minutes

5
switch Statements and Jump Tables

How a dense switch becomes a jump table while a sparse one becomes a chain of compares.

30 minutes

6
Chapter 3 Summary and Quiz

Review the flags register, the conditional jump family, and the compiled shapes of if/else, loops, and switch statements.

20 minutes

Functions, the Stack, and Calling Conventions (8 lessons)

How the call stack works, the function prologue and epilogue, the System V calling convention, argument passing, return values, floating point in the xmm registers, and local variables.

1
What Is the Stack?

The call stack, the rsp register, push and pop, and how the stack grows downward in memory.

25 minutes

2
The Function Prologue and Epilogue

The push rbp / mov rbp, rsp setup and its matching teardown, and what a stack frame is.

25 minutes

3
The System V Calling Convention

Which registers carry arguments and return values, and the difference between caller-saved and callee-saved registers.

30 minutes

4
Passing Arguments in Registers

Watch several arguments land in rdi, rsi, rdx and friends just before a call.

25 minutes

5
Return Values

How a function hands its result back to the caller in eax/rax.

20 minutes

6
Floating Point: The xmm Registers

Where float and double live: the xmm registers, the scalar SSE instructions like movss and addsd, and how floating-point arguments and return values are passed.

30 minutes

7
Local Variables on the Stack

How local variables are stored at fixed offsets from the frame pointer.

30 minutes

8
Chapter 4 Summary and Quiz

Review the stack, the prologue and epilogue, the System V calling convention, argument and return registers, the xmm registers, and local variable storage.

20 minutes

Data, Pointers, and Memory (6 lessons)

How pointers and references look in assembly, indexing into arrays, struct layout, global versus local storage, and a first look at the heap.

1
Pointers and References

A pointer is just an address in a register, and dereferencing it is a memory access.

25 minutes

2
Indexing into Arrays

How arr[i] becomes base + index*scale addressing, with the element size as the scale.

30 minutes

3
Struct Layout and Member Access

Member access as a fixed offset from a struct's base address, plus alignment and padding.

30 minutes

4
Global versus Local Storage

Globals in .data, .bss, and .rodata reached by RIP-relative addressing, versus locals on the stack.

25 minutes

5
A Glimpse of the Heap

What new and delete look like in assembly, and how they differ from stack allocation.

25 minutes

6
Chapter 5 Summary and Quiz

Review pointers and references in registers, array indexing, struct layout and padding, global storage sections, and heap allocation.

20 minutes

C++ Features in Assembly (6 lessons)

What distinctly C++ constructs look like at machine level: member functions and the hidden this pointer, constructors and destructors, virtual dispatch through vtables, templates, and a glimpse of exceptions.

1
Member Functions and the this Pointer

A member function is an ordinary function whose first, hidden argument is the object's address in rdi.

30 minutes

2
Constructors, Destructors, and RAII

Constructors and destructors are function calls you never wrote, and RAII is the compiler placing destructor calls on every exit path.

30 minutes

3
Virtual Functions and vtables

How a virtual call becomes a double indirection: load the vtable pointer, load the function pointer, call through it.

30 minutes

4
Templates in Assembly

Templates vanish at compile time: each instantiation is a separate, fully concrete function, often with a mangled name.

25 minutes

5
A Glimpse of Exceptions

What throw and try/catch add to a listing, landing pads and unwind tables, and why the happy path stays almost free.

25 minutes

6
Chapter 6 Summary and Quiz

Review the hidden this pointer, constructor and destructor calls, vtable dispatch, template instantiation, and the cost model of exceptions.

20 minutes

The Optimizer at Work (8 lessons)

Comparing -O0 to -O2 and the transformations behind the difference: constant folding, inlining, dead code elimination, loop unrolling, and vectorisation, capped by reading a full real-world function.

1
Comparing -O0 and -O2

The same function at both optimization levels, and what the optimizer strips away.

30 minutes

2
Constant Folding and Propagation

The compiler computing constant expressions at compile time so the program does not have to.

25 minutes

3
Inlining

How small functions are absorbed into their callers and the call disappears.

25 minutes

4
Dead Code Elimination

How unused computations and unreachable code are removed entirely.

25 minutes

5
Loop Unrolling

How loops are expanded to cut per-iteration overhead.

25 minutes

6
A Glimpse of Vectorisation

SIMD registers and packed instructions that process several elements at once.

30 minutes

7
Capstone: Reading a Real Function

A line-by-line walkthrough of a complete optimized function that combines a loop, array indexing, a function call, and a conditional, drawing on every chapter of the course.

40 minutes

8
Chapter 7 Summary and Quiz

Review the optimizer's core transformations and consolidate the reading skills from the whole course.

20 minutes