为什么我要使用 NASM 而不是 GNU Assembler (GAS)?

Ser*_*ket 3 assembly gnu gnu-assembler nasm

当 GAS 支持多种架构而 NASM 只支持 x86 架构时,为什么我要在 GNU 汇编器 (GAS) 上使用 NASM?我知道存在句法差异,但这并没有让我太困扰。

Pet*_*des 9

ASM 本质上是不可移植的。对于其他 ISA,只有 GAS 指令是相同的(不是指令甚至注释字符),并且任何给定的 asm 源文件都将用于单个 ISA。GAS 本身支持多个目标并不是真正相关的,你仍然需要学习其他机器。(一旦您了解了基础知识,至少不难掌握,但指令语法差异通常更容易)。一些其他的汇编为其他的ISA使用NASM风格dbdd数据伪指令,其他人使用Unix风格.byte.long类似气体(或气体)。但这很容易适应。

GAS 最初设计用于汇编编译器输出;因此,它的错误消息并不总是适合人类使用。(就明确它不喜欢一条线的内容而言)。NASM 趋向于更好(但绝不是完美的),现代 GAS 通常也不错;一些主要项目(如 glibc 和 Linux)有手写的 GAS 源文件,所以肯定有人使用它。

NASM 有一种宏语言 ( https://www.nasm.us/doc/nasmdoc4.html ),它在某些方面比GAS 的.macro更容易用于复杂的东西。(尽管在 GAS 中使用 CPP 宏是很常见的)。

对于微基准测试(如今手动玩 asm 的少数原因之一),NASM 具有我不知道如何在 GAS 中轻松实现的功能:times重复一行。 %rep重复一个块也很有用。GAS.rept可以做到这一点,但如果您想改变块(例如展开和执行[rdi+0]/ [rdi+4]/ ...),NASM 更好。在 GAS 中,您可以使用递归宏,该宏使用较小的 arg 调用自身,但 NASM 允许%assign%rep.

    times 10  imul eax,eax        ; repeat this line 10 times

 %rep 10                       ; repeat this block 10 times
    add  eax, ecx
    add  ecx, eax
 %endrep
Run Code Online (Sandbox Code Playgroud)

NASM 对作为数字的多字符常量具有非常好的语法,例如mov rax, 'abcdefgh'/push rax导致堆栈上按源顺序排列的 8 个 ASCII 字符。GAS 不能做任何等效的事情;你需要使用原始数字或类似的东西'h'<<56 | 'g'<<48 | ...

NASM 可以组装平面二进制文件,而无需链接器 + 链接器脚本的复杂性。大多数只与 16 位引导加载程序相关,但可能与 shellcode 相关。

直到最近,GAS 还有一些不好的东西,比如add [rdi], 1234默默地默认为 dword 操作数大小,而不是警告你它对于mov. 最近的 GAS 已经解决了这个问题;现在这是一个错误,就像在 NASM 中一样。


NASM 的语法是 100% 一致的[]- 括号存在总是意味着内存操作数,不存在意味着永远不会是内存操作数。(只是为了清楚我的意思,LEA 接受一个内存操作数,但不从中加载。)AT&T 语法也很容易区分($或不是立即数或内存之间的区别),但GAS.intel_syntax noprefix取决于符号如何被宣布add eax, foobar可能是add eax, imm32add eax, [disp32]。更糟的是,这取决于是否foobar有被宣布equ=之前或指令,除非你使用用途后OFFSET,即使你以后做foobar = 42将 GNU 中的内存与常量区分为 .intel_syntax.

Intel 语法是 NASM 的主要且唯一的模式,因此您可以轻松地在 Intel 或 AMD 的手册中查找说明。 .intel_syntax noprefix是 GAS 的次要功能,不像其 AT&T 那样有详细的文档记录。除了上述歧义外,它确实可以正常工作。

有时 GNU 工具即使在 Intel 语法模式下(如objdump -d -Mintel)仍然遵循 AT&T 语法错误交换的某些形式的 x87 指令,如 fdiv 与 fdivr。如果您想使用 x87,请尽可能避免使用 GAS。请参阅GAS 手册中的9.16.17 AT&T 语法错误。我认为现代 objdump 现在可能“正确”,但如果我只使用 GAS + binutils,我将不会有一些我相信不会被 GAS 必须与错误兼容的愚蠢 AT&T 实现错误破坏的东西。在 x87 指令之外完全不相关,所以幸运的是现在大部分时间都不相关。

  • 从概述的角度来看,这涵盖了所有内容。我很高兴您谈到 NASM 的宏功能。这经常被忽视,但对于小任务来说却非常方便。始终具有教育意义的答案。 (5认同)