The Hack Computer
Specification: the manual for a machine
Before writing programs you need to know what the machine promises: how many parts, how memory is split, where addresses come from, and what one beat can finish. This page covers the specification only; it does not take the CPU apart.
01Four parts, one instruction path
The machine has only four parts: CPU, ROM (instructions), RAM (data, screen, keyboard) and PC. Three groups of lines connect them: address, data and control.
| Item | Spec |
|---|---|
| Word size | 16 bits |
| Instruction memory | 32K × 16 (addresses 0–32767) |
| Data memory | 32K × 16 (addresses 0–32767) |
| Registers | A, D, PC |
| Instruction kinds | Two (A and C) |
| Cycle | One instruction per beat |
02The memory map: address is everything
There are no device registers: the screen and keyboard are just memory at particular addresses. A program reaches them exactly as it reaches an ordinary variable.
| Address range | What it is | How it is used |
|---|---|---|
| 0 – 16383 | Data | R0–R15, variables, the stack |
| 16384 – 24575 | Screen (8K words) | Write a 1 to light a pixel |
| 24576 | Keyboard | Read the scan code of the key held |
| 0 – 32767(ROM) | Instructions | Read wherever PC points |
So @SCREEN is just @16384 and @KBD is just @24576 — predefined symbols in the assembler, not new instructions.
03Two registers, one address
A has two roles: it is a data register and an address register. When the CPU touches memory it uses the value in A: M always reads and writes RAM[A].
D holds data only. So moving a value out of memory takes two steps: put the address in A, then use M.
| Register | Role | Who can write it |
|---|---|---|
| A | Data + address (M = RAM[A]) | The A instruction, or dest of a C instruction |
| D | Data only | dest of a C instruction |
| PC | Address of the next instruction | Only jumps and reset |
This is why every memory operation in machine language is preceded by @address — not verbosity, but the fact that the hardware has one address line, and it is wired to A.
04Four things per beat
One tick of the clock and the machine does four steps in lockstep. They are not four cycles; they are four stages of the same cycle:
- Fetch: send the 16-bit instruction at ROM[PC] to the CPU.
- Execute: compute once as the instruction says (the ALU), or just load a constant into A.
- Write back: store the result into some of A / D / M.
- PC+1: advance by default; if the instruction jumps and its condition holds, load A instead.
"One computation per instruction" is not laziness: the ALU can only run once per cycle.
05Screen: 8K words, 512×256 pixels
The screen is not drawn, it is written. One row of 512 pixels is 32 words, and each word’s 16 bits are 16 pixels.
Address arithmetic: row r, word c is 16384 + 32 × r + c; to light pixel b, set that bit to 1. 256 rows × 32 = 8192 words, exactly 8K.
06Boot: PC starts at 0
On reset PC = 0 and the CPU immediately reads ROM[0]. So the first instruction must live at address 0 — there is no operating system, no loader; power on and it runs.
That is why assembly programs often start with:
@0 0;JMP // jump to the real entry point (or just start here)
A program is always loaded from ROM[0]; if you write a label such as (LOOP), the assembler turns it into a line number in ROM.
07Design thinking: three circles bound the machine
The spec is not a wish list; it is the intersection of three circles.
| Circle | The question it asks | Hack’s answer |
|---|---|---|
| Lower bound | Can it compute anything computable? | Read/write memory, add and subtract, conditional jump, unconditional jump — all four present |
| Programmability | Do common statements need detours? | 18 ALU functions covering constants, moves, negation, add/subtract, and/or |
| Buildability | Can a student build it from the chips at hand? | One adder, one AND gate, a few multiplexers |
The bar for universality is very low: in theory, memory access plus subtraction plus a conditional branch is enough for Turing completeness (one-instruction computers exist).So only four or five of those 18 functions are truly necessary; the rest trade a handful of gates for a lot of writing comfort.
Acceptance testing is plain: try the programs you must be able to write — multiplication (repeated addition), filling the screen, echoing the keyboard, a call stack.If they can be written at all, the lower bound holds; if they write smoothly, programmability is enough.
08Why there is no instruction register
A classic CPU has an IR (instruction register): the fetched instruction is stored, then decoded slowly over several cycles. Hack has none —because an instruction lives for exactly one cycle.
| With an IR (multi-cycle) | Hack (single cycle) | |
|---|---|---|
| Where it lives | An IR, 16 bits | Nowhere: ROM’s output feeds the control logic directly |
| One instruction | Several cycles (fetch / decode / execute…) | Everything in one cycle |
| Reuse | Yes (microcode, replay) | No, discarded after use |
| Cost | 16 more bits of register, write control, timing | Saved — but the instruction must be fully used in that beat |
Put another way: Hack’s instruction format is the format of the control signals. The 16 bits from ROM are split within the beat into ALU control bits, dest and jump — nothing is buffered.
09Why two registers, A and D, are enough
Two reasons: one from encoding, one from function.
Encoding: the 16 bits are already full — opcode, comp, dest, jump. More registers mean wider dest and source fields,and comp only has 6 bits to spare — one more register and the whole format changes.
Function: A does two jobs (data and address), D is the accumulator.Two registers plus memory can express any program; when you run out, spill temporaries to RAM.
| Register | Role | What nothing else can do |
|---|---|---|
| A | Data register + address register | The only register that can hold an address (M = RAM[A]) |
| D | Accumulator | The ALU’s x input always comes from D |
| PC | Next instruction address | Maintained by hardware; programs change it only by jumping |
The price is real: too many temporaries and you spill to RAM, so Hack assembly needs careful use of D and A.Real CPUs have 16–32 registers for exactly this reason — at the cost of more encoding bits and decode logic.
10What the instruction set is designed from
An instruction set is a contract between software and hardware: software promises to issue only these commands; hardware promises to finish each in one cycle.So it is not designed from "what would be nice" but from four sources asking at once.
| Source | What it asks for | How Hack answers |
|---|---|---|
| Hardware | Instructions can only use what the datapath has | Only A and D; the ALU has only 18 functions |
| Software | Common statements must be expressible directly | comp covers constants, moves, negation, add/subtract, and/or |
| Cost | Decoding must be simple and gate count small | Fixed 16 bits; the top two bits identify the instruction |
| Compatibility | Existing software must not be invalidated | Hack carries no legacy, so it starts from zero |
The derivation chain (each step forced by the previous one):
| Given | It forces |
|---|---|
| 16-bit words | Instructions are 16 bits |
| One instruction per cycle | Instruction bits must be the control bits; no microcode |
| Only A and D | dest needs 3 bits (A / D / M) |
| 18 ALU functions | comp needs 7 bits (a plus 6 control bits) |
| Jumps read zr / ng | jump needs 3 bits (6 conditions, plus no jump) |
| 15-bit addresses | An A instruction is 0 plus a 15-bit value |
Add the fields up: 3 (opcode) + 1 (a) + 6 (comp) + 3 (dest) + 3 (jump) = 16.The format was not chosen and then filled; the content filled all 16 bits.
The classic trade-offs (every ISA picks one; Hack’s choice in bold):
| Dimension | Options | Hack |
|---|---|---|
| Instruction length | Fixed / variable | Fixed 16 (decode reads the top bit only) |
| Operand style | Register-register / register-memory / accumulator | Accumulator (D + A/M) |
| Registers | Few (save encoding) / many (save memory traffic) | Two |
| Addressing | Direct / indirect / indexed | Indirect (M = RAM[A]) |
| Instruction count | Few (simple) / many (expressive) | Two formats |
| Field layout | Packed / regular | Regular (fixed fields, zero decode cost) |
How to check the design — not by feel, but with four tests:
- Expression: can you write multiplication, screen drawing, keyboard echo and a call stack?
- Encoding: do all fields fit in the word? (Hack comes to exactly 16.)
- Cost: how many gate levels to decode? Hack needs the top two bits.
- Writing: how many instructions does a common statement take?
a = a + 1is two in Hack:@a; M=M+1.
This is why Hack’s instruction set looks simple: it is not a cut-down version but the only solution under three constraints — 16 bits, one cycle, two registers.
11Design order: which comes first
In real engineering, ISA and hardware are polished against each other: needs come first, then a draft of instructions, then a cost estimate; what is too expensive gets cut, and then you check the software again.Hack takes one edge of that loop — hardware first.
| Mode | Order | Fits | Examples |
|---|---|---|---|
| Hardware first | Build the circuit, then wrap its abilities as instructions | Goal is buildability, with budget or process limits | Early computers, Hack, teaching CPUs |
| ISA first | Decide what software needs, then design hardware | Goal is comfortable programming, with legacy compatibility | IBM 360, x86 clones |
| Co-design | Draft → cost → revise | Both matter, and schedule is flexible | ARM, RISC-V |
Hack’s actual order: gates (P1) → the ALU’s 18 functions (P2) → registers and RAM (P3) → the machine spec → the instruction format.The format comes last, and it is almost forced by everything before it rather than designed.
So why does the course give you the ISA before the CPU? Because the CPU needs a target: without knowing what instructions look like,you would not know what the control logic decodes. The order is “hand over the contract, then honour it” — and the client side of that contract is what you built in P1–P3.
| If… | Then |
|---|---|
| The goal is a working machine from limited gates | Hardware first |
| The goal is easy compilation and programming | ISA first |
| Both, with a flexible schedule | Co-design: draft, estimate, revise |
The rule is one sentence: satisfy the harder constraint first. Hack’s hard constraint is that a student can build it from the chips at hand,so hardware comes first.
A counter-example: starting from the ISA would probably give "8 general registers + shifts + multiply" — reasonable sounding,but 16 bits cannot hold fields for 8 registers, and a multiplier costs thousands of gates. ISA-first tempts you with features and charges you in buildability.