Part 0 · Orientation
Why you will never write this
The goal is reading, not writing — and that single decision changes the whole syllabus. Plus the five rules that make it work.
What this lesson is trying to break (3)
- Learning assembly means learning to write assembly.
- Assembly is obsolete because compilers are better than humans now.
- Knowing assembly means you should hand-optimise things.
If you have worked through Reading Rust, you were repeatedly told things were “zero-cost” and asked to take it on trust. This course is where that trust gets cashed.
If you have not: the short version is that you are about to learn to read the layer everything else sits on, and you will not be asked to write a single line of it in anger.
The goal, stated precisely
You will learn to read assembly. You will not learn to write it.
That is not modesty, it is a design decision, and it changes everything downstream. A course that taught writing would spend weeks on syntax drills, manual register allocation, and hand-rolled loops — skills you would use once and then never again, because the compiler is better at all three.
What you will be able to do:
- Open a profiler’s disassembly view and know what you are looking at.
- Answer “what does this line cost?” to an order of magnitude.
- Tell whether a performance claim is supported, including your own.
- Read
-O2output and see which of your abstractions survived.
That last one is the payoff, and it is the reason this pairs with the Rust course. “Iterator chains compile to the same loop” is a claim. In 3.6 you check it.
The objection, answered
“Compilers beat humans at this now. Why bother?”
Correct, and irrelevant — you are not competing with the compiler, you are reading its work. The fact that it is good is precisely what makes the output informative. If compilers were bad, their output would tell you about the compiler. Because they are good, the output tells you about the machine, and about what your source code actually asked for.
An analogy that may land: you do not need to be able to typeset a book to benefit enormously from being able to read one.
The first look
Let us establish the loop immediately. This is the pattern for every lesson.
Here is a C function. Below it are two buttons that compile it for real and show you the assembly.
int square(int x) {
return x * x;
}Before you press anything: how many instructions do you expect at -O2?
Write an actual number, not “a few”.
Press x86-64. You will see exactly this:
"square":
imul edi, edi
mov eax, edi
retThree. And two of them are not the multiplication.
edi holds the first argument — that is the calling convention
(2.2). eax holds the return value. So the function is
“square the argument where it already sits, copy it to the return register,
return”.
Note the order, because it is a small lesson in itself: gcc multiplied in place
in edi and copied afterwards, rather than copying to eax first and
multiplying there. Both are three instructions and both are correct. Which one
you get is a register-allocation decision, not a meaningful difference — and
noticing that a difference is not meaningful is as much a reading skill as
noticing that one is.
Now press ARM64 and read them side by side:
square:
mul w0, w0, w0
retTwo. ARM64 uses w0 for both the first argument and the return value, and
its mul takes three operands — destination, source, source — so no copy is
needed.
That comparison is the whole method of this course in miniature. Same source, same compiler version, one variable changed. What differed was incidental: register names, operand count, whether a copy was needed. What stayed the same was essential: arguments arrive in registers, results leave in registers, and there is exactly one multiply because that is what you asked for.
If you guessed 1, you forgot that arguments and return values have to live
somewhere specific. If you guessed 10, you were probably imagining -O0, which
is a different and much sadder listing — see
3.2.
Why this course is uncomfortable on purpose
The same reasoning as the Rust course, so briefly:
Reading a well-written explanation produces fluency — smooth, pleasant, and almost uncorrelated with whether you can use the material later. The fix is desirable difficulties (Robert Bjork’s term): retrieval, spacing, interleaving, and generation. Each makes practice feel worse and learning measurably better, which is roughly why you have not met them in a programming course.
Assembly has a specific extra trap. It looks simple — short lines, few keywords, no abstractions — so it produces false confidence faster than almost any other subject. You can read a listing, follow every individual instruction, and still have no idea why one version is four times faster. Part 4 exists entirely because of that gap.
The five rules
1. Commit a number before you compile. The Predict boxes ask “how many instructions?” or “will there be a branch?”. Write the number. A vague sense is too imprecise to be wrong, and something that cannot be wrong cannot teach you anything.
2. Always compile both ISAs. Two clicks instead of one. When you see the same idea in x86-64 and ARM64, you learn which parts are properties of computers and which are trivia about one instruction set. One-ISA knowledge is mostly trivia you cannot yet identify as trivia.
3. Rate your confidence honestly, especially when it is high. Calibration records it and shows you your accuracy at each level. For an experienced engineer, overconfidence — not inability — is the obstacle, and it is invisible without measurement.
4. Come back on days you did not plan to. The Review queue mixes topics deliberately. Working out which idea applies is the part that survives contact with unfamiliar code.
5. Never argue from instruction count alone. This is the rule specific to this subject, and it is the one you will break. Fewer instructions is not faster. By Part 4 you will know why, and until then treat any “it’s fewer instructions” argument — including your own — as unfinished.
Write down the actual reason you want to read assembly. Be concrete: a profiler you could not interpret, a performance argument you could not settle, a claim you had to accept on trust.
Keep it. Around Part 4 the material gets hard enough that a specific motivation is worth more than a general one.
About the English
Assembly’s vocabulary is small but unusually treacherous, because many terms are ordinary English words with narrow technical meanings — word, page, frame, flag, port, retire, stall, pressure. A word is not a word. Retiring an instruction has nothing to do with finishing.
So the Glossary gives each term a plain definition and a sentence showing how engineers actually use it, because “there’s port pressure on the load units” is a thing people say and it is not guessable from the parts.
What comes next
0.2 gives you the frame: the claim that assembly presents four convenient fictions, and that fluency means knowing both the fiction and where it breaks. It also contains a six-question pretest.
You will do badly on it. That is intended and it is not a figure of speech — being tested on material you have not learned improves how well you learn it afterwards, including the questions you get wrong. Do not look anything up.