Computation from scratch
A modern computer can feel like magic — billions of operations a second, conjured from a slab of silicon. But there's no magic in it, only layers. Each layer does one small, comprehensible thing and hides the layer below, and the whole tower rests on something almost laughably simple: a switch that is either on or off. This page builds the tower from that switch up, one floor at a time, until a general-purpose computer stands at the top.
A little history
The machine on your desk is the culmination of a chain of ideas that runs back two centuries — long before electronics, and in two cases before anyone had built a working computer at all.
It begins with Charles Babbage, a Victorian mathematician exasperated by the error-riddled mathematical tables of his day. The story goes that, dozing over a book of logarithms, he was asked what he was dreaming about and answered, “I am thinking that all these tables might be calculated by machinery.” His Analytical Engine, designed in 1837, was the first plan for a general-purpose, programmable computer — a mechanical one of brass and steam, never finished in his lifetime, but right in almost every conceptual detail: a “store” (memory), a “mill” (the processor), and instructions fed in on punched cards.
His collaborator Ada Lovelace saw further than Babbage what the engine meant. In her 1843 notes she wrote what is widely regarded as the first computer program, and grasped that the machine might manipulate not just numbers but any symbol: it “weaves algebraic patterns just as the Jacquard loom weaves flowers and leaves.” She also pinned down its limit with a clarity still quoted in AI debates today — “The Analytical Engine has no pretensions whatever to originate anything. It can do whatever we know how to order it to perform.”
A century on, Alan Turing asked the abstract question underneath the engineering: what does it even mean to compute? His 1936 paper On Computable Numbers stripped computation down to an imaginary device — the Turing machine we'll meet at the end — and in doing so defined both the reach and the hard limits of every computer that would ever be built. Then John von Neumann, in a 1945 report on the EDVAC, set down the architecture nearly all computers still use: the stored-program idea, where instructions live in the same memory as data. (Von Neumann had a mathematician's sense of humour about the machines, too — “Anyone who attempts to generate random numbers by deterministic means is, of course, living in a state of sin.”)
Turning all this into a discipline fell to Donald Knuth, whose multi-volume The Art of Computer Programming — begun in 1962 and still being written — made the analysis of algorithms a rigorous science. Knuth is the source of much of the field's hard-won wisdom, delivered with a wink: “Premature optimization is the root of all evil,” and, on the gap between proof and practice, “Beware of bugs in the above code; I have only proved it correct, not tried it.” His definition of the whole endeavour is the one to keep in mind as you read on: “Science is what we understand well enough to explain to a computer. Art is everything else we do.” The rest of this page is an attempt to understand the machine well enough to explain it back.
The plan
With the cast assembled, here is the tower we're going to build — from the single switch at the bottom to running programs at the top. Each floor is made only from the floor beneath it.
The ground floor: a bit
Start with the smallest possible distinction: a thing that can be in one of
two states. On or off. High voltage or low. We write them 1 and
0 and call the pair a bit — a
binary digit. That's the whole vocabulary. Everything a
computer ever does is shuffling, combining and storing bits.
Two states sound like too little to build a universe on, but the trick is that you can group them. One bit has two possible values; eight bits (a byte) have 28 = 256; sixty-four bits have more combinations than there are grains of sand on Earth. Any information you like — a number, a letter, a pixel's colour, a note of music — is just an agreed-upon way of reading a pattern of bits.
Numbers are the natural first example. We count in base ten out of habit (ten fingers); a computer counts in base two. The columns aren't ones, tens and hundreds but ones, twos, fours, eights — each worth double the one to its right. Read off which columns are switched on and add them up.
1011 is eleven. Same idea as decimal — just columns that double instead of multiply by ten.Try it
Count in binary
Flip the switches. Each column is worth double the one to its right; the lit ones add up to the number below.
binary 0000 0000 = 0
Logic gates: making bits decide
Storing bits is no use unless we can act on them. Here is where Claude Shannon enters: in his 1937 master's thesis — often called the most important of the century — he showed that the Boolean algebra of true and false, worked out by George Boole back in 1854, maps exactly onto circuits of electrical switches. True is a 1, false is a 0, and a circuit can reason. The device that does the reasoning is a logic gate: a tiny circuit that takes one or two bits in and produces one bit out, following a fixed rule. Three gates are enough to start.
- AND — output 1 only if both inputs are 1. (“Both must agree.”)
- OR — output 1 if either input is 1. (“At least one.”)
- NOT — one input, flipped: 0 becomes 1, 1 becomes 0. (“The opposite.”)
Their behaviour is captured completely by a truth table: every possible input on the left, the resulting output on the right. There's nothing hidden — the table is the gate.
| A | B | A AND B | A OR B | NOT A |
|---|---|---|---|---|
| 0 | 0 | 0 | 0 | 1 |
| 0 | 1 | 0 | 1 | 1 |
| 1 | 0 | 0 | 1 | 0 |
| 1 | 1 | 1 | 1 | 0 |
Try it
A logic gate you can poke
Toggle the two inputs and pick a gate. Watch the output lamp, and see which row of the truth table you're standing on.
0 AND 0 = 0
| A | B | out |
|---|
Physically, a gate is built from transistors — voltage-controlled switches etched into silicon, a few nanometres across, of which a modern chip holds tens of billions. But you rarely need to think at that level. Once a gate behaves according to its truth table, you can treat it as a black box and stop caring what's inside — the first and most important move in all of computing.
One gate to rule them all
Here's a small miracle. You don't actually need three gates — you need one. The NAND gate (“not-and”: AND followed by NOT, so it outputs 0 only when both inputs are 1) is universal. Wire NANDs together cleverly and you can reproduce AND, OR, NOT, and from those, any logical function whatsoever. NOT is just a NAND with both inputs tied together; the rest follow.
This is the deep reason computers are buildable at all: the entire edifice of logic reduces to copies of a single, dirt-cheap part, repeated billions of times. (The course and book Nand to Tetris takes exactly this idea and builds a working computer and operating system from nothing but NAND gates — the best hands-on version of this whole page.)
From logic to arithmetic
Gates compute true and false — but true/false is the same as 1/0, so
the very same gates can do maths. Take adding two single bits. The
answer is one of: 0, 1, or “2”, and 2 in binary is 10
— a result that needs two bits, a sum and a
carry. Look closely:
- 0 + 0 = sum 0, carry 0
- 0 + 1 = sum 1, carry 0
- 1 + 0 = sum 1, carry 0
- 1 + 1 = sum 0, carry 1
The carry column is exactly an AND gate (1 only when both inputs are 1). The sum column is XOR — “exclusive or”, 1 when the inputs differ — which is itself just a handful of the basic gates. Wire those two together and you have a half adder: a circuit that adds two bits. Chain a row of these (passing each carry along to the next column, exactly as you carry the one in school arithmetic) and you can add two 64-bit numbers in a single tick. Subtraction, multiplication and the rest are built the same way, from gates.
Try it
Add two bits
Set A and B. The XOR gate gives the sum, the AND gate gives the carry — together they spell the answer in binary.
0 + 0 = 0 (binary 00)
Remembering: how a bit stays put
So far every gate is forgetful: change the inputs and the output changes at once, with no trace of what came before. A computer needs the opposite too — a way to hold a value until told otherwise. The trick is feedback: loop a gate's output back into its own input so the circuit reinforces its current state and sits there, stable, indefinitely.
The simplest version is the latch: two gates cross-wired so that the pair has two stable configurations — holding a 1 or holding a 0 — and a control line that lets you flip between them. That single remembered bit, copied a few billion times, is your computer's memory: registers (the handful of bits the processor works on right now), then fast cache, then the main RAM where your running programs and their data live.
Try it
Store a bit
Press Set to store a 1, Reset to store a 0 — then leave it alone. Unlike a plain gate, it remembers: the value stays put until you change it.
Holding 0. Press a button to change it.
The processor: a machine that follows orders
Now assemble the pieces. Take an arithmetic unit (adders and friends, the ALU — arithmetic-logic unit), a bank of registers to hold bits, and memory to hold more, and wire them to a controller. Add a clock — a signal ticking millions or billions of times a second — to keep everything in step. What you've built is a CPU, and it does exactly one thing, over and over, forever:
- Fetch the next instruction from memory.
- Decode it — work out which operation it names.
- Execute it — add these two registers, store this value, jump to there.
Then repeat, for the next instruction, billions of times a second. That's it. Every program you have ever run is this loop, grinding through a list of breathtakingly simple steps faster than you can perceive.
Software is just numbers in memory
What are those instructions made of? Bits, of course. Each one is a number, stored in memory like any other — a few bits naming the operation (“add”, “load”, “jump”), the rest naming which registers or addresses it acts on. The CPU's decode step is just a lookup from that number to the right bundle of gates. This pile of numbered operations is machine code.
The pivotal idea — the stored-program or von Neumann design — is that the instructions live in the same memory as the data they work on. A program is just data the machine happens to be reading as orders. That single decision is why a computer is general-purpose: load different numbers into memory and the very same hardware becomes a calculator, a word processor, a web browser or a game. Nothing physical changes; only the pattern of bits does.
Writing raw numbers by hand is miserable, so we climb the abstraction tower
once more. Assembly gives the operations human-readable
names (ADD, MOV). High-level languages
— C, Python, JavaScript — let you write closer to how you think,
and a compiler or interpreter translates
that back down, layer by layer, into the machine code the CPU eats. Every
program you use is this translation, all the way down to gates flipping bits.
What can be computed at all?
Step back from the engineering and a deeper question appears: is there a limit to what this loop of simple steps can do? In 1936, before any of these machines existed, Alan Turing answered it with a thought experiment now called the Turing machine — an imaginary device with an infinite paper tape, a head that reads and writes one symbol at a time, and a tiny table of rules. It is absurdly minimal, yet Turing showed it can compute anything that any step-by-step procedure can compute.
The startling claim — the Church–Turing thesis — is that this defines computation itself. Your laptop, a supercomputer, a smartphone and Turing's paper tape are all equivalent in what they can compute; they differ only in speed, memory and convenience, not in ultimate power. Any one of them can simulate any other. That is why a single idea — bits run through gates by a fetch–decode–execute loop — suffices to build a machine that runs every program there could ever be.
Turing also proved the flip side: some problems no computer can ever solve, no matter how fast or how much memory it has. The famous one is the halting problem — there is no general program that can look at any other program and reliably decide whether it will eventually stop or loop forever. Computation is staggeringly powerful, but it is not omnipotent, and we have known its outer edge since before the first computer was switched on.
The view from the top
That's the whole tower. A bit is a switch. Gates make bits decide; one gate, NAND, suffices for all of them. Wire gates into adders and you have arithmetic; loop them back on themselves and you have memory. Put arithmetic, memory and a controller under a clock and you have a CPU that fetches, decodes and executes — and because instructions are themselves just numbers in memory, the same hardware runs any program at all, up to the universal limit Turing drew in 1936.
The reason this is buildable by mortals, and the reason it's worth understanding, is the discipline of abstraction: each layer does one job, exposes a clean interface, and lets you forget everything beneath it. Nobody writing a web app thinks about transistors, and nobody designing a transistor thinks about web apps — yet it's one unbroken chain from the silicon to the screen. If you want to feel it in your hands rather than read about it, build the tower yourself: Nand to Tetris walks you from a single gate to a running game, and Charles Petzold's Code tells the same story as a book. There is no magic in here — only layers, all the way down.
Some of the figures in the diagrams on this page were compiled with the help of AI tools and may contain errors or be out of date. They are shared in good faith for general interest only — not as professional, financial, investment or purchasing advice — and should be checked against the cited primary sources before you rely on them.