Tiny CPU: the Little Man Computer

A program sits in the same hundred mailboxes as the numbers it works on. Step it and the page lights each move of the fetch–decode–execute cycle: a mailbox read in blue, a mailbox written in amber, the next instruction outlined in purple.

Loading interactive simulation...

Lesson

The theory — Tiny CPU: the Little Man Computer

The fetch–decode–execute cycle is what a processor does with every instruction. Fetch copies PC into MAR, reads that mailbox into MDR, copies it into CIR and adds 1 to PC. Decode splits the instruction into an operation (the hundreds digit) and an address (the last two digits), except for 901, 902 and 000, which are whole codes for INP, OUT and HLT and name no mailbox. Execute carries it out, which may read or write one more mailbox through MAR and MDR.

What each symbol means

PC
program counter: the address of the next instruction to fetch
MAR
memory address register: the mailbox about to be read or written
MDR
memory data register: the value just read, or about to be written
CIR
current instruction register: the instruction being run
ACC
accumulator: where ADD, SUB and LDA put their result
Assumes
Stuart Madnick's Little Man Computer (MIT, 1965) leaves undefined what happens when SUB goes below zero or ADD passes 999. This machine's accumulator holds −999 to 999, so BRP tests a sign, and a result outside that range stops the run with an overflow instead of wrapping. School simulators differ on this point, and a program whose accumulator stays between 0 and 999 runs the same on all of them.

The machine cannot tell a number from an instruction 🖖

Press Data run as code. The program is LDA n and OUT, written to print 105 once, and its author forgot HLT. So PC moves on to mailbox 02, where the 105 is stored, and the machine fetches it like any other instruction: 105 is ADD 05, and mailbox 05 holds 20. The next DAT is 902, which is OUT, so 125 is printed, and the one after is 0, which is HLT. Nothing in a mailbox says whether it holds an instruction or a number. It is an instruction if PC lands on it, and data if an LDA, ADD or SUB names it: the first instruction read this 105 as a number, and the third ran it. That is the stored-program idea, first run on the Manchester Baby in June 1948.

To read the next item in a list, this program rewrites itself 🖖

Press Sum a list and watch mailbox 00. It starts as 517, LDA 17, which loads the first number of the list. An LMC instruction carries its address inside it, and the machine has no register an instruction could take an address from, so there is no way to say “the mailbox after the one I just read”. Writing LDA 17, ADD 18, ADD 19 and so on works for this list and for no longer one. To sum with one loop, whatever the count says, the program loads its own first instruction as a number, adds 1 and stores it back. 517 becomes 518, which is LDA 18. Five passes write mailbox 00 five times, and the last version, LDA 22, never runs because the count reaches zero first. Real processors read an address from a register for exactly this, so a list can be walked without the program touching itself.

Most of what the machine reads is its own program 🖖

Every instruction costs one mailbox read before it does anything: the fetch. LDA, ADD and SUB read one more mailbox, STA writes one, and the branches, INP and OUT touch none. So in Multiply by adding, 6 × 7 takes 65 fetches, 30 operand reads and 16 writes, and 58.6% of all the traffic between the processor and memory is the machine fetching its instructions. Over every pair of inputs whose product is at most 999, that share stays between 57.2% and 69.2%. Program and data travel along the same path to the same memory, one at a time. John Backus named that path the von Neumann bottleneck in his 1977 Turing Award lecture.

Problem solved in full

  1. Why 2 × 99 costs 801 instructions and 99 × 2 costs 25 4 steps

    Press 2 × 99, the slow way, then change the inputs to 99, 2. Both print 198. Count the instructions each run executes, find the formula, and say what the worst order costs for a product that fits in a mailbox.

    Open this problem in the tool

    1. Before the loop, two INP and two STA: 4 instructions. The loop body runs LDA b, BRZ, SUB one, STA b, LDA total, ADD a, STA total, BRA loop: 8 instructions, once for each unit of b.

    2. When b reaches zero the loop runs only LDA b and BRZ, then LDA total, OUT and HLT finish: 5 more. So a run costs 4 + 8b + 5 = 8b + 9, and a does not appear at all.

    3. With b = 99 that is 8 × 99 + 9 = 801; with b = 2 it is 25. The results table prints 801 for the first order and 25 for the second.

    4. The largest product a mailbox holds is 999. Typed as 1, 999, the loop runs 999 times: 8,001 instructions. Typed as 999, 1, it runs once: 17.

    Answer

    8b + 9 instructions, with b the second input. The same 999 costs 8,001 instructions one way round and 17 the other, about 470 times as many, and a program that compared its inputs first and looped over the smaller would never pay more than 8 × 31 + 9 plus the comparison, since the smaller factor of a product up to 999 is at most 31.

Learning path

How a computer runs a program

References (4)