awesome-everything RU
↑ Back to the climb

Base CS from zero

The processor: build a CPU simulator

Crux Build a working software simulator of the toy CPU — registers, program counter, memory, and a fetch-decode-execute loop — then run a real machine-code program through it.
Your altitude — climbing toward senior
ZeroJuniorMiddleSenior
You are at middle altitude — in the sky
◷ 220 min

You traced the toy CPU by hand. Now make the machine real: write a program that IS the CPU. When your fetch-decode-execute loop runs a chunk of machine code and lands the right number in the right memory cell, the processor stops being an abstraction and becomes something you built.

Goal

Turn the unit’s mental model into running code. You will implement the toy CPU’s state (registers, program counter, memory), its instruction set, and the fetch-decode-execute loop, then hand it a machine-code program as bytes and watch it compute the right answer — proving you understand the loop by making it execute.

Project
0 of 6
Objective

Implement a software simulator of the unit's toy CPU in any language you like. It must hold its own state, decode raw machine-code bytes, run the fetch-decode-execute loop until it halts, and produce the correct final memory and register state for a given program.

Requirements
Acceptance criteria
  • The sample addition program prints a four-cycle trace ending with mem[202] = 42 and PC = 8, matching the lesson's worked example exactly.
  • Decoding is done from the raw bytes/bits (opcode and register extracted from byte 0), not by storing pre-parsed instruction objects — feeding in different bytes runs a different program with no code change.
  • A program containing a JUMP visibly skips the instruction it jumps over in the trace, and the PC value after the JUMP equals the jump target, not PC + 2.
  • A short write-up (a few sentences) explaining, in your own words, where in your code the Fetch, Decode, and Execute steps live and how the program counter drives the loop.
Senior stretch
  • Add a conditional branch: a JUMP-IF-ZERO opcode plus a one-bit zero flag set by ADD, then write a program that uses it to implement a countdown loop (decrement R0 until it reaches zero) — proving loops are just conditional jumps.
  • Add a clock-cycle counter (1 cycle per instruction) and report total cycles and the simulated run time at an assumed clock rate (e.g. 2 GHz), connecting the trace to real timing.
  • Hand-assemble a slightly larger program (e.g. sum the four numbers at addresses 200-203 into 204 using a loop) into machine-code bytes yourself, then run it — practising the compiler's job of turning intent into the instruction set.
  • Write a tiny assembler: accept text like 'LOAD R0, 200' and emit the correct 2-byte encoding, so you can author programs in mnemonics instead of raw bytes.
Recap

Building the simulator forces every idea in the unit to become concrete: registers and the program counter are just variables, memory is just an array, machine code is just the bytes you load in, and the fetch-decode-execute cycle is a literal loop reading the bytes the PC points at. When your trace matches the lesson cycle for cycle and a JUMP visibly redirects the PC, you have proven the processor is not magic — it is a loop you can write yourself in an afternoon.

Continue the climb ↑The assembler idea
shortcuts expand
search
K
prev piece
k
next piece
j
cycle tier
t
this menu
?
sources2
expand
  1. 01
  2. 02

Trademarks belong to their respective owners. Editorial reference only.