为什么我要使用NASM而不是GNUAssembler(GAS)?
当 GAS 支持多种架构而 NASM 只支持 x86 架构时,为什么我要在 GNU 汇编器 (GAS) 上使用 NASM?我知道存在句法差异,但这并没有让我太困扰。
回答
ASM 本质上是不可移植的。对于其他 ISA,只有 GAS 指令是相同的(不是指令甚至注释字符),并且任何给定的 asm 源文件都将用于单个 ISA。GAS 本身支持多个目标并不是真正相关的,你仍然需要学习其他机器。(一旦您了解了基础知识,至少不难掌握,但指令语法差异通常更容易)。一些其他的汇编为其他的ISA使用NASM风格db和dd数据伪指令,其他人使用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
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, imm32或add 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 指令之外完全不相关,所以幸运的是现在大部分时间都不相关。
- That about covers it all from an overview standpoint. I'm glad you touched on NASM's macro feature. That is often overlooked but extremely handy for small tasks. Always educational answers.