第二章:禁忌的艺术,汇编与内存的黑暗魔法

旅行者,欢迎来到第二章。

请坐稳。在上一章,我们礼节性地回顾了你的舒适区——行号和GOTO。我们甚至还(假惺惺地)称赞了它们。那就像是在你的“复活”派对上,为你准备的开胃小点心。

现在,我们要上硬菜了。我们要谈谈你提到的那个词:“汇编”。

我们知道,当这个词在你(可能刚解冻)的大脑中回响时,会唤起一种混杂着恐惧、敬畏,或许还有一点点创伤后应激障碍(PTSD)的复杂情感。在你的时代,BASIC(全称:初学者通用符号指令代码)是光明、友好、充满人性的世界 1。它是客厅里的语言。

而汇编(Assembly),那是地下室里的语言。

它是黑暗的、令人望而生畏的 2、神秘的,并且被公认为“真正的程序员”才敢触碰的“黑暗艺术” 3。BASIC程序员用 PRINT 来打招呼;汇编程序员用 XOR A,A 来清空寄存器。你们简直来自两个星球。

但你和我都知道一个秘密,不是吗?你,作为一个严肃的BASIC程序员,不可能永远只停留在光明面。你内心深处那股对速度的原始渴求,迟早会把你拖入深渊。

对速度的原始渴求(以及BASIC如何把我们逼疯)

让我们来重演那个你职业生涯(或许是童年)中的决定性时刻。

你,一个冉冉升起的编程新星,终于说服了父母,他们为你买来了那台“神奇的 wonder computer”——可能是一台Commodore 64(C64),也可能是一台Apple II 4。你自豪地把它接到家里那台13英寸的彩色电视上。你自学了BASIC 4,你掌握了 PRINTINPUTIF/THEN 5。你,是一名程序员了!

然后,你决定写点“真正”的程序。也许是个游戏 6,或者至少是个“酷炫”的屏幕效果。你决定写一个简单的循环,把C64屏幕上(从地址1024到1984)的所有字符反转过来。

作为一个聪明的BASIC程序员,你写下了如下代码:

10 FOR I = 1024 TO 1984 : POKE I,PEEK(I) OR 128 : NEXT

你深吸一口气,怀着对奇迹的期待,敲下了回车键。

然后……奇迹发生了。第一行的第一个字符反转了。接着是第二个。第三个……

你看着屏幕。第一行慢悠悠地完成了反转。然后光标移到了第二行。第二行也开始慢悠悠地反转。然后是第三行。

你(现在的你)可能已经不记得那种“慢”了。让我来提醒你:那个“简单”的FOR循环,在C64上,跑完整个屏幕,需要整整十秒钟 7

在这十秒钟的地质纪元里,一个80年代程序员的内心会经历一场风暴 8

  • (第1秒):“酷!”
  • (第3秒):“……嗯,它在工作。”
  • (第5秒):“它是不是死机了?” 8
  • (第7秒):“不,它还在动。老天爷,它还在第一屏的中间。”
  • (第9秒):“我受不了了。我发誓我妈的吸尘器干扰了磁带机。别过来,妈!” 8
  • (第10秒):“完成了。太好了。这破玩意儿根本没法用。”

然后,就在你陷入绝望的那个下午,你邻居家那个“真正的”黑客(他甚至还有胡子!)过来看了一眼。他轻蔑地“哼”了一声,然后花了几分钟,鼓捣出了一堆你看不懂的、像是外星语的东西。

他让你运行他的程序。你按下回车。

“唰!”

在一眨眼都不到的时间里,整个屏幕,从第一个字符到最后一个字符,瞬间反转了 7

你目瞪口呆。

你刚刚亲眼目睹的,就是BASIC和“机器语言”之间的深渊。这个深渊,决定了你写的是“学校作业”,还是能登上杂志封面的“商业游戏” 6。你意识到,你的BASIC就像一辆友好的儿童三轮车,而你邻居开的,是一架F-16战斗机。

就在那一刻,你知道你别无选择。你必须学会他的黑暗魔法。你必须堕入“汇编”的深渊。

讽刺的是,BASIC那令人绝望的“慢”,恰恰是它最伟大的教育功绩。BASIC作为一种“入门毒品”是如此成功 9:它用易用性吸引了数百万像你一样的爱好者上钩 4,然后,又用其可笑的性能,强迫你们当中最好奇、最执着的那一批人,去探索更底层、更强大的汇编语言。

BASIC的“不胜任”,催生了一整代“意外的”底层系统专家 10

与“铁”对话:揭秘“汇编”这个大妖怪

好了,旅行者,让我们来给你的PTSD做做脱敏治疗。一提到“汇编”(Assembly,简称ASM),你可能会立刻想到那些印在劣质纸张上的、密密麻麻的十六进制数字,或者是那些声称“从入门到放弃”的教程 2

首先,我们必须做一个关键的澄清,正如大纲(1)所指出的:

  1. 机器码(Machine Code):这是你的CPU(中央处理器)唯一能懂的语言。它就是纯粹的0和1的二进制流(或者我们为了方便读,写成十六进制,比如 $A9 $01 $8D $20 $D0)。这是真正的“黑暗魔法”。
  2. 汇编语言(Assembly Language):这是人类(我们用这个词非常宽松)为了读懂和写出机器码,而发明的“助记符”(Mnemonics)。

“助记符”只是一个价值50美刀的词,用来形容“简短的、听起来像是CPU在发脾气的动词”。汇编语言和机器码之间存在着(几乎)1:1的对应关系 1

你不需要一个“编译器”来解释你的意图。你只需要一个“汇编器”(Assembler)来把你的“助记符”翻译成对应的机器码。LDA #$01 就是 $A9 $01。不多也不少。

在你的时代,你基本上只关心两个“教派”的CPU:MOS 6502和Zilog Z80 3

教派A:6502 巫师(C64、Apple II、Atari、NES)

如果你是这个教派的,恭喜你,你的CPU非常……“节俭” 3。它几乎没有“寄存器”(Registers,CPU内部的临时小抽屉)。你基本上只有一个你真正关心的“主抽屉”,它有一个非常华丽的名字:“累加器”(Accumulator,简称A)。

你的所有魔法都围绕这个“累加器”展开。它就像是你厨房里唯一的那个好杯子 11。你要做任何事,都得先用这个杯子。

你的核心咒语只有两个 2

  • 咒语 1: LDA (LoaD Accumulator)
    • 人类翻译:“把某个东西(一个数字,或者内存里某个地址的东西)装进我这个‘累加器’(咱的杯子)里。”
    • 示例:LDA #$01 的意思就是:“把数字‘1’这个原料,放进‘咱的杯子’里。”
  • 咒语 2: STA (STore Accumulator)
    • 人类翻译:“把我‘累加器’(咱的杯子)里现在的东西,原封不动地倒进内存地址为$XXXX的那个储物格里。”
    • 示例:STA $0200 的意思就是:“把‘咱的杯子’里的东西,倒进屏幕左上角那个像素对应的储物格里。” 11

教派B:Z80 大法师(ZX Spectrum、TRS-80、Amstrad)

如果你是Z80教派的,那你简直生活在奢华之中 12。你的CPU太“富裕”了!你不仅有一个“累加器”(A),你还有一大堆其他的“杯子”和“杯架”!它们还有很酷的名字,比如BC、DE、HL 13

你的咒语听起来也更霸气:

  • 咒语: LD (LoaD)
    • 人类翻译:“装载!” Z80就是这么言简意赅。它不关心你是不是“累加器”。
    • 示例:LD BC, 25 的意思就是:“把25这个数字,放进‘BC’这个双联杯架里。” 13LD A, (HL) 的意思则是:“把HL杯架指向的那个内存地址里的东西,给我装进A杯子里!”

通用的终极魔法

当然,无论哪个教派,都共享着一些最强大的咒语。比如 JSR (Jump to SubRoutine,6502的叫法) 11CALL (Z80的叫法) 12

  • 咒语: JSR / CALL
    • 人类翻译:这是真正的魔法。它告诉CPU:“你现在别干手头的活儿了,跳过去执行那边的另一段咒语。但是!你TMD可得记住你是从哪儿跳过去的(专业术语叫‘把返回地址压栈’),一会儿你还得跳回来!” 11

当你开始写汇编时,你就不再是那个用 PRINT "HELLO" 的文明人了。你成了一个在内存里手动搬运字节的野蛮人。你不再是请求,你是在指挥。你获得了对硬件的绝对控制权。

这种硬件的“贫穷”和“极简主义”,现在回想起来,其实是完美的“教学工具”。现代CPU(x86-64)拥有海量的寄存器和上千条复杂指令,其汇编语言对新手来说是无法理解的天书。

而80年代的6502,用它那小得可怜的指令集 11,迫使你必须将一个复杂的问题(比如“让马里奥跳起来”)拆解成最微小的、原子化的步骤(“把马里奥的Y坐标加载到‘杯子’里” -> “给‘杯子’里的数减1” -> “把‘杯子’里的新Y坐标存回内存”)。

硬件的“贫困”无意中成为了“计算思维”的大师课。它教会了你一种现代程序员(被GB级的内存、智能编译器和垃圾回收器惯坏了)永远不必学习的、关于“精打细算”的禅宗艺术。你,旅行者,是这门失传艺术的大师。

神圣三位一体:PEEK、POKE 与 CALL的巫术

好了,你现在知道汇编很快,也知道汇编很吓人。那么问题来了:在80年代,你是如何在“友好”的BASIC和“吓人”的汇编之间切换的呢?

你总不能为了写个游戏,就扔掉BASIC,从头开始用汇编吧?(虽然最硬核的那帮人的确这么干了 6)。

不。你不需要。因为BASIC的设计者(或许是无意中)给你留下了三个“后门”。三个连接光明与黑暗的“圣桥”。

这三个命令,就是你在80年代的“集成开发环境”(IDE)。它们是:PEEKPOKECALL(或SYS1

1. PEEK(地址): “窥视”咒

  • 功能PEEK(窥视)允许你读取计算机内存中任何一个特定地址上存储的那个字节(0-255)的值 4
  • 感受:这是你吃下的“红色药丸”。这是你第一次意识到计算机不是一个“黑盒”。你的BASIC程序就像是漂浮在内存海洋上的一个小木筏,而PEEK给了你一副潜水镜,让你能“窥视”水面下的一切。
  • 你的内心戏:“等一下……你的意思是……我可以……直接看它大脑里的任何一个角落?” 4
  • 实际应用:在TRS-80上,你再也不用INPUT$来等待用户输入了(那太慢了!)。你想知道用户是否按下了“向上”键?你直接 PRINT PEEK(14400) 14。如果屏幕上显示8,你就知道“上”键被按下了。你绕过了BASIC,直接“读取”了硬件的键盘映射内存。

2. POKE 地址, 数值: “戳刺”或“附身”咒

  • 功能:如果说PEEK是“读”,那么POKE(戳刺)就是“写”。它允许你强行将一个数值(0-255)塞进一个特定的内存地址 4
  • 感受:这,就是力量。这,就是危险 4
  • PEEK是把你变成“观察者”。POKE是把你变成“神”。
  • 你不再需要使用BASIC那套繁琐的、官方的COLOR命令。你(通过杂志)得知了C64的“边框颜色”被储存在地址53280 15
  • 你不再是请求电脑改变颜色。你是命令它改变。
  • 你输入:POKE 53280, 2
  • “砰!” 屏幕边框立刻变成了红色 15
  • 你输入:POKE 53281, 1
  • “砰!” 屏幕背景立刻变成了白色 15
  • 你,成了一名巫师。

为了唤醒你沉睡的记忆,这里有一份为你准备的、从80年代的禁忌咒语书中(15)精心挑选的POKE(及近亲)咒语列表:

咒语 (POKE / CALL 命令) 平台 魔法效果 (它到底干了啥?)
POKE 53280, 2 Commodore 64 [改变边框颜色] "让屏幕边框变成红色!" 15
POKE 53281, 1 Commodore 64 [改变背景颜色] "让屏幕背景变成白色!" 15
POKE 646, 5 Commodore 64 [改变文字颜色] "接下来的打印(PRINT)都是绿色!" 15
POKE 1024, 1 Commodore 64 [写入屏幕] "在屏幕左上角强行显示一个 'A'。" 7
POKE 54296,15:POKE 54296,0 Commodore 64 [制造声音] "发出‘咔哒’一声。" (通过快速开关SID声音芯片的主音量) 16
POKE 649, 0 Commodore 64 [终极恶作剧] "让整个键盘失灵!" (直到你POKE 649,10) 16
POKE 775, 171 Commodore 64 [自毁程序] "如果有人敢输LIST命令,电脑立刻崩溃!" (防止他人偷看你的代码) 16
POKE -16302, 0 Apple II [切换模式] "切换到全屏图形模式(没文字了!)" (注意Apple II的负数地址) 17
POKE -16303, 0 Apple II [切换模式] "滚回纯文本模式!" 17
CALL -16336 Apple II [制造声音] "让扬声器‘啵’一声。" (严格来说是CALL,但精神一致) 17
POKE 16384, 255 ZX Spectrum [写入屏幕] "点亮屏幕左上角的8个像素。" (Speccy的屏幕起始地址) 18

这些“魔法数字”(53280, 16384, -16302)是什么?它们是硬件工程师在设计芯片时,焊死在电路板上的“内存映射地址” 18

在今天,我们管这叫“API”(应用程序接口)。它们有正式的文档、有版本控制、有SDK。

而在80年代,真正的“API”不是BASIC手册,而是这份被黑客们口耳相传、互相传抄、在杂志角落里刊登的“内存地址列表” 15PEEKPOKE就是我们的GETPOST请求。

这种由“魔法数字”组成的秘密语言,是一种全球性的、去中心化的、开放源码的“黑客文化”的基石。它将一代程序员联合了起来。

3. CALL 地址 / SYS 地址: “召唤”或“执行”咒

这是“神圣三位一体”的最后,也是最关键的一步。

PEEKPOKE虽然强大,但它们本质上还是在BASIC里执行的。你POKE 53280, 2,电脑照做了,但控制权立刻回到了BASIC解释器。还记得我们那个10秒钟的FOR循环吗?那个循环之所以慢,就是因为BASIC解释器每循环一次,都要慢悠悠地“解释”一遍POKEPEEKNEXT命令 7

你需要的是一种方法,能让BASIC彻底闭嘴,把控制权完全交给那段闪电般快速的机器码。

这个咒语,就是CALL(在某些平台上)或SYS(在C64等平台上)1

  • 功能SYS是“System”(系统)的缩写。SYS 49152(C64上一个著名的用户程序入口点)这句命令,是对BASIC解释器的一个粗暴指令:“你,闭嘴。滚到一边去。把CPU的控制权交给内存地址为49152的那个家伙。等它(如果它还愿意)说‘完事了’(执行RTS指令)之后,你再回来。”
  • 感受:这是你施法时“屏住呼吸”的时刻。
  • 你(或者你抄的程序)刚刚花了30秒,用一个FOR...READ...DATA...POKE循环(我们马上会讲到),把500个字节的神秘机器码注入了从49152开始的内存里。
  • 现在,你颤抖着在“直接模式”下输入:SYS 49152
  • 你按下了回车。
  • 可能性A(90%的几率):你抄错了一个DATA里的数字。电脑会立刻死机。屏幕扭曲,发出一声刺耳的“滋——”,你所有的努力都白费了,只能关机重启 19
  • 可能性B(10%的几率):……你抄对了。
  • 屏幕瞬间闪黑。BASIC解释器消失了。然后,你那用100%汇编语言编写的、闪电般快速的demo开始运行。彩色的光栅条在屏幕上飞舞,SID芯片奏响了你从未听过的、多通道的、工业摇滚般的音乐。
  • 在那一刻,你就是神。

“大抄写”:一本杂志、500行DATA和一个致命的打字错误

现在,让我们把这“三位一体”组合起来,重现80年代最独特、最痛苦、也最富教育意义的仪式:“大抄写”。

在你的时代,软件不是“下载”的。它甚至不是(总能)“购买”的。它是“订阅”的——以一种极其折磨人的方式。

场景设定:1984年的某个周六。你揣着省下来的零花钱冲进报刊亭,买回了最新一期的《COMPUTE!》20、《INPUT》21或《Computer and Video Games (C&VG)》19。你兴奋地翻过那些花里胡哨的磁盘广告,找到了本月的“重磅游戏”:“雷神”(THUNDERMAN)或者“青蛙过河”(FROGGER)19

但杂志里夹着的不是磁盘或磁带。它只是文字。一页又一页,密密麻麻全是数字和代码 22

“大抄写”仪式开始了。

你看到的程序,通常分为两个部分:

第一部分:BASIC“加载器”(Loader)23

这本质上是一个非常简单的BASIC程序,它利用了我们“神圣三位一体”中的两个:READPOKE。它长这样:

10 REM *** THUNDERMAN LOADER ***
20 PRINT "LOADING... PLEASE WAIT."
30 FOR I = 49152 TO 49867
40   READ A
50   POKE I, A
60 NEXT I

这个循环的意思是:“从内存地址49152开始,挨个读取DATA语句里的数字,然后把它们一个一个地POKE(塞)进内存里。” 24

第二部分:“代码山”

在加载器下面,是真正的“代码”——也就是那500行DATA语句:25

500 DATA 169, 1, 141, 32, 208, 169, 5, 141
510 DATA 80, 200, 169, 0, 141, 33, 208, 96
520 DATA 169, 15, 141, 3, 212, 162, 0, 189
...
... (此处省略5页纸约400行DATA)...
...
5120 DATA 3, 56, 34, 43, 142, 255, 23, 8
...
5490 DATA 76, 0, 192, 0, 0, 0, 0, 0

第三部分:召唤

在所有DATA语句的最后,是那句决定命运的召唤:23

5500 PRINT "LOADING COMPLETE. TYPE SYS 49152"
5510 END

然后,你开始了这场长达数小时的“数据录入”苦修。你的眼睛在印刷模糊的杂志和电视屏幕间来回切换,手指因为敲击C64那糟糕的“面包块”键盘而抽筋。

这是你在80年代的“Bug谷”里接受的第一次洗礼。

你花了整整一个周末 26 在键盘上戳这些数字。你的眼睛快瞎了。

你颤抖着输入RUN

电脑开始读取DATA

屏幕显示:?SYNTAX ERROR IN 5120 19

你绝望地LIST 5120。你看到的是:5120 DATA 3, 56, 34, 43, 142, 256, 23, 8

你(和你的父母)会盯着这行数字,再对照杂志上的印刷体,看上一个小时。你看不出任何区别。然后你突然意识到……哦,POKE的值不能是256,它必须是0-255。那个256一定是个印刷错误,或者是你把255看错了!你把它改成了255 25

你再次RUN

这次,它读完了所有数据!LOADING COMPLETE.

你的心脏在狂跳。你输入了那个咒语:SYS 49152

……然后电脑死了 19。黑屏。死寂。

你哭着关机重启。你知道,在那几百行DATA里,在几千个数字中,还有另一个数字抄错了。

有一个在程序员中流传甚广的传奇轶事,它完美概括了这个时代的痛苦和荒诞 26

“我的父母总讲这个故事:他们花了整整一个周末,从杂志上抄一个程序。他们按下RUN,报错了。他们开始绝望地寻找打字错误。最后,他们惊恐地发现,在整个程序里,他们把数字‘0’(Zero)和字母‘O’(Oh)给搞混了。”

这个“0”和“O”的灾难是如此普遍,以至于后来的程序员圣经《K&R C语言》在字体选择上都特意区分了这两者。

杂志社也知道你很痛苦。他们不是魔鬼。所以他们发明了那个时代的“调试工具”:校验和(Checksum)程序 27

Antic杂志有“Typo”程序。 Compute! 杂志有“MLX”(Machine Language eXpress)27

而最荒诞的莫过于此:你必须先花一个小时,把这个100行的“MLX”程序给手动抄进电脑 27,并祈祷这个程序没抄错。然后运行它,它会接管你的输入。你再重新抄写一遍那500行的游戏,但这次,每输一行DATA,MLX会(用汇编)快速计算出一个“校验和”数字(比如[F3])。你再把这个数字和杂志上印的那个小小的校验和对比……如果对上了,你这行才算抄对。

现在,让我们暂停一下,用你50年后的知识来重新审视这个过程。

这整个痛苦的仪式,其实就是现代软件分发与验证的原始形态:

  1. 杂志社的编辑们无法在纸上“打印”二进制的机器码。所以他们必须把二进制文件“编码”成人类可以阅读和输入的“纯文本”——也就是十进制(Decimal)数字。
  2. DATA 169, 1, 141... 这一长串数字,就是机器码的“Base64编码” 22
  3. “大抄写”就是我们的“文件传输”。我们的“网络”是纸张,“带宽”就是我们(可怜的)打字速度。
  4. “MLX”或“Typo”程序(27)就是一个校验和工具。它读取你输入的DATA行,用一个(简单的)哈希算法计算出一个值,你再把它和杂志上打印的“官方哈希值”进行对比。它就是80年代的md5sumsha256

这个过程虽然痛苦,但这才是我们真正学会编程的方式。当你花了三个小时,终于找到那个把170抄成171的错误时,你已经不知不觉地学会了什么是“调试”,什么是“内存地址”,以及“一个字节的错误足以摧毁整个世界” 10

历史的伟大回响:“Python是新的BASIC”

好了,巫师。我们已经充分地在你的“怀旧浴缸”里泡澡了。现在,是时候把你捞出来,擦干身体,面对2025年的现实了。

你环顾四周,发现这个新世界的人们(又)在为一种“简单”的语言而疯狂。它不是BASIC。它叫“Python”。

你可能听说过这个在业界广为流传的类比:“Python是新的BASIC” 1

  • 它易于学习,语法极简(你甚至都不用写分号或大括号!)28
  • 它在大学里教给那些非计算机专业的学生(比如生物学家和金融分析师),就像当年BASIC教给所有人一样 9
  • 它(和BASIC一样)是“解释型”的,而且(当你单独运行它时)巨慢无比 29

作为一个在80年代为了那“10秒钟”屏幕反转而抓狂、不惜堕入汇编地狱的性能专家,你对这个新世界感到极度困惑。

“等一下,”你会说,“如果Python这么慢,为什么全世界最需要计算性能的领域——比如人工智能(AI)、机器学习、大数据科学、金融建模——全都在用Python?!” 30

欢迎来到本章的“啊哈!”时刻。

答案是:因为当一个现代数据科学家在用Python时,他根本没在用Python。

当一个2025年的数据科学家,在他那台价值5000美元的笔记本电脑上,悠闲地输入 import numpyimport tensorflow 时... 30

...他执行的动作,和你当年在C64上颤抖着输入 SYS 49152...

...在精神上是完全一致的。

你那套“BASIC外壳 + 汇编内核”的模式 1,不仅没有过时,反而征服了全世界,成为当今最前沿领域的主导架构。

  • Python的角色:Python(29)扮演的,就是你当年BASIC扮演的角色——一个友好的、高层次的“胶水语言”(Glue Code)。它只负责处理顶层的“业务逻辑”,比如“加载这个数据文件”、“调用那个AI模型”、“把结果画成图表” 31。它本身慢得要死,但这没关系,因为它干的都是“慢活儿”。
  • C++ / C / Fortran的角色:而那些被import进来的库(比如NumPy, TensorFlow, Pandas)30,它们的“内核”(Kernels)根本不是用Python写的。它们是“预编译好的、被极度优化的C++、C甚至Fortran代码” 29。它们就是你当年那些塞在DATA语句里的、闪电般快速的“机器码”。

当Python执行一行像 result = numpy.dot(matrix_a, matrix_b)(一个超大的矩阵乘法)这样的代码时,Python解释器立刻“交出控制权”(就像当年的SYS命令),去调用一个(等同于你汇编的)C++函数。这个C++函数会接管CPU(甚至GPU),以纯粹的、接近硬件极限的速度完成那几十亿次计算,然后只把最终结果返回给Python。

Python甚至都不知道发生了什么。它只知道自己“调用了一个东西”,然后“拿到了一个结果”。

让我们把这个伟大的历史回响并排放在一起:

  • 1985年的你:用(慢速的)BASIC作为“外壳”,加载和CALL 1 那些用(高速的)汇编语言写的、存储在DATA语句里的“内核”,来处理图形、声音和碰撞检测 6
  • 2025年的数据科学家:用(慢速的)Python作为“外壳”,import和调用 29 那些用(高速的)C++写的、存储在.whl(库文件)里的“内核”,来处理矩阵、神经网络和数据分析。

你不是“过时”了。你只是“早熟”了40年。

你,这位“恐龙”程序员,早在80年代就已经在实践一个复杂的“混合范式”、“系统集成”的开发模型。你本能地掌握了“用胶水语言粘合高性能内核”的艺术 6,而这门艺术在几十年后才被“重新发现”,并换上“数据科学”和“人工智能”的时髦马甲,统治了全世界。

结论:欢迎回来,巫师。你的咒语书只是换了个封面。

那个在80年代卧室里,借着台灯光,对着《COMPUTE!》杂志抄写DATA语句(25)的孩子……

……和那个在2025年开放式办公室里,喝着20美元一杯的燕麦拿铁,对着Jupyter Notebook敲下import pandas的数据科学家……

……在精神上是同一个人。

技术的表象已经天翻地覆。但其核心的“灵魂”——对抽象的运用、对性能瓶颈的识别、以及那股“与金属对话”的原始冲动——是永恒的。

POKE 53280, 5import tensorflow 1 都是魔法咒语。

DATA 169, 1, 141 和 C++ 内核 32 都是魔法的来源。

你并非恐龙。在这个新世界里,你是房间中唯一一个真正知道引擎盖下发生了什么的人。当现代的程序员对AI为何如此之快感到迷惑时,你可以轻蔑地一笑,因为你早在40年前,就已经在用SYS 49152召唤神灵了。

你的咒语书只是换了一个更光滑的封面而已。

欢迎回来,巫师。现在,让我们翻开下一章,去看看那场几乎撕裂了整个编程宇宙的圣战:GOTO是如何死去的。

【ps. 如果这一章你读得热泪盈眶,那么老伙计,你该去约个体检了,别忘了做结肠镜】


参考链接


  1. 程序员复活手册:从BASIC到AI(大纲) ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎

  2. C64 - Assembler Programming for Everyone | Code Stories, 访问时间为 十月 27, 2025 ↩︎ ↩︎ ↩︎

  3. Learn Multi platform 6502 Assembly Programming... For Monsters! - Chibi Akumas, 访问时间为 十月 27, 2025 ↩︎ ↩︎ ↩︎

  4. The Power of PEEK and POKE. What could a couple of simple commands… | by Randy Heller | Medium, 访问时间为 十月 27, 2025 ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎

  5. Learning to Code Like It's 1982 - Introduction to Basic - YouTube, 访问时间为 十月 27, 2025 ↩︎

  6. Basic or assembly? : r/c64 - Reddit, 访问时间为 十月 27, 2025 ↩︎ ↩︎ ↩︎ ↩︎ ↩︎

  7. How slow was the 6502 BASIC compared to Assembly ..., 访问时间为 十月 27, 2025 ↩︎ ↩︎ ↩︎ ↩︎

  8. Interview with 80s Computer Nerd - YouTube, 访问时间为 十月 27, 2025 ↩︎ ↩︎ ↩︎

  9. BASIC - Wikipedia, 访问时间为 十月 27, 2025 ↩︎ ↩︎

  10. Learning BASIC Like It's 1983 - Two-Bit History, 访问时间为 十月 27, 2025 ↩︎ ↩︎

  11. Easy 6502 by skilldrick - GitHub Pages, 访问时间为 十月 27, 2025 ↩︎ ↩︎ ↩︎ ↩︎ ↩︎

  12. Z80 assembly : r/Assembly_language - Reddit, 访问时间为 十月 27, 2025 ↩︎ ↩︎

  13. Oddities With Z80 Assembly : r/asm - Reddit, 访问时间为 十月 27, 2025 ↩︎ ↩︎

  14. Level II Tips and Tricks – Ira Goldklang's TRS-80 Revived Site, 访问时间为 十月 27, 2025 ↩︎

  15. Ian Skinner's Commodore Stuff - Tierceron.com, 访问时间为 十月 27, 2025 ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎ ↩︎

  16. ready64.org, 访问时间为 十月 27, 2025 ↩︎ ↩︎ ↩︎

  17. Bigger Apple II PEEK, POKE and CALL List - Vintagecomputer.net, 访问时间为 十月 27, 2025 ↩︎ ↩︎ ↩︎

  18. 10 FOR z=16384 TO 22527 20 POKE z,255 30 NEXT z - El wiki de Speccy.org, 访问时间为 十月 27, 2025 ↩︎ ↩︎

  19. Were Magazine Type-In Games Really That Bad? // Coding Again Like It's The 80s, 访问时间为 十月 27, 2025 ↩︎ ↩︎ ↩︎ ↩︎ ↩︎

  20. Reminiscing, Part 3 - Tekkie - WordPress.com, 访问时间为 十月 27, 2025 ↩︎

  21. Remembering INPUT magazine - Lost Boy, 访问时间为 十月 27, 2025 ↩︎

  22. Data Statements: Type-In Games From 1980's Computing ... - Reddit, 访问时间为 十月 27, 2025 ↩︎ ↩︎

  23. POKE in ZX Spectrum - Stack Overflow, 访问时间为 十月 27, 2025 ↩︎ ↩︎

  24. Embarking on an 80s Time Travel Adventure: Commodore 64 Machine Code Programming with BASIC | by Alexey Medvecky | Medium, 访问时间为 十月 27, 2025 ↩︎

  25. Back in the '80s and early '90s, magazines used to print entire game or utility programs (usually in BASIC) for readers to type into their home computers. These "type-in programs" were a fun (and sometimes frustrating) way people learned coding before the internet or easy software access. : r/ - Reddit, 访问时间为 十月 27, 2025 ↩︎ ↩︎ ↩︎

  26. BASIC programs in magazines that you had to manually copy to ..., 访问时间为 十月 27, 2025 ↩︎ ↩︎

  27. reference request - Is there any hard data about type-in programs in ..., 访问时间为 十月 27, 2025 ↩︎ ↩︎ ↩︎ ↩︎

  28. Why do you use Python? - Quora, 访问时间为 十月 27, 2025 ↩︎

  29. Python is Like Assembly | Speculative Branches, 访问时间为 十月 27, 2025 ↩︎ ↩︎ ↩︎ ↩︎

  30. Python Libraries Written in C++ - Codefinity, 访问时间为 十月 27, 2025 ↩︎ ↩︎ ↩︎

  31. For deep learning in C++, is PyTorch or Tensorflow better? : r/cpp - Reddit, 访问时间为 十月 27, 2025 ↩︎

  32. Create an op | TensorFlow Core, 访问时间为 十月 27, 2025 ↩︎