CS ATLAS A map of computing

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.

ROM32K instructionsPCnext addressCPUA / D / ALUMemoryRAM + screenaddressinstruction[16]next pcaddress / outMinMloadOne instruction per cycle: ROM emits it, the CPU executes, A / D / M are written, PC advances
ItemSpec
Word size16 bits
Instruction memory32K × 16 (addresses 0–32767)
Data memory32K × 16 (addresses 0–32767)
RegistersA, D, PC
Instruction kindsTwo (A and C)
CycleOne 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.

Data0 – 16383Screen16384 – 24575Keyboard24576Unused24577 – 32767RAM (32K words, 16 bits each)addresses start at 0ROM is separate: 0 – 32767, instructions
Address rangeWhat it isHow it is used
0 – 16383DataR0–R15, variables, the stack
16384 – 24575Screen (8K words)Write a 1 to light a pixel
24576KeyboardRead the scan code of the key held
0 – 32767(ROM)InstructionsRead 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.

RegisterRoleWho can write it
AData + address (M = RAM[A])The A instruction, or dest of a C instruction
DData onlydest of a C instruction
PCAddress of the next instructionOnly 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:

1. fetch2. execute3. write back4. PC+1All four happen in one beat, so one instruction = one 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.

one row = 32 words = 512 pixelseach word’s 16 bits = 16 pixels (1 on / 0 off)1001001001001001address of row r, word c = 16384 + 32 × r + c

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.

CircleThe question it asksHack’s answer
Lower boundCan it compute anything computable?Read/write memory, add and subtract, conditional jump, unconditional jump — all four present
ProgrammabilityDo common statements need detours?18 ALU functions covering constants, moves, negation, add/subtract, and/or
BuildabilityCan 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.

ROMinstructioninstruction[16]Control logicsplits bits this beatALU control bitsdest / jumpNo IR: the instruction is decoded directly, never stored
With an IR (multi-cycle)Hack (single cycle)
Where it livesAn IR, 16 bitsNowhere: ROM’s output feeds the control logic directly
One instructionSeveral cycles (fetch / decode / execute…)Everything in one cycle
ReuseYes (microcode, replay)No, discarded after use
Cost16 more bits of register, write control, timingSaved — 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.

RegisterRoleWhat nothing else can do
AData register + address registerThe only register that can hold an address (M = RAM[A])
DAccumulatorThe ALU’s x input always comes from D
PCNext instruction addressMaintained 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.

SourceWhat it asks forHow Hack answers
HardwareInstructions can only use what the datapath hasOnly A and D; the ALU has only 18 functions
SoftwareCommon statements must be expressible directlycomp covers constants, moves, negation, add/subtract, and/or
CostDecoding must be simple and gate count smallFixed 16 bits; the top two bits identify the instruction
CompatibilityExisting software must not be invalidatedHack carries no legacy, so it starts from zero

The derivation chain (each step forced by the previous one):

GivenIt forces
16-bit wordsInstructions are 16 bits
One instruction per cycleInstruction bits must be the control bits; no microcode
Only A and Ddest needs 3 bits (A / D / M)
18 ALU functionscomp needs 7 bits (a plus 6 control bits)
Jumps read zr / ngjump needs 3 bits (6 conditions, plus no jump)
15-bit addressesAn 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):

DimensionOptionsHack
Instruction lengthFixed / variableFixed 16 (decode reads the top bit only)
Operand styleRegister-register / register-memory / accumulatorAccumulator (D + A/M)
RegistersFew (save encoding) / many (save memory traffic)Two
AddressingDirect / indirect / indexedIndirect (M = RAM[A])
Instruction countFew (simple) / many (expressive)Two formats
Field layoutPacked / regularRegular (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 + 1 is 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.

Software needswhat programs to writeISA draftformat and encodingHardware costgates / cycles / registersadjustcut features or add fieldsiterate until both sides agree
ModeOrderFitsExamples
Hardware firstBuild the circuit, then wrap its abilities as instructionsGoal is buildability, with budget or process limitsEarly computers, Hack, teaching CPUs
ISA firstDecide what software needs, then design hardwareGoal is comfortable programming, with legacy compatibilityIBM 360, x86 clones
Co-designDraft → cost → reviseBoth matter, and schedule is flexibleARM, 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 gatesHardware first
The goal is easy compilation and programmingISA first
Both, with a flexible scheduleCo-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.