Your assembler in week 6 produced VOF object files with unresolved symbols. This week you write the static linker that resolves those symbols, applies relocations, and produces a flat binary image. By end of week you can compile two separate source files, link them, and run the result on your CPU.
Reading
- Chapter prose (primary). draft-chapters/ch6a-linker-prose.md
- Petzold weave anchors. Ch 24 Languages High and Low p. 351 (the parenthetical that names the linker's existence: "Actually there's another step in the process, but it's not important in this account of what happens"); Ch 22 The Operating System p. 328 (the bootstrap loader); Ch 17 Automation p. 223 (the stored-program model; code and data in the same RAM)
- Cross-chapter handouts. VOF v1 layout reference; instruction memory layout
Lecture
lectures/ch6a-static-linker-lecture.md. 3 hours. Key arc:
- Symbol resolution. The linker collects all symbol definitions across all input object files; it matches each undefined symbol reference to a definition
- Relocation. Once symbols have final addresses, the linker walks each relocation entry and patches the encoded instruction bytes to use the resolved address
- Two relocation types: PC-relative (for branches and jumps within the binary) and absolute (for data addresses)
- The linker produces a flat binary plus a memory map. Your CPU's bootloader reads the flat binary and starts executing at the entry point
Lab exercises
Five labs in worksheets/ch6a/.
- lab-6a.1-symbol-resolution.md
- lab-6a.2-two-relocation-types.md
- lab-6a.3-link-and-boot-two-files.md, two-file program runs on silicon
- lab-6a.4-corrupted-input-and-industry-reconciliation.md
- lab-6a.5-ghidra-whole-program.md, Ghidra returns
Plan for ~5 hours of lab.
Independent practice
- Read Petzold Ch 24 p. 351 carefully. The parenthetical that names the linker is small but pointed; the academy curriculum brings the linker to the foreground because it is operationally central in every real toolchain
- Update your Toolchain Diary. Week 7 introduces:
ld(the GNU linker, for reconciliation),readelf -rfor relocation inspection,objdump -dfor whole-program disassembly - Optional: read Levine, Linkers and Loaders Ch 1-3. Industry-grade depth on what your week's work covers in miniature
Architecture comparison sidebar
Static linking copies all referenced library code into the final binary; dynamic linking defers the resolution to load-time or even call-time. CSA-101 uses static linking exclusively (simpler; the binary is self-contained). CSA-201 introduces dynamic linking. The trade-off is binary size (static is larger) versus runtime startup cost (dynamic adds a resolution step) versus update flexibility (dynamic lets you upgrade libraries without recompiling).
Reflection prompts
- The linker is "another step in the process, but it's not important in this account of what happens" (Petzold p. 351). Why did this course spend a whole week on the step Petzold parenthesized?
- Symbol resolution and relocation feel like clerical work. What would happen if you skipped them and just concatenated the object files byte-for-byte?
- Your linker's output is a flat binary. A real OS executable (ELF) has additional sections (program headers, dynamic-loader metadata, debug info). What pressures cause the difference?
What's next
Week 8 introduces virtual machines. Your toolchain so far goes: assembly → object file → flat binary. Now we add a layer on top: a stack-based VM that compiles to your assembly. The first time the toolchain has two layers between source and silicon.