新浪新闻客户端

阿波罗11号登月源码竟然开源了!仅靠4KB内存,把人类送上月球!

阿波罗11号登月源码竟然开源了!仅靠4KB内存,把人类送上月球!
2026年10月22日 07:01 新浪网 作者
avatar
资讯动态

  (来源:图灵人工智能)

转自JackCui,仅用于学术分享,如有侵权留言删除报道

  球!

  阿波罗 11 号登月飞船的完整代码,最近又小火了一把!

  其实它早就在 GitHub 上开源了,每隔几年都会被翻出来刷一次屏。

  最硬核的是,这套登月代码的运行内存小得可怜,仅有 4 KB。

  就连存放整套程序的只读存储器,也只有约 72 KB,还不如一张手机截图大。

  在如此有限的条件下,1969 年的工程师居然用汇编一行行写出了一整套飞控系统!

  真是螺蛳壳里做道场,太强了...

  仓库名叫 chrislgarry/Apollo-11,截至 2026 年,已经有 7.5 万个 Star。

  仓库链接:https://github.com/chrislgarry/Apollo-11

  于是,我把这个仓库又又又从头到尾翻了一遍,发现了很多有意思的细节。

  一、基础结构

  仓库里有两套核心程序:负责指令舱的 Comanche055(Colossus 2A),和负责“鹰号”登月舱的 Luminary099(Luminary 1A)。

  程序各约 6.5 万行(含注释),各有 90 个左右的文件,全部平铺在一个目录里,没有子文件夹。

  它本质上是从头到尾一次性汇编,不像现代项目那样拆成独立模块。

  •   底层是操作系统:EXECUTIVE(任务调度)、WAITLIST(定时任务)、中断处理、重启恢复。

  •   中间层是公共能力:INTERPRETER(虚拟机)、各种数学子程序、PINBALL_GAME_BUTTONS_AND_LIGHTS(键盘和显示)。

  •   上层是具体任务,文件直接按程序编号命名,比如 P20-P25、P40-P47、P51-P53。这些编号和宇航员在键盘上输入的程序号是一一对应的,P63 就是登月下降。

  看起来平平无奇,实则每一层的设计都非常精妙,我们逐个拆解这套代码的关键设计,你就会理解 4KB内存是怎么把人送上月球的。

  二、极限内存和储存

  4KB运行内存,72 KB 储存登月,怎么做到的?

  首先了解一下他们用的计算机,是阿波罗导航计算机。

  这台计算机重约 32 千克,功耗仅 55 瓦,主频约 2.048 MHz,是最早采用集成电路的计算机之一。

  今天的电脑和手机普遍数据按 8 位一个字节来存。

  而 AGC 一个字只有 15 位数据,外加 1 位用来查错的奇偶校验位,连“字节”这个概念都没有。

  也没有浮点数,程序员只能自己记住每个数的小数点在哪。

阿波罗机载飞行软件团队负责人玛格丽特·汉密尔顿

  所以,在这样一台机器上写登月程序,其实是非常困难的。

  我翻了专门分配内存的 ERASABLE_ASSIGNMENTS.agc 和调度程序 EXECUTIVE.agc,发现 60 年代的程序员为了把这点内存用到极致,想了两个办法:

  第一,同一块内存按阶段轮流用。

  翻到这个文件的开头可以发现,他们给大量内存位置标了“身份”。

  PRM 表示整个任务期间专用;TMP 表示可以临时借用,不同时运行的程序能共用同一块。

  光是登月舱程序,就标注了 1500 个变量。

  而且每个变量还有不同注释,写明它可以和谁共用,不能和谁共用。

  比如有的写着“可以覆盖,但要小心,只在动力下降时使用”,有的写着“不能覆盖 RONE 和 VONE”。

  第二,每个任务只给 12 个字的空间。

  登月过程中,计算机要同时做好几个任务,比如导航计算、发动机控制、姿态调整。

  但它不会临时给任务分配内存,而是提前切好 8 个“任务槽”。

  每个槽 12 个字,相当于一个极简的进程上下文。

  当前任务固定在 0 号槽,切换任务只需交换两个槽的 12 个字。

  要做向量、矩阵这类复杂运算的任务,还能再领一块 44 个字的“草稿区”。

  但一共只有 5 块,用不着的任务一个字都不多给。

  算下来,整套多任务系统只占了大约 340 个字,用六分之一的内存,就能让这台计算机实现多任务调度。

  而 72KB的储存则更硬核,是用铜线织出来的。

  那时候没有闪存芯片,大家的选择不多,只能选择磁芯绳存储器。

  这是一种纯手工制作的存储器。甚至没有通电写入这个功能,数据就是它的物理结构本身。

  代码定稿后,会被送到工厂。

  由女工们坐在放大镜前,拿着细细的铜线,对着一排排微小的磁环穿针引线,铜线从磁环中间穿过代表 1,从旁边绕过代表 0,这样储存一整套登月程序。

女工穿线

  铜绳一旦织好,就再也改不了,更没法在线打补丁。所以,代码结构必须万分严谨,不能有冗余。

  翻开 FIXED_FIXED_CONSTANT_POOL.agc,能看到代码中刻意去重的地方。

  有不少常数直接引用别处已有的位置,比如说数字 4、数字 11,都可以借用键盘显示程序里现成的存储单元。

  更有意思的是,常数的相邻关系也被利用了,负零放在零前面,两个字连起来,又能作为一个双精度常数使用。

  而最大的一笔减法,是在这台机器里被塞进了一台“虚拟机”。

  二、波兰虚拟机

  翻开 INTERPRETER.agc 文件,会发现一个更疯狂的设计。

  前面说到的阿波罗导航计算机,它天生只认识 8 条基本指令,甚至无法直接进行向量和矩阵运算,连乘除法都要借助额外的前缀指令才能完成。

  但是,我们必须要让它算出三维空间里的登月轨道,怎么办?

  在这样的硬件条件之上,60年代的程序员硬生生用汇编写出了一套解释器。

  按源码粗略估算,它只占了约 2000 个字的程序存储,却能直接处理 28 位的双精度数,以及由 6 个字组成的三维向量。

  只要在汇编里写一行 TC INTPRET,这台 15 位的机器就会切换进虚拟机模式,点乘(DOT)、叉乘(VXV)、单位化(UNIT)、矩阵乘向量(MXV),都只要一条指令。

  为了省空间,这台虚拟机也处处精打细算。

  一是一个字塞两条指令。

  虚拟机的操作码只有 7 位,最多能编 128 种运算。

  汇编器会把相邻的两条打包进同一个 15 位的字里,指令部分的空间直接省下一半。

  二是用正负号省掉地址。

  虚拟机采用不需要括号的波兰表示法,操作码字存储时被取反,是负数;内存地址则是正数。

  需要取操作数时,它会先偷看下一个字。

  是正数,就去那个地址取数;是负数,说明程序员没写地址,下一个字已经是新指令了。

  它就直接从栈里弹出上一步的结果,接着算。

  三、软重启机制

  还有一部分值得说,就是藏在 RESTART_TABLES.agc 里的软重启机制。

  1969 年 7 月 20 日,“鹰号”登月舱下降途中,发生了惊心动魄的一幕。

  离月面还有约 1 万米时,计算机突然报警。

  阿波罗登月器导航计算机专家杰克:加尔曼在发射前模拟导致着陆中止后,编写了一份备忘单,列出了警报代码。史蒂夫·贝尔斯在阿波罗11号登陆时将这份副本贴在他的控制台上。

  警报一共响了 5 次,大部分是 1202,中间还夹着一次 1201。

  OCT  1201   # NO VAC AREAS.OCT  1202   # NO CORE SETS AVAILABLE.

  1202 是“任务槽用完了”,1201 是“草稿区用完了”。

  前面说的那 8 个任务槽、5 块草稿区,在登月最关键的时刻被挤满了。

  换成很多计算机,这时候大概已经死机了。

  但阿波罗计算机很快就恢复了工作,导航和发动机控制几乎没受影响,这全部归功于程序设计的软重启机制。

  它的思路很简单:关键任务每走到一个重要步骤,都会调用一次 PHASCHNG,记下“我是第几组任务、走到了第几步”。

  这些断点都保存在内存里,重启也不会丢。

  一旦撑不住,计算机就进入报警程序 BAILOUT,记下报警代码,再跳到软重启入口 ENEMA。

  把堵住的任务一口气清空,再按断点记录,把导航、发动机控制这些关键任务重新拉起来。

  飞船就这样在一次次重启中,继续稳稳地往下降。

  四、彩蛋

  翻到注释里,你会发现这群 60 年代的程序员其实非常好玩。

  登月舱的主点火程序,文件名叫 BURN_BABY_BURN--MASTER_IGNITION_ROUTINE.agc,直译过来就是“燃烧吧宝贝燃烧,主点火程序”。

  这句话来自 60 年代的灵魂乐 DJ Magnificent Montague,他每次播到最火的新歌,都会大喊一句“Burn, baby! BURN!”,写点火程序的 Don Eyles 和 Peter Adler 就顺手借来当了名字。

  登月程序 THE_LUNAR_LANDING.agc 里的注释更逗。

  计算机提示宇航员手动转动雷达天线时,注释写着“PLEASE CRANK THE SILLY THING AROUND”(请把这破玩意儿转过来)。

  宇航员按了确认,它还要再查一遍,注释写着“SEE IF HE’S LYING”(看看他是不是在骗人)。

  确认无误后,程序跳转去点火,注释则写着“OFF TO SEE THE WIZARD...”(去见魔法师了),化用的是电影《绿野仙踪》里的经典歌名。

  有意思的是,全篇搜不到一个 TODO 或 FIXME,可能因为在登月这件事上,没人敢把问题留到以后。

  最后说说这份代码是怎么来的。

  它不是 NASA 从哪块硬盘里导出来的,而是一摞存放在 MIT 博物馆里的纸质打印稿。

  翻开任意一个文件的开头,都能看到这样一段说明:

  代码由飞行历史学者 Paul Fjeld 在博物馆逐页拍照,由博物馆的 Deborah Douglas 协助安排,再由 Virtual AGC 项目的 Ron Burkey 带着志愿者,对着照片一个字符一个字符敲回电脑,最后用汇编器 yaYUL 重新编译验证。

  登月舱程序的打印稿上,还印着当年的汇编时间:1969 年 7 月 14 日 16 点 27 分。

  也就是说,这份代码定稿时,离阿波罗 11 号发射只剩两天。

  五、结尾

  chrislgarry/Apollo-11 这个仓库,每隔几年就会被新一代程序员重新翻出来膜拜。

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

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

  今天的我们太富有了。内存不够?加内存条。

  代码跑得慢?升级显卡。

  有 Bug?先上线,等用户报错了再打补丁。

  我们在海量算力的温床里,写出了越来越臃肿、越来越脆弱的软件。

  而打开阿波罗 11 号的源码,你会看到另一个世界。

  在那个只有 4 KB 内存、连改一行代码都要剪断铜线的年代,一群平均年龄二十多岁的年轻人,在针尖上跳出了一支零失误的芭蕾。

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

特别声明:以上文章内容仅代表作者本人观点,不代表新浪网观点或立场。如有关于作品内容、版权或其它问题请于作品发表后的30日内与新浪网联系。
权利保护声明页/Notice to Right Holders

举报邮箱:jubao@vip.sina.com

Copyright © 1996-2026 SINA Corporation

All Rights Reserved 新浪公司 版权所有