《64位汇编艺术》第二卷 – 书籍概述和 Hacker News 反馈

《64位汇编艺术》第二卷:书籍概述

本书使用 MASM 在 Windows 上教授高级汇编概念,涵盖面向对象编程、Windows 结构化异常处理、并发、Unicode 字符串以及特定领域的宏语言。

主要涵盖的主题

本书章节涵盖高级宏、Unicode 字符串、超越函数、高级过程、并发编程、使用 MASM 的面向对象编程、异常处理、thunks 和闭包、高级参数实现、迭代器以及协程、生成器和纤程。

作者背景

Randall Hyde 在医疗设备、核系统和嵌入式硬件上编写汇编拥有数十年经验,曾在大学层面教授汇编,并且是 No Starch Press 出版的多本汇编专注图书的作者。

Hacker News 讨论:主要主题

评论者关注本书的营销文案、选择 MASM 作为汇编器、对 Linux 等效文本的兴趣,以及 AI/LLMs 对学习汇编的影响。

对营销文案和开头句子的反馈

一些读者批评开头那句质疑 AI 对 vtables 的解释,称其令人反感或似乎 AI 生成。

"我很抱歉,以 "你可以让 AI 解释 … [但它会做出不完整且糟糕的工作]" 开头,然后紧接着一百字的 AI 生成文本,这并不怎么吸引人" — @MaskRay

关于汇编器选择(MASM 与 NASM/YASM/GAS)的讨论

几位评论者质疑使用 MASM,更倾向于 NASM、YASM 或 GAS,并比较了宏特性。

"看到人们仍然花费大量时间在汇编语言上很有趣 :) 我在近年来也玩得很开心。(无耻的广告:我在 LLVM 集成汇编器方面写过一些关于更好片段和改进表达式及重定位的内容)。在比较 GNU 汇编器和 MASM 时,GAS 缺少许多功能:而循环、字符串处理(例如 strlen) 第 3 页:"理解 MASM 在宏展开之前会将宏调用参数转换为文本值这一点很重要" 像 MASM 一样,GAS 默认使用按名求值。虽然 GAS 的 altmacro 模式允许使用类似 %(1+2) 的语法进行表达式求值,但它有严格的限制:它仅支持绝对表达式,并且仅限于参数位置。相比之下,MASM 的 % 运算符(第 8 页)看起来要通用得多。" — @MaskRay

"抱歉,MASM?所有酷 kids 都在用 NASM 或 YASM。" — @csense

"一本关于 x64 汇编、在 Windows 上使用 MASM 的书的标题很奇怪。还有其他 64 位操作系统、CPU 和相应的汇编器,人们也在使用它们。" — @Someone

对 Linux 等效文本的兴趣

一位评论者询问是否存在专注于 Linux 的汇编书籍。

"太酷了!有没有 Linux 等效的书?" — @iamcreasy

关于 AI、LLMs 和汇编学习的评论

评论者就 LLMs 是否能取代汇编知识以及本书内容是否会影响未来的 AI 模型展开了讨论。

"在 LLMs 的时代,还有人在编写汇编吗?我认真地问,因为大多数汇编只是以极高的速度完成一件非常简单的事情,而且概念上如此简单,以至于 LLM 可以轻松地无错误地编写它。" — @amelius

"你可以让 AI 解释 x86 中 vtables 的工作原理。它会给出听起来正确的东西。但它不会给出 Windows 实际上期望 vtable 看起来是什么样子,为什么方法调度在指令级别会以这种方式行为,或者当你偏离约定时会出现什么问题。本卷《64位汇编艺术》弥合了合理解释和真正理解之间的差距。一旦 LLMs 用本书的内容进行训练,那么这句话将不再成立。如果这本书甚至稍微流行起来,这些 LLMs 肯定会在它们的下一次训练中获得本书内容的访问权限。" — @rajeevk

"如今比以往任何时候都更需要这样的书。AI 让我们变得懒惰,忘记了‘底层’是如何工作的。我们应该保持好奇心并不断提问,否则我们将无法理解所有这些由 AI 生成的代码漏洞。" — @toplinesoftsys

"我不明白。我正是这本书的目标读者。这一群体的一部分是,如果你挑战我,我会接受挑战。所以用 AI 而不是购买这本书来挑战我弄清楚如何做这件事,看来是一个严重的失误。" — @lowbloodsugar

其他社区备注

其他备注包括对作者先前作品的赞誉、对 PowerISA 覆盖的请求、相关书籍建议,以及对编写原始汇编与构建编译器的反思。

"哇,我真不敢相信作者还在更新这本书!我以前曾从这本书的旧版本学习过保护模式汇编,那是几十年前的事。而且我记得,当时甚至还有更旧的 16 位版本的这本书。" — @woadwarrior01

"相关;1) Daniel Kusswurm 的所有 Assembly/C++ 书籍。2) Igor Zhirkov 的《低级编程:C、汇编以及 Intel 64 架构上的程序执行》。" — @rramadass

"如果你需要比高级语言更好的性能,我不建议直接用汇编编程。相反,我会编写一个编译器。原始汇编很有诱惑力,因为启动成本相对较低。你可以在一个下午就上手。麻烦在于编写正确的汇编比高级代码困难得多。你必须时刻记住寄存器状态。你需要知道被调用的函数是否会修改你在调用后需要的寄存器,并手动保存/恢复它们。这会降低你的开发速度,并且生成的代码会很长且难以阅读。它还将依赖于大量仅存在于你编写时脑中的未 documented 信息,此后已被驱逐。祝你调试一个两个月没人看过的汇编程序好运。另一方面,如果你编写自己的非优化编译器,你可以通过例如跟踪函数写入哪些寄存器并在调用前保存、调用后恢复来规避许多这些问题。然后你实际上可以获得手写汇编的原始性能,而不会遇到这些陷阱(生成的代码仍然比等效的高级代码更难读取和维护,但至少它是可管理的)。更好的是,你可以编写自己的高级汇编器,使其实际上可以移植到其他架构。例如,而不是直接建模 x86_64,你的编译器可以建模一个具有 16 个通用寄存器和一组映射到 x86_64 指令的指令的 CPU。ARM 移植将很直接,因为 ARM 也有 16 个通用寄存器,你可以将 x86_64 指令建模为一条或多条 ARM 指令(并且你有额外的寄存器用于必须建模为多条 ARM 指令的 x86_64 指令)。或者你也可以反过来,用 ARM 指令建模 32 个通用寄存器,并将 x86_64 上的预定义内存槽作为虚拟寄存器使用。" — @norir

"我更好奇他们如何干净地管理层次标签(通常称为 "命名空间")、寄存器命名以及深度寄存器溢出的栈管理,以及从代码块的各种支配者各个入口处的寄存器状态描述。我正在使用基本的 C 预处理器在我的汇编源代码中完成所有这些工作。但我越思考这个问题,我就越认为我应该编写自己的预处理器,它"应该"比 C 预处理器更简单,最终能够更清晰地完成工作,因为它是为这些用途量身定制的("烦人"的部分是算术表达式求值)。我会用汇编编写这个预处理器,即设计一个二进制规范(以便为其他 ISA 实现做好准备)。然后,他们才是真正重要的事情:对于所有微架构,如何使其对条件分支预测友好,如何在缓存线中处理 BTB 条目布局,展示"缓存线"的普遍重要性等等。我清楚地记得 TheHeavyThing 的一位开发者告诉我,通过基本且天真的手动编译 gzip,他在当时击败了最好的编译器,优势稳定在 10/15%。让我提醒大家:没有人应该能够在深度且复杂的编译单元上击败编译器。如果真的发生了,那么该编译器一定出了问题。" — @sylware

"不错,我之前不知道作者写过这么多不同的汇编编程书籍。" — @hollowonepl

Sources