谁说 Assembly 是无类型的?大家都错了

Everyone says assembly is untyped—everyone is wrong

我坚信 Odin 的 inline assembly 是目前所有语言中最好的。与 GCC、Clang 或 Rust 等语言将内联汇编视为字符串补丁不同,Odin 将其设计为与语言深度集成的 `asm` 模板。这些模板支持完整的类型检查、统一的语法以及通过 `core:rexcode` 提供的真实语义诊断。汇编并非无类型,每条指令都有严格的类型约束。Odin 在约 7 天内构建了这套系统,它不再是一个逃生舱口,而是语言本身的一部分,真正实现了汇编代码与宿主语言的无缝融合。

汇编实际上是一种多态类型代数,但大家都约定俗成地假装它是一锅字节汤。
  1. AshamedCaptain

    > AT&T 把操作数宽度直接 baked 进了助记符里(movb, movw, movl, movq [...]),而 Intel 语法则是给内存操作数加上 byte、word、dword 或 qword 前缀,但 Odin 直接使用了 Odin 的类型系统。

    在 GAS 里你可以省略助记符中的宽度后缀,在大多数 Intel 汇编器里你也可以省略像 byte 这样的内存类型操作符。它们会乐意根据操作数自动推断。问题在于,在 x86 上(甚至其他 ISA 上,尽管程度较低),不同的操作数尺寸会带来很多副作用,这就是为什么大家都把操作数尺寸显式写出来,以至于作者/LLM 似乎认为这是强制要求的。

    这简直让文章的标题显得有点自相矛盾……

    明天你需要把一个 128 位整数传入两个寄存器,你那花哨的语法到时候也会变成一堆乱七八糟的 hack。这就是为什么所有人的内联汇编语法都长那个样子,因为他们想覆盖那些奇怪的边缘情况(gcc 的那套简直就是一本历史书)。你通常是在遇到某些荒谬的角落情况时才会用内联汇编,如果不是这种情况,那你应该用的是更接近 intrinsics 的东西……

    另外,它还漏掉了 Watcom C,它确实有一套完整但混乱的内联汇编语法(这与其指定非常奇怪的调用约定的能力结合得很好)。

  2. amluto

    我对这种自定义语法意见很复杂。在我看来,正确的汇编语法(极少数例外除外)就是手册里写的那套。这就是为什么 Intel 语法是对的,而 AT&T 语法是错的:ISA 来自 Intel,文档来自 Intel 和 AMD,而这些文档用的都是 Intel 语法。

    所以我原本有点指望这种自定义语法至少能带来一个非常、非常强大的检查器,至少能和 Fil-C 的一样好。也许还能留个逃生舱口,让你能说类似“我知道这看起来像是我破坏了 xyz,但我保证我真的没有”这样的话。

    可惜,文章里的 CPUID 例子似乎能编译通过,但在我看来它根本不应该通过:CPUID 需要两个输入,分别在 EAX 和 ECX 里,而例子忘了把 ECX 绑定为输入。有人可能会争辩说,如果你在虚拟机里做点特殊操作,CPUID 甚至需要更多输入,但 ECX 真的非常明确。

  3. Jblx2

    你能在汇编时或运行时得到类型错误吗?如果去掉这个标题党式的标题,否则这篇文章可能还挺不错的。

同日更多故事

2026-08-22