1010 程序是怎么来的
第 8 站 随时来查

术语表

每个词都给了英文原名——将来你在英文书、报错信息或者 GitHub 上遇到它,能认出来。 输入框里打几个字就能过滤(中文、英文都行)。

程序program

给机器看的一串步骤。今天的程序存在文件里;最早的程序是接线、开关和卡片上的洞。

指令instruction

机器能做的一件小事,比如“加一个数”“跳到这里”。程序就是许多条指令排成的队伍。

机器码machine code

CPU 直接执行的数字。每条指令对应一个数字编码,人读起来几乎全是天书——所以后来才需要翻译官。

位 / 字节bit / byte

位是最小的单位,只有 0 和 1;8 位组成一个字节,能表示 0 到 255 之间的一个数。第 5 站的拨开关面板,就是一位一个开关。

十六进制hexadecimal

用 0-9 和 A-F 表示数字,一位刚好对应 4 个二进制位,两个十六进制数字刚好一个字节。早期程序员用它代替又长又难数的一串 0 和 1。

汇编语言assembly language

用短名字(助记符)写机器指令的语言,一条对一条。它已经很接近机器,但人能看懂、能记住。

助记符mnemonic

给指令起的短名字,比如 LDA(把数装进累加器)、JMP(跳转)。目的是让大脑少记编号。

汇编器assembler

把汇编语言翻译成机器码的程序。它还会替你算地址、解析标签。1950 年前后出现,是最早的“翻译官”。

标签label

给某一行程序起的名字,比如 loop:。汇编器会自动算出它在哪个地址,你不用自己数格子。

编译器compiler

把一门语言写的程序整体翻译成机器码(或另一种语言的程序)。1957 年的 FORTRAN 让“机器翻译的代码够快”这件事被广泛接受。

解释器interpreter

一边读一边执行的翻译官,像同声传译。改起来方便,通常比编译慢一些。

源码source code

人写的、可以给人看和改的程序文本。它必须先被翻译(编译或解释)成机器码,机器才认得。

链接器linker

把好几段编译好的机器码拼在一起、把地址对齐的工具。自举链条里,hex2 就兼职做这件事。

自举bootstrapping

用自己(或者比自己稍旧的版本)把自己造出来的过程。编译器用自己这门语言写自己,然后自己编译自己——这就是编译器的自举。

引导程序bootstrap loader

开机时先把更大程序读进来的那一小段程序。名字来自“抓着自己的靴带把自己拎起来”的老笑话。开机叫 boot,就是因为它。

种子seed

整条自举链最底下那一小段程序。小到人能够手工检查——比如 stage0-posix 的 256 字节 hex0。

自举阶段stage0 / stage1 / stage2

自举的标准步骤:用种子编出 stage1,用 stage1 编出 stage2,再逐字节对比两者。对得上,说明编译器能正确编译自己。

元循环求值器meta-circular evaluator

用某门语言自己写的、能计算该语言程序的求值器。LISP 在 1950 年代末就做到了:语言可以用自己描述自己。

存储程序stored program

把指令和数据放进同一个内存的结构。它让换程序变成换数据,也让“程序读入程序”成为可能——自举的前提。

打孔卡punched card

纸板卡片,洞的位置表示信息。先用来控制织布机,后来用来存数据和程序。

打孔纸带paper tape

一条长长的纸带,横向一排孔表示一个字符。写错了可以剪断、用胶带贴上、重新打洞——真正物理意义上的“打补丁”。

插线板plugboard

用插线来设定机器行为的板子。ENIAC 时代的“编程”就是插线加拨开关,换程序要花好几天。

前面板front panel

计算机正面的那一排开关和灯。1975 年的 Altair 8800 就靠它开机:用开关一位位拨入引导程序。

寄存器 / 累加器 / 程序计数器register / accumulator / program counter

CPU 里的几个小格子:累加器放正在算的数,程序计数器记住下一条指令在哪。第 5 站的 CPU 状态面板就是这三样。

微码 / 译码器microcode / instruction decoder

机器码之下的一层:CPU 内部的电路(有时还有一小段微码)负责把指令数字翻译成各种控制信号。再往下就是晶体管和硅片——那是物理,不能自举,只能造。

操作系统 / 固件operating system / firmware

管理整台机器的程序。固件是刻在设备里的最小系统,开机第一段跑起来的东西。它们同样要被“读进来”,所以也在自举链上。

交叉编译cross compilation

在一种机器上,编译出给另一种机器用的程序。自举时常常要靠它:新机器上还没有编译器,就先借别的机器编一个。

可复现构建reproducible build

不同的人、不同的机器、从同一份源码出发,编译出来的结果逐字节一样。它是“这条链子里没有藏东西”的证据。

信任链chain of trust

从种子到你的程序,每一级都被上一级验证过的链条。Ken Thompson 1984 年的演讲说明:链条上任何一环被污染,都可能一代代传下去。

调试debug

找出并修掉程序里的错误(bug)。1947 年那只从 Mark II 里夹出来的飞蛾,让“bug”这个词从此有了新含义。