CS ATLAS A map of computing

Project 6 · Assembler

Assembly language and the assembler

Assembly language is a low-level language that maps almost one to one onto machine instructions: one statement is usually one instruction, with mnemonics in place of 0s and 1s and symbols in place of addresses. It still faces registers, memory and jumps directly, with no functions in between. The program that turns those mnemonics into machine code is the assembler.

01Assembly: machine instructions written with symbols

It is called a language because the grammar is fixed: every line is one of three things — give an address, do a computation, or just mark a position.

FormMeaningEmits an instruction?
@valueAn A instruction: puts a number, or a symbol’s address, into Ayes, one
dest=comp;jumpA C instruction: compute, store, maybe jumpyes, one
(LABEL)A label: names the address of the next instructionno

Comments and blank lines emit nothing either. So line number ≠ address — exactly what the first pass works out.

02Why two passes: the forward-reference crisis

The dead end of a single pass:
@END       // crisis: on this line the assembler has no idea what END is!
D;JEQ
...
(END)      // only here does the assembler learn the address of END
In real code a conditional jump usually targets a label further down (used before defined). Scanning once, the assembler is stuck on the very first line: it cannot produce a complete 16-bit word.

The fix is a clean piece of engineering decoupling — two passes:

PassRoleWhat it doesOutput
FirstSurveyorMeasures only: counts instruction addresses, records the current address at each (LABEL)A complete label table
SecondBuilderWith the table in hand, turns every mnemonic and symbol into machine code with absolute addresses16-bit instructions

The first pass measures without building; the second builds to the plan. From then on, jumps forward or backward always land on a known address.

03Three kinds of names in the symbol table

KindExampleWhere the address comes from
PredefinedR0–R15, SCREEN, KBD, SP, LCL, ARG, THIS, THATFixed values
Label(LOOP)The instruction address counted in pass one
Variable@sumStarts at 16, allocated in order of first appearance

Allocation order changes addresses (whichever appears first gets 16), but behaviour does not change — names follow the addresses.

04Hands-on: edit the code and watch the translation

Edit assembly on the left; the symbol table and line-by-line machine code update on the right.

Symbol table

NameAddressType
R00predefined
R11predefined
LOOP6label
n16variable
sum17variable
END20label

Line by line

LineSourceAddressMachine codeHexNote
2@R0000000000000000000x0000predefined R0, RAM address 0
3D=M111111100000100000xFC10C instruction
4@n200000000000100000x0010new variable n, RAM address 16
5M=D311100011000010000xE308C instruction
6@sum400000000000100010x0011new variable sum, RAM address 17
7M=0511101010100010000xEA88C instruction
8(LOOP)——a label, no instruction
9@n600000000000100000x0010variable n, RAM address 16
10D=M711111100000100000xFC10C instruction
11@END800000000000101000x0014label END, instruction address 20
12D;JEQ911100011000000100xE302C instruction JEQ
13@sum1000000000000100010x0011variable sum, RAM address 17
14D=M1111111100000100000xFC10C instruction
15@n1200000000000100000x0010variable n, RAM address 16
16D=D+M1311110000100100000xF090C instruction
17@sum1400000000000100010x0011variable sum, RAM address 17
18M=D1511100011000010000xE308C instruction
19@n1600000000000100000x0010variable n, RAM address 16
20M=M-11711111100100010000xFC88C instruction
21@LOOP1800000000000001100x0006label LOOP, instruction address 6
220;JMP1911101010100001110xEA87C instruction JMP
23(END)——a label, no instruction
24@sum2000000000000100010x0011variable sum, RAM address 17
25D=M2111111100000100000xFC10C instruction
26@R12200000000000000010x0001predefined R1, RAM address 1
27M=D2311100011000010000xE308C instruction

No errors: 24 instructions, 6 symbols.

05The three usual mistakes

SymptomCauseFix
The label is “not found”Missing brackets when defining, or a colon when referencingDefine (END), reference @END
A variable lands at an unexpected addressAssuming variables start at 0They start at 16; 0–15 are R0–R15
@40000 is rejectedAn A instruction carries 15 bitsThe maximum is 32767

06After translation

source (.asm) → assembler → machine code (.hack) → ROM → CPU executes

The output is a stream of 16-bit words loaded into ROM in order (starting at address 0); after reset PC = 0 and the CPU runs the first one. How that loading and running works is on the whole machine page.

That is why the machine language page covers the instruction format first: the assembler only removes symbols; the encoding itself is unchanged.