A History of UNIX That ClicksEpisode 7 / Remove Every Rung of the Ladder

1969, when neither C nor B existed — Unix was written in the words just above machine code

The First Unix — an OS Written in Assembly The C, B, BCPL, and intermediate code we've descended through were all ladders for getting by without touching the machine directly. In 1969, not one rung of that ladder yet existed. Ken Thompson wrote the first Unix in the assembly language of the PDP-7 — in the thinnest words there are, just above machine code.

Tools you'll need: Episodes 5 and 6 (the language ladder) The reveal: assembly is a thin skin over machine code

At the end of Episode 6 we said "below the escape route (intermediate code), there is ultimately assembly and the machine." Now we descend there. The stage is Bell Labs in 1969. It's an era when neither C nor B (Episodes 5 and 6) yet exist in sufficient form. Ken Thompson found a small, idle computer — a PDP-7 — and, in its assembly language alone, wrote the kernel, the shell, and the editor. Without using a single rung of the high-level-language ladder — this is Unix's bare starting point.

01Why 1969, and why the PDP-7?

The immediate trigger was a great failure. Bell Labs had teamed with MIT and GE to build the ambitious OS Multics, but progress was slow, and in the late 1960s they withdrew (this Multics itself is covered in a bonus episode, at the very top of the lineage). With time on his hands, Thompson tried to port the space-travel game Space Travel, which he'd built on Multics, to the idle PDP-7 — and along the way he made a file system, made processes, and before he knew it, it had become an OS. At first it had no official budget from Bell Labs either.

Bridging voice — the name means "castrated Multics" In 1970, a colleague, Brian Kernighan, gave this little OS the name UNICS. A pun on the giant Multics (Multiplexed…), it was Uniplexed…, pronounced "you-niks" (eunuchs). A small, terse dig at the large, ambitious Multics. The Unix design philosophy that "small is right" was there from the very name. Later the spelling became UNIX.

02Everything was assembly

On the PDP-7, Thompson (and later Ritchie too) wrote one thing after another in assembly language — the kernel, the command interpreter (shell), the editor, the assembler itself, and a set of small utilities. Here were born the concepts that are still the spine of Unix/Linux today: the hierarchical file system, processes, and device files. All of it in the words just above machine code.

03What is assembly? A thin skin over machine code

Let's make clear what "written in assembly" means. What the machine actually executes is machine code — just a sequence of numbers (opcodes and addresses), which humans can barely read. Assembly language is simply that, with human-readable names attached to the numbers. Instructions get mnemonics like lac (load) and add (add); addresses get labels like start: and n:. The two correspond almost one-to-one.

And the program that mechanically replaces those names with numbers is the assembler. In the figure below, watch line by line as assembly is translated into machine code. Look only at the numbers afterward, and the meaning becomes utterly unreadable — that is "the world the machine sees."

Figure 1: Assembly. The assembler takes human-readable assembly (left) and, replacing mnemonic→opcode and label→address, turns it into machine code (right, octal). Look only at the right and the meaning is no longer readable.
The assembly on the left is human-readable. With "▶ Assemble," it's translated line by line into machine code (right).
This episode's crux — the ladder nearly runs out here

C, B, BCPL, and intermediate code were all ladders for "writing in an easier language and having it translated." Assembly is the bottom rung of that ladder. It just sticks names on the machine's very instructions; there's almost no more room to escape to "some easier language." Below here is the bare machine — machine code as numbers, and the physics that runs it.

◇ ◇ ◇

04Here too, a chicken and egg — what built the assembler?

The ladder may run out, but the chicken and egg doesn't vanish. To turn assembly into machine code, you need an assembler. So what assembled that first assembler? Moreover, PDP-7 Unix included the assembler itself, written in assembly. Eventually Unix could reassemble itself with its own assembler (self-supporting) — the smallest self-hosting, at the assembly layer. But "the very first one" can't be made inside that ring (Episode 0). In the figure below, see that ring, and the question that remains outside it.

Figure 2: The lowest layer of PDP-7 Unix. The assembler (as) assembles the kernel, the shell, and itself (self-hosting at the assembly layer). But "what assembled the first as" lies outside this ring — on to Episode 8.
PDP-7 Unix is written entirely in assembly. The central as (assembler) assembles the other parts and itself into machine code.

05What lies ahead — the PDP-11, then C (closing one loop)

PDP-7 Unix eventually moved to the PDP-11 in 1970 (again in assembly), and, as we saw in Episode 5, was rewritten in C in 1972–73. Here one loop of the series closes — Episode 5's "C grew out of B" and this Episode 7's "the first Unix was assembly" tie together at the same knot, the 1973 move to C. We are now heading even further below that knot, toward the origin of the very first assembler.

The honest line — the instructions in the figure are a "plausible" made-up example

(1) The instructions and octal codes in Figure 1 are a simplified example to convey the feel of the correspondence between assembly and machine code; they are not a strict reproduction of the actual PDP-7 instruction table (the PDP-7 was a small 18-bit-word machine, and mnemonics like lac/dac/tad/jmp are real). (2) "Assembly→machine code is almost one-to-one" is basically correct, but there are exceptions such as pseudo-instructions, macros, and multi-word instructions.

(3) The story of Unix's birth (Multics withdrawal → Space Travel → file system → OS) is a famous, oft-retold arc, but the details differ by source. (4) "The ladder runs out here" is a figure of speech; in reality there are layers even below assembly, inside the machine, such as microcode (covered in Episode 10). (5) Early on, the assembly itself was done on a different machine — that story is exactly Episode 8.

Practice problems (solvable with just this episode)
  1. The first Unix (1969) was written on which machine, in what language?
    Show the answer
    The (PDP-7's) assembly language, on the PDP-7. Neither C nor B was yet sufficiently available, so it was written in the words just above machine code.
  2. State the difference between assembly language and an assembler in one sentence.
    Show the answer
    Assembly language is a notation that attaches human-readable names (mnemonics and labels) to machine code (numbers); an assembler is a program that mechanically replaces those names with numbers to produce machine code.
  3. What is the decisive difference between assembly and C/B/BCPL/intermediate code?
    Show the answer
    The latter are "ladders for writing in an easier language and having it translated." Assembly just sticks names on the machine's very instructions, with almost no room to escape to an easier language = the bottom rung of the ladder.
  4. What new "chicken and egg" remains from this episode?
    Show the answer
    You need an assembler to turn assembly into machine code, but what assembled that first assembler? The question of the origin of the very first one, lying outside the self-hosting ring (Episode 8).

SummaryRemove every rung, and a thin skin over machine code remains

In 1969, at a Bell Labs that had withdrawn from Multics, Thompson, while porting Space Travel to an idle PDP-7, made a file system along the way, and it became the first Unix (named UNICS by Kernighan). Neither C nor B yet existed, and the kernel, shell, editor, assembler, and utilities were all written in the assembly language of the PDP-7. Here the spine of Unix — the hierarchical file system, processes — was born.

Assembly is the thinnest skin, just human-readable names (mnemonics and labels) stuck onto machine code (numbers unreadable to humans). What replaces them with numbers is the assembler. The "easy-mode ladders" of C, B, BCPL, and intermediate code have here descended all the way to the bottom rung. But the chicken and egg remains — what assembled the first assembler? PDP-7 Unix includes the assembler itself and self-hosts at the assembly layer, but the very first one lies outside the ring. Next time, the answer — the cross approach that assembled on a different machine and carried it on paper tape.

This document is Episode 7 of the series "A History of UNIX That Clicks." Historical notes: In the late 1960s, Bell Labs withdrew from Multics development with MIT and GE. Ken Thompson moved the game Space Travel, which he had made on Multics, to the PDP-7 via GECOS (GE-635), and in the process implemented a file system and more, which became the first Unix. The first Unix was written in the assembly language of the PDP-7 (kernel, shell, editor, assembler, various utilities), and concepts such as the hierarchical file system, processes, device files, and the command interpreter were born. The name UNICS was coined in 1970 by Brian Kernighan as a pun on Multics (Uniplexed…, later UNIX). Unix was rewritten to the PDP-11 in 1970 and to C in 1972–73 (Episode 5). The instruction sequence and octal codes in Figure 1 are a simplified example to explain the correspondence between assembly and machine code, not a strict reproduction of the PDP-7 instruction table (mnemonics like lac/dac/tad/jmp are real). The correspondence between assembly and machine code is roughly one-to-one, but there are exceptions such as pseudo-instructions and macros. The PDP-7 is a small 18-bit-word machine. — To print, use your browser's "Print" and "Save as PDF" (in the printed version, the figure controls and answers are frozen / hidden).

Print / save as PDF: ⌘+P (Ctrl+P on Windows). On screen, use "▶ Assemble" in Figure 1 to trace the assembly→machine code translation, and Figure 2 to follow the self-hosting of PDP-7 Unix's lowest layer. "Show the answer" reveals each solution.