AX 爱鲜报

综合 / 后端 · 2026-10-22 08:54 · 2 阅读 · 0 赞

仅4KB内存就把人类送上月球:阿波罗11号源码的工程奇迹

阿波罗11号导航计算机仅有4KB内存,其完整源码在GitHub上公开。本文回顾了这套代码如何被志愿者从纸质清单中抢救出来,并剖析了其精妙的虚拟机设计、零TODO的严谨态度,以及1202报警背后的优先级调度智慧。

把尼尔·阿姆斯特朗和巴兹·奥尔德林送上月球的计算机,运行内存只有 4 KB。

4 KB 是什么概念?今天你用手机随手发一张微信表情包,体积都是它的上百倍。随便打开一个空白的现代网页,吃掉的内存就能装下几十万台登月计算机。但就是在这样一个连一张低清自拍都塞不下的数字螺蛳壳里,1969 年的工程师硬生生写出了人类历史上最伟大的飞控系统,带着两舱宇航员跨越 38 万公里,在月球静海精准着陆。

让人惊叹的是:这套传奇的阿波罗 11 号完整源代码,今天任何人都能在 GitHub 上直接点开阅读,甚至在自己的电脑上重新编译运行。

近日,工程类账号 World of Engineering(@engineers_feed)发了一条只有一句话的短帖:“阿波罗 11 号的源码可以在 GitHub 上找到。”

起始帖:World of Engineering 宣布阿波罗 11 号源码可在 GitHub 获取

▲ World of Engineering 的一句话短帖,再次掀起全球开发者的“技术考古”狂欢

评论区里,有人立刻晒出了让人倒吸一口凉气的硬件规格,也有人半开玩笑地感叹:“现在,任何人都能自己搞个航天计划了。”

引用转发补充 AGC 内存规格与公开意义

▲ 网友迅速补上关键参数:仅约 4 KB 可读写内存与 72 KB 只读存储,指令舱与登月舱代码全部公开

当你点进这个拥有 7.5 万颗星标(Star) 的仓库,一行行翻看五十多年前的汇编指令时,很难把它当成一份枯燥的古董文档。那里有摇滚电台的口头禅、有拉丁文的警告、有用铜线一针一线“织”出来的二进制,还有一个在 15 位芯片里手搓出来的“虚拟机”奇迹。

01 一页页敲出来的“针线活”:代码一旦写错,就得拿剪刀剪

很多人第一眼看到这个仓库(chrislgarry/Apollo-11),会以为是 NASA 刚刚大发慈悲搞了一次“官方开源”。其实,这是一场跨越几十年的数字抢救。

GitHub 仓库首页:chrislgarry/Apollo-11

▲ 由 Chris Garry 维护的 Apollo-11 仓库首页,标注为 100% 汇编语言,属于公共领域(Public domain)

仓库里躺着两套核心程序:一套是负责指令舱(Colossus 2A)的 Comanche055,另一套是负责“鹰号”登月舱(Luminary 1A)的 Luminary099。1969 年根本没有 Git,NASA 也从未从某个老硬盘里直接导出过它们。当年,这些代码是一摞摞堆在麻省理工学院博物馆(MIT Museum)里的纸质打印清单。

为了不让人类首次登月的数字大脑烂在故纸堆里,飞行历史学者 Paul Fjeld 在博物馆里将上千页发黄的硬拷贝一页页拍照扫描;随后,Virtual AGC(虚拟阿波罗制导计算机) 项目的维护者 Ron Burkey 带着全球志愿者,对着扫描件用肉眼校对、一个字符一个字符地敲进现代电脑,并用自制的汇编器 yaYUL 重新跑通验证。

回复指出源码来自 MIT 博物馆硬拷贝誊录

▲ 网友 Geoff 在评论区揭秘:这份仓库并非 NASA 一键导出,全靠志愿者在 MIT 博物馆对着纸质清单生生敲出来

为什么当年的工程师要把纸质清单审得像圣经一样严?因为阿波罗导航计算机(AGC)里的程序,是真的用针线“织”出来的。

打开维基百科的 AGC 档案,你会看到一台重约 32 千克、功耗仅 55 瓦(还没一根家用白炽灯亮)、主频约 2.048 MHz 的机器。它的字长非常奇特:15 位数据加 1 位奇偶校验。可擦写磁芯内存只有 2,048 字(约 4 KB),用来存程序的只读存储器也只有 36,864 字(约 72 KB)。

维基百科 Apollo Guidance Computer 条目首页

▲ 阿波罗导航计算机(AGC)与宇航员操作的数码管键盘界面(DSKY)

那时候没有闪存芯片,程序要怎么写进只读存储器?答案是磁芯绳存储器(Core Rope Memory)。

代码一旦定稿,就会被送到雷神公司(Raytheon)的工厂。女工们坐在放大镜前,手里拿着细细的铜线,对着一排排微小的磁环穿针引线:铜线穿过磁环代表 1,绕过磁环代表 0。 整套登月程序,最终变成了一捆密密麻麻、手工编织的物理铜绳。当时的工程师带着敬意与幽默,把这种存储器戏称为 “LOL Memory”(Little Old Lady memory,老太太存储器)。

如此特殊的工艺,决定了阿波罗的代码根本无法在线热更新或事后打补丁。只要一行代码有 Bug,女工们几个月的穿线就彻底报废。软件在变成火箭上的动作之前,先变成了无法轻易篡改的物理铁律。

02 满屏摇滚黑话,却找不到一个“TODO”

你可能会以为,背负着几条人命和冷战国运的代码,读起来一定死气沉沉。但只要点开源码目录,60 年代 MIT 天才程序员的灵魂就会扑面而来。

整个仓库被截图转发最多的文件,藏在登月舱目录里,名字叫:BURN_BABY_BURN--MASTER_IGNITION_ROUTINE.agc(《燃烧吧宝贝燃烧,主点火例程》)。

GitHub 上的 BURN_BABY_BURN 主点火例程源文件

▲ 登月舱主点火例程源文件,把 60 年代电台摇滚口头禅直接写进了文件名

负责编写这段代码的年轻程序员 Don Eyles 后来回忆,当时正值 1960 年代末,洛杉矶灵魂乐电台 DJ “Magnificent Montague” 每次播到高潮就会大喊一句口头禅:“Burn, baby! BURN!”(燃烧吧,宝贝!)。负责点燃登月舱火箭发动机的程序员们一拍大腿,直接把这句街头流行语变成了官方主点火例程的名字。

再往文件里看,幽默感和敬畏感交织在一起:文件头印着拉丁文格言 HONI SOIT QUI MAL Y PENSE(心怀恶念者蒙羞),紧接着在关键数据表旁边又用拉丁文写下严厉警告:NOLI SE TANGERE(切勿触碰!)。而负责处理宇航员按键和仪表盘闪烁的巨大状态机文件,干脆被起名为 PINBALL_GAME_BUTTONS_AND_LIGHTS.agc(《弹球游戏的按钮与灯光》),在程序员眼里,跟宇宙飞船对话,就像在打一台史上最刺激的弹球机。

可一旦涉及到责任与质量,这群“嬉皮士程序员”比谁都严肃。

翻开指令舱的 CONTRACT_AND_APPROVALS.agc(合同与批准页),你会看到一段直接被敲进源代码里的军令状。在“提交人”一栏,赫然写着:Margaret H. Hamilton(玛格丽特·汉密尔顿),1969 年 3 月 28 日。正是她带领的 MIT 团队,在那个连“软件”都还被视为硬件附庸的年代,亲手创造并推广了 “Software Engineering”(软件工程) 这个词。把自己的名字和审批日期直接编译进飞船的只读内存里,这就是当年工程师的担当。

CONTRACT_AND_APPROVALS.agc 中的汉密尔顿提交与批准栏

▲ 直接写在源代码里的审批签名页,提交人为玛格丽特·汉密尔顿(Margaret H. Hamilton)

更有好事的现代程序员,把整个阿波罗 11 号仓库拉到本地,用搜索工具全局检索了现代代码里最常见的两个词:TODO(待办) 和 FIXME(待修复)。结果是:0 个

回复称源码中未见 TODO 或 FIXME

▲ 网友全局搜索后的震撼发现:数万行登月代码里,没有任何一个“以后再改”的 TODO 或 FIXME

平时程序员写代码,动不动就留下一句 // TODO: 这里逻辑有点乱,以后再优化。但在 1969 年的登月舱里,没有“以后”。每一行指令在织进铜线之前,都已经过了千百次推演。

03 只有 8 条基本指令?那就手搓一台“波兰虚拟机”!

如果只看表面的文件名,那还只是看个热闹。这套源码最让现代顶尖架构师跪服的,是它在 INTERPRETER.agc 里展现的极限微操。

不妨算一笔账:阿波罗计算机的一个“字”只有 15 个数据位。在这 15 位里,后 12 位要留给内存寻址,留给操作码(Opcode,也就是告诉 CPU 要干什么)的空间,只有区区 3 位!

学过初中数学都知道,

2^3 = 8

也就是说,这台计算机天生只能识别 8 条基本指令(加、存、跳、取反等)。它甚至采用“1 的补码”来表示负数,导致机器里同时存在两个零:正零(八进制 00000)和负零(八进制 77777)!

只有 8 条指令、15 位精度,连乘法和除法都没地方放,怎么算三维空间里的登月轨道、雷达滤波和姿态旋转矩阵?MIT 的工程师祭出了两招神级操作:

第一招,给 CPU 装个“脚踏板”:EXTEND 指令。 就像一架只有 8 个琴键的玩具钢琴,根本弹不出交响乐。工程师专门设计了一条叫 EXTEND 的前缀指令。平时按琴键是普通加减法;一旦先踩一下 EXTEND 这个“踏板”,紧接着的下一条指令就会瞬间切换到“第二张指令表”,原本普通的按键立刻变成硬件乘法(MP)、除法(DV)和双精度操作。

第二招,在 15 位机器里硬塞进一台“高级虚拟机”! 即便有了乘法,用底层汇编去写 3×3 矩阵乘以三维向量,代码也会长到把 72 KB 的铜绳撑爆。于是,Charles Muntz 和 Hugh Blair-Smith 等人做了一件疯狂的事:他们仅仅花了约 1,000 个字的常驻内存,在底层硬件之上,手搓出了一套支持 28 位双精度和 6 字三维向量的字节码解释器(INTERPRETER.agc)!

只要在汇编里写下一行 TC INTPRET,这台寒酸的 15 位机器就会瞬间变身成一台高级数学计算机,直接支持向量点乘(DOT)、叉乘(VXV)、单位化(UNIT)和矩阵相乘(MXV)。

为了省内存,这个解释器把“抠门”发挥到了艺术的境界:

  • 一个字塞两条指令:解释器指令只用 7 位编码(支持 128 种高级运算)。汇编器会把连续的两条 7 位指令打包塞进同一个 15 位的内存字里,空间直接省一半!
  • 用正负号玩出“自动弹栈”:解释器采用了不需要写括号的波兰表示法(Polish Notation)。在设计编码时,工程师故意把所有“指令字”的最高位都设成负数特征,而把所有“内存地址”都保持为正数。当解释器做乘法需要取数字时,它会先偷看下一格内存:如果是正数,就乖乖去那个地址拿数据;如果程序员偷懒没写地址,下一格内存就会直接撞上下一条指令(负数)!解释器一看到负数,瞬间秒懂:“哦!程序员没给地址,那我直接从工作栈(Pushdown Stack)里把上一步算出来的结果弹出来接着算!”

最绝的是这台虚拟机的总入口标签名字。在源码第 1003 页,所有解释器指令执行完后跳回的主分发入口,被命名为 DANZIG(但泽)。

几十年后,后辈程序员百思不得其解,跑去问当年写下这段代码的元老 Hugh Blair-Smith。老先生哈哈大笑,揭开了这个跨越半个世纪的极客冷笑话:

“因为我们的虚拟机用的是波兰表示法(Polish Notation)啊!在我小时候(二战前)的世界地图上,通往波兰的海上大门,就是波罗的海港口城市,但泽(Danzig,今波兰格但斯克)。既然这行代码是进入‘波兰表示法’的大门(Gateway to Polish),我就顺手给它起名叫 DANZIG 喽!”

在生死攸关的登月代码核心区,藏着一个地理与数学的双关语。这就是顶级工程师的浪漫。

04 着陆前 3 分钟的死神考验:1202 报警

如果说前面的架构是纸面上的精妙,那么 1969 年 7 月 20 日,这套代码迎来了人类科技史上最惊心动魄的实战大考。

当时,“鹰号”登月舱正在向月球表面急速下降,距离月面只剩几千英尺。突然,宇航员面前的报警灯剧烈闪烁,蜂鸣器响起,数码管跳出了一个冰冷的八进制代码:1202。紧接着又是 1201。

阿姆斯特朗立刻向休斯敦呼叫:“程序报警(Program alarm)……是个 1202。”

ALARM_AND_ABORT.agc 报警例程开头

▲ 仓库中的 ALARM_AND_ABORT.agc 文件,专门处理非中止类报警并将错误码写入寄存器

那几秒钟里,全世界捏了一把汗。如果是今天的普通电脑或者车载大屏,遇到 CPU 和内存任务被彻底塞满的情况,结果往往只有一个:卡死、蓝屏、全盘崩溃。

为什么会报警?因为登月舱在下降时,本来只需要打开着陆雷达;但用于返回对接的“交会雷达”开关被放在了错误的位置上,源源不断地向计算机发送虚假脉冲,疯狂窃取 CPU 周期,终于把本来就只有 4 KB 的工作内存槽(Core Sets / VAC areas)彻底挤爆了!

但阿波罗计算机没有死机。

Make Tech Easier 文章解释 4KB 级计算机如何完成着陆

▲ 科技媒体长文复盘:一台内存不如电子贺卡的计算机,如何靠精妙的优先级调度化解 1202 危机

在玛格丽特·汉密尔顿团队和调度器设计者 J. Halcombe Laning 编写的操作系统里,早就算到了“万一算力不够用怎么办”。当 1202 报警触发时,ALARM_AND_ABORT.agc 点亮警报灯通知宇航员,同时底层执行体(Executive)立刻启动毫秒级软重启。

它像一个极度冷静的战地外科医生:面对漫天飞来的杂务表单,它一把将所有低优先级的雷达废数据全部扫进垃圾桶,死死保住优先级最高的发动机推力控制与姿态稳定任务!

地面控制中心 26 岁的制导军官 Steve Bales 知道这套软件的脾气,只要 1202 未曾连续狂闪,就说明计算机正在一边自动扔垃圾、一边稳稳控制飞船。他在短短几秒内抓起麦克风,喊出了那句载入史册的:“Go!”(继续着陆!)

几分钟后,“鹰号”稳稳落在月球静海。

05 写在最后:算力泛滥的时代,我们为什么还在怀念 4KB?

算上 2019 年登月五十周年的刷屏,再到如今 2026 年的又一次全网翻红,chrislgarry/Apollo-11 这个仓库每隔几年就会被新一代程序员重新捧上热搜。

为什么在拥有千亿参数大模型、几十 GB 内存手机的今天,我们看着五十多年前的八进制汇编,依然会起一身鸡皮疙瘩?

因为极度的匮乏,逼出了极致的优雅。

今天的我们太富有了。内存不够?加内存条。代码跑得慢?升级显卡。有 Bug?先上线,等用户报错了再打补丁。我们在海量算力的温床里,写出了越来越臃肿、越来越脆弱的软件。

而打开阿波罗 11 号的源码,你会看到另一个世界:在那个只有 4 KB 内存、连改一行代码都要剪断铜线的年代,一群平均年龄二十多岁的年轻人,用双操作符打包、用正负号判别栈顶、用抢占式优先级重启,在针尖上跳出了一支零失误的芭蕾。

在这堆发黄的汇编指令背后,是人类在算力荒原上,仅凭智慧、纪律与勇气,向星辰大海递出的第一封信。

标签 GitHub 汇编 虚拟机 软件工程 历史

评论

登录后才可评论

0 条评论

  • 暂无评论,来写第一条吧。