Exercise 2: Resolving a Cross-File Label — Possible Solution ==================================================================== Setup: main.asm calls a label that is only defined inside helper.asm. WHICH STAGE RESOLVES IT ------------------------------ The LINKER stage. Per the chapter's own four-stage pipeline: 1. Assembler -- turns EACH source file into its OWN object file, independently. When the assembler processes main.asm, it has no visibility into helper.asm at all -- it can recognize that main.asm *references* a label it can't find locally, but it cannot resolve that reference to an actual address yet. It marks it as an unresolved external reference and moves on. 2. Linker -- this is the stage that actually looks across MULTIPLE object files at once. It combines main.asm's object file and helper.asm's object file into a single executable image, and in doing so, matches main.asm's unresolved reference against the label helper.asm actually defines, filling in the real address. 3. Loader -- only runs after linking is already done; it just copies the finished, fully-resolved executable into memory. 4. CPU execution -- runs the final program; by this point there's no such thing as an "unresolved reference" left at all. WHAT WOULD GO WRONG IF LINKING WERE SKIPPED ------------------------------ If the pipeline jumped straight from assembling to loading (skipping the linker), main.asm's object file would still contain a placeholder for the address of helper.asm's label -- because the assembler alone was never able to fill it in. Loading and running that object file directly would mean the CPU eventually tries to execute an instruction whose operand points at an unresolved, meaningless address -- not "the program fails with a clear error," but a jump or reference to essentially garbage, which is exactly the kind of failure the linker exists to prevent by catching and resolving it before the program ever runs. WHY THIS WORKS AS AN ANSWER ------------------------------ It names the specific stage (linker, not assembler or loader) using the chapter's own four-stage breakdown, explains *why* the assembler alone can't do it (each file is assembled independently, with no visibility into other files), and describes a concrete consequence of skipping the stage rather than a vague "it wouldn't work."