Open-source project
mschwartz/assembly-tutorial avatar
mschwartz/assembly-tutorial

The assembly tutorial starts with a cardboard CPU from Bell Labs

Programming in assembly language tutorial

2,046 stars139 forksAssemblyLicense varies

At a glance

What is it?
mschwartz' assembly tutorial is a single README file that teaches AMD64 programming by starting from CARDIAC, a paper teaching aid with ten opcodes and two registers, then building up to paging, the MMU and ELF loading. The repository holds four entries in total.
Who is it for?
This tutorial suits a programmer who already knows a high level language and wants to understand what the CPU actually executes, especially for embedded work, compiler work or operating systems. It does not suit someone who needs ARM or RISC-V instruction detail, since it is x86-64 only, and it is not a reference on optimization.
Can I use it commercially?
Not without permission. GitHub finds no licence file in the repository, and without a licence all rights are reserved by default: you may read the code but not reuse it. Check the README, or ask the authors, before using it.
Is it still maintained?
Yes. The repository last received commits 161 days ago.
What is it written in?
Mainly Assembly, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 6, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Four entries, one of which is the tutorial

Before reading a word of it, look at what the repository actually is. There are four top-level entries: a .gitignore, a README.md, a hello-world directory, an images directory and an instruction-set directory. The tutorial is the README, and it is long enough to carry a table of contents with three top-level parts. The Introduction part covers number bases, math, boolean algebra, bit shifting, memory, ELF files and the loader, permissions, sections and privileged instructions, the MMU with paging and swapping, four kinds of exception, the ALU, and the x64 register set including general purpose, special purpose and CPU control registers. The AMD64 Instruction Set part covers assembly source and addressing modes. The third part is a practical reference of commonly used instructions organized by task, then assembler directives, and then Hello World written twice. A hello-world directory and an images directory support the text rather than duplicating it. There is no build system, no package manifest, no test suite and no license file in the listing, which tells you what kind of artifact this is.

CARDIAC is the model the rest of the tutorial keeps returning to

The opening move is unusual and deliberate. The author describes discovering how CPUs work as a kind of lost art, notes that a small percentage of engineers need it, typically those on embedded software, operating systems, compilers or JIT compilers, and then starts not with a register but with a cardboard teaching aid called CARDIAC, which stands for CARDboard Illiustrative Aid to Computation, developed at Bell Labs. The personal framing is given too: assembly was one of the author's first languages, learned in high school classes that went from BASIC to FORTRAN IV to BAL for the IBM 360, and CARDIAC was one of the earliest lessons. The relevance to a reader today is that CARDIAC removes the first barrier. Its numbers and instructions are in base 10, so a beginner does not have to understand base 2, base 8 or base 16 before understanding what a computer does. You write the program and variables on the cardboard, then step through it performing each operation by hand.

Ten opcodes and two registers are enough to learn from

The CARDIAC instruction set is listed in full, and it is worth reading as a table because the later material maps onto it. Step 0 is INP, read a card into memory. Step 1 is CLA, clear the accumulator and add from memory. Step 2 is ADD from memory into the accumulator. Step 3 is TAC, test the accumulator and jump if negative. Step 4 is SFT, shift the accumulator. Step 5 is OUT, write a memory location to an output card. Step 6 is STO, store the accumulator to memory. Step 7 is SUB, subtract memory from the accumulator. Step 8 is JMP, jump and save the program counter. Step 9 is HRS, halt and reset. The point made about it is that the CPU has only two registers, an accumulator and a program counter, where modern CPUs have many more, and that this is enough to learn from, because you pick up memory layout, instruction opcodes, instruction encoding and memory access along the way. The tutorial then states the through-line explicitly: as it progresses, the CPU being programmed turns out to be a glorified version of CARDIAC.

Number bases and memory come before any instruction

The course order is the argument for how assembly should be learned, and it is bottom-up rather than top-down. A bit is introduced as the smallest piece of information a CPU processes, a boolean of 0 or 1. Bits group into bytes of eight, which the tutorial draws as a row of digits:

code
76543210

The note that follows says that a byte represents an unsigned value of 0 to 255 or a signed value of -128 to 127 and that bit 7 is the sign bit. The text then makes a point novices usually miss: whether a byte is treated as signed or unsigned is a decision, not a property. After math and boolean algebra come bit shifting and then memory, and only after memory does the ELF section and the loader appear. Permissions, sections and privileged instructions follow, then the MMU and paging and swapping. The exceptions chapter handles segfault, divide by zero, invalid opcode and general protection. So the reader meets the machinery of a process before meeting a single instruction, which is the reverse of how the hardware manuals are usually written.

Addressing modes get a four-part breakdown

The AMD64 instruction set section is where the tutorial becomes a reference rather than an introduction, and the part worth stopping on is addressing modes, broken into four forms. Register operands operate entirely in registers. Direct memory operands are described in the table of contents as better known as immediate operands, which is a naming collision with the assembler's immediate syntax that will confuse anyone who knows another assembler. Indirect operands dereference through a register, so the register holds the address. Indirect with displacement adds a constant offset. Indirect with displacement and scaled index adds the register times a scale factor plus an offset, which is the form that makes array indexing cheap in assembly and that no high level language exposes. After addressing modes the tutorial moves into commonly used instructions, grouped by what you are trying to do: arithmetic, boolean algebra, branching and subroutines, bit manipulation, register manipulation with casting and conversions, flags manipulation, and stack manipulation. The instruction-set directory at the repository root is where a fuller reference lives.

Assembler directives are documented, Hello World is written twice

The assembler section covers what you write around the instructions, which is where beginners often stall. Section type is first, then the bits directives in 16, 32 and 64 bit forms and their use16, use32 and use64 equivalents, then comments, constants, program variables and strings, assembler variables and labels, repetition, macros, conditional assembly, alignment, structures and includes. The table of contents misspells repetition as Repetion, which is a small reminder that this is one person's notes rather than an edited manual. Hello World follows in two variants, a macOS version and a Linux version, each followed by a how it works subsection covering Linux syscalls and macOS syscalls. That pairing is the practical payoff of the whole tutorial: two systems with the same instruction set and different ways of asking the kernel for the same thing, which is precisely the difference that trips up a program written once and moved between them.

Where this tutorial stops being enough

Three limits are worth naming before you plan a course from it. The first is architecture. The tutorial states up front that it covers AMD64 and Intel 64 bit programming, that instruction sets for other processors such as ARM or RISC-V are radically different, and that the concepts are the same even though the instructions are not. The author argues from experience that moving from Z80 to 6502 to 6809 to 8086 to 68000 took hours to be productive and a week or two to be writing quality code, which is a reasonable expectation to set. The second is depth. The audience is stated as novices and beginners who want to learn the first thing about assembly, with the note that an expert may or may not get a lot out of it, and the organization matches that: it is an introduction with a reference section attached, not a manual on optimization, on calling conventions or on a specific instruction set reference. The third is practice. There is no exercise set and no test suite in the repository, so the learning happens by writing code and reading manuals, which the author recommends by pointing at a processor's technical manuals as the way to evaluate an instruction set's power and flexibility.

Editorial conclusion

This tutorial suits a programmer who already knows a high level language and wants to understand what the CPU actually executes, especially for embedded work, compiler work or operating systems. It does not suit someone who needs ARM or RISC-V instruction detail, since it is x86-64 only, and it is not a reference on optimization. Before adopting, read the CARDIAC introduction and the four-part addressing modes section, then compile the Linux Hello World from the hello-world directory to check your assembler toolchain against the text.

Frequently asked questions

What is CARDIAC and why does the assembly tutorial start with it?

CARDIAC stands for CARDboard Illustrative Aid to Computation, a Bell Labs teaching device that simulates a mythical CPU with ten opcodes numbered 0 to 9 and two registers, an accumulator and a program counter. It uses base 10 numbers so a beginner can learn memory layout, opcodes and memory access before learning number bases.

Which processor architecture does this tutorial cover?

AMD64 and Intel 64 bit. The README says instruction sets for other processors such as ARM or RISC-V are radically different, and that the concepts transfer even though the instructions do not.

What order does the tutorial teach things in?

Bottom-up. Bits, bytes, words and number bases come first, then math, boolean algebra, bit shifting, memory, ELF files and the loader, permissions and privileged instructions, the MMU with paging and swapping, exceptions, the ALU, and registers, before any instruction set detail.

Does the tutorial cover system calls?

Yes, Hello World is written twice, a macOS version and a Linux version, each followed by a how it works section covering macOS syscalls and Linux syscalls separately.

What are the addressing modes the tutorial describes?

Four: register operands, direct memory operands, indirect operands, indirect with displacement, and indirect with displacement and scaled index. Direct memory operands are labelled better known as immediate operands in the table of contents.

Official sources

  1. Issues
  2. mschwartz/assembly-tutorial on GitHub
  3. README