NASM - 全网通用汇编器

引言

什么是NASM?

全网通用汇编器(NASM,Netwide Assembler)是一款为可移植性和模块化而设计的80x86和x86-64汇编器,支持多种目标文件格式,包括Linux与*BSD的a.out、ELF、Mach-O、16位和32位的.obj(OMF)格式,COFF(包括其Win32和Win64变体)。同样可以输出原始二进制文件、Intel十六进制格式和以及Motorola S-Record。其语法设计得简单易懂,类似于Intel软件开发者手册中的语法,并尽可能降低了复杂性。支持当前所有已知的x86架构扩展,并提供了强大的宏命令支持。

许可证

NASM遵循所谓的2-clause BSD许可证,亦称BSD简化许可证:
版权所在 1996-2024 NASM作者 - 保留所有权利。
允许以源代码和二进制形式再分发与使用(无论修改与否),但须满足以下条件:

  • 源代码再分发须保留上述版权声明、本条件清单及下述免责声明。
  • 二进制形式再分发须在随分发的文档和/或其他材料中复制上述版权声明、本材料清单及下述免责声明。
    本软件按”原样”提供,版权持有人及贡献者不承担任何明示或默示的担保责任,包括但不限于对适销性和特定用途适用性的默示担保。在任何情况下,无论基于何种法律理论(无论是合同责任、严格责任还是侵权责任,包括疏忽或其他原因),版权持有人或贡献者均不对因使用本软件而产生的任何直接、间接、偶然、特殊、典型或后果性损害(包括但不限于替代商品或服务的采购、使用损失、数据丢失或利润损失、业务中断)承担责任,即使已被告知发生此类损害的可能性。

运行NASM

NASM命令行语法

要汇编一个文件,可以使用以下形式的命令:

1
nasm -f <格式> <文件名> [-o <输出文件名>]

例如:
1
nasm -f elf myfile.asm

将汇编myfile.asm为ELF对象文件myfile.o,而:
1
nasm -f bin myfile.asm -o myfile.com

将汇编myfile.asm为原始二进制文件myfile.com
要生成在源代码左侧显示NASM输出的十六进制机器码的列表文件,添加-l选项并给出列表文件名,例如:
1
nasm -f coff myfile.asm -l myfile.lst

要获取NASM的更多使用说明,请输入:
1
nasm -h

选项-h可替换为--help
如果使用Linux但不确定系统使用的是a.out还是ELF,(在存放NASM二进制文件的目录)执行:
1
file nasm

如果输出结果类似:
1
nasm: ELF 32-bit LSB executable i386 (386 and up) Version 1

则系统使用ELF,在编译Linux目标文件时应当使用-f elf选项。如果输出结果类似:
1
nasm: Linux/i386 demand-paged executable (QMAGIC)

系统使用a.out,应当使用-f aout(Linuxa.out系统早已废弃,如今已罕见)
和Unix编译器与汇编器一样,NASM除报错外没有其他提示。

-o选项:输出文件名

NASM通常会自动选择输出文件名,具体命名规则取决于目标文件格式。对于Microsoft目标文件格式(objwin32win64),会将你的源文件名的.asm扩展名(或其他扩展名——NASM对此无限制)换成.obj。对于Unix目标文件格式(aoutas86coffelf32elf64elfx32ieeemacho32macho64),会换成.o。对于dbgithsrec,会分别使用.dbg.ith.srec。对于bin格式只是去掉扩展名,例如myfile.asm生成myfile文件。
如果输出文件已存在,NASM会将其覆盖。除非其名称与输入文件相同,这种情况将会给出警告并使用nasm.out作为输出文件名。
如果不接受该默认行为,NASM提供了-o命令行选项,用于指定自己想要的的输出文件名。可以在-o选项后加上自己想要的输出文件名,中间有无空格均可,例如:

1
2
nasm -f bin program.asm -o program.com
nasm -f bin driver.asm -odriver.sys

注意此处为小写o,与制定优化次数的大写O不同。见节2.1.24

-f选项:输出文件格式

如果未指定-f选项,NASM将自己选择输出文件格式。在NASM的发行版中,默认选项始终是bin;如果自行编译NASM,可以在编译时重新定义OF_DEFAULT并指定想要的默认选项。
-o一样,-f和输出文件格式间的空格可有可无;因此-f elf-felf均有效。
可用输出文件格式的完整列表可以由命令nasm -h给出。

-l选项:生成列表文件

如果指定-l选项并在其后(中间的空格可有可无)加上一个文件名,NASM会生成一个源代码列表文件。其中地址和生成的机器码会列在左侧,源代码和多行宏的展开内容(除特别声明不展开的宏外:见节4.5.11)。例如:

1
nasm -f elf myfile.asm -l myfile.lst

若已启用列表文件生成,可通过指令[list -]不列出源代码中的某一部分,通过[list +]恢复列出(默认)。该指令不存在(省略括号的)“使用形式”。该功能可用于仅列出目标的代码部分,避免生成过于冗长的列表文件。

-L选项:附加或修改列表文件信息

使用该选项指定列表文件的输出细节。
支持的选项有:

  • -Lb显示内置宏包(标准和%use
  • -Ld以十进制,而非十六进制显示字节计数和重复次数
  • -Le显示预处理输入
  • -Lf忽略.nolist并强制输出列表文件
  • -Lm显示带参数展开的多行宏调用
  • -Lp在每次编译过程输出列表文件,用于错误排查
  • -Ls显示所有单行宏定义
  • -Lw逐行刷新输出(极慢,主要用于调试NASM崩溃问题)
  • -L+启用除-Lw外的所有列表功能选项(极详细)
    这些选项可以通过使用运行时指令%pragma list options启用或禁用:
    1
    %pragma list options [+|-]标志...
    例如,启用dm标志,禁用s标志:
    1
    %pragma list options +dm -s
    出于向前兼容性考虑,未定义的标志将忽略。因此,指定NASM新版本引入的标志并不会影响旧版本。列表文件选项标志始终为单字母数字字符,区分大小写。

-M选项:生成Makefile依赖项

该选项用于将makefile依赖项输出到stdout。可重定向到一个文件以进行后续处理。例如:

1
nasm -M myfile.asm > myfile.dep

-MG选项:生成Makefile依赖项

该选项用于将makefile依赖项输出到stdout。与-M选项不同,如果遇到不存在的文件,会将其视为生成的文件,并将其添加到依赖列表(无前缀)。

-MF选项:设置Makefile依赖文件

该选项和-M-MG一起使用,将输出送入文件而不是stdout,例如:

1
nasm -M -MF myfile.dep myfile.asm

-MD选项:汇编并生成依赖项

-MD选项等效于同时使用-M-MF选项(此时必须指定文件名)。但是,和-M-MG选项不同,-MD没有终止汇编器的正常功能。使用该选项在每次汇编时自动生成更新的依赖项。例如:

1
nasm -f elf -o myfile.o -MD myfile.dep myfile.asm

如果-MD后的参数是选项而非文件名,则按以下优先级确定输出文件名:

  • -MF选项设置的文件名;
  • -o选项的输出文件名加上.d
  • 输入文件名,扩展名设为.d

-MT选项:依赖目标名称

-MT可用于覆盖依赖目标的默认名称。一般和输出文件名一致,由-o选项指定。

-MQ选项:依赖目标名称(转义)

-MQ选项与-MT选项功能类似,除了会试着对Makefile语法中的特殊字符转义。这并非万无一失,因为并非所有特殊字符都能在make中正确地转义。默认输出(如果未指定-MT-MQ)会自动转义。

-MP选项:生成伪Makefile目标

和任何依赖生成选项一起使用时,-MP选项会使NASM为每个头文件生成一个无依赖项的伪目标。阻止make在头文件被移除时报错。

-MW选项:Watcom make转义风格

该选项使NASM尝试根据Watcom make规则而非POSIX make规则(也被大多数make的变种所采用)转义依赖。这种规则转义#的方式是$#而不是\#,续行符使用&而不是\,并将包含空格的文件名用引号括起来。

-F选项:调试信息格式

该选项用于选择输出文件中调试信息的格式,供调试器使用。在2.03.01版本前,启用此选项并不会输出所选的调试信息格式。使用-g启用输出,见节2.1.14。版本2.03.01及后续版本在指定-F时自动启用-g
输出格式可用的调试文件格式的完整列表可通过命令nasm -h查询。当前并非所有输出格式均支持调试输出。
请不要和-f dbg输出格式选项混淆,见节8.13

-g选项:启用调试信息

该选项可以用于生成制定格式的调试信息。见节[2.1.13]。不使用-F单独使用-g会以所选输出格式的默认调试格式(如果存在)输出调试信息。如果当前所选输出格式未实现调试信息,-g将被忽略。

-X选项:选择报错格式

该选项可被用于选择任何NASM产生的报错的格式。
目前有两种可选的报错格式。分别是-Xvc选项和-Xgnu选项。GNU格式为默认,如下所示:

1
filename.asm:65: error: specific error messageerror is the severity of the error (this could be warning)

其中filename.asm是发现错误的源文件的文件名,65是发现错误的源文件行号,error是错误的严重性(还可能是warning),specific error message是更详细的文本说明,帮助定位具体问题。
另一种格式,由-Xvc指定,是由微软Visual C++和其他一些程序使用的风格,如下所示:
1
filename.asm(65) : error: specific error message

唯一的区别是行号在括号中,而不是被分号分隔。
Visual C++输出格式,节8.5

-Z选项:将错误发送到文件

MS-DOS上很难(虽然可以)将程序的标准错误输出重定向到一个文件。由于NASM通常将警告和错误输出到stderr,(举例来说)如果需要将这些信息载入编辑器,可能很难捕获错误。
NASM因此提供了-Z选项,接受一个文件名参数,并将错误信息输出到指定文件而非标准错误流。因此可以用如下命令将错误重定向到一个文件。

1
nasm -Z myfile.err -f obj myfile.asm

在NASM的早期版本,该选项称作-E,但因-E选项通常仅用于预处理,该设计已被调整,复用会引发灾难性后果。见节2.1.22

-s选项:将错误发送到stdout

-s选项将错误信息重定向到stdout而不是stderr,因此可以在MS-DOS上重定向。要汇编myfile.asm文件并将其输出传递给more程序,可以输入以下命令:

1
nasm -s -f obj myfile.asm | more

-Z选项,节2.1.16

-i选项:包含文件搜索目录

当NASM在源文件中遇到%include%pathsearch命令(见节4.8.1,节4.8.2或节3.2.3),不仅会在当前目录搜索指定文件,还会在东莞命令行选项-i添加的目录中搜素。因此 比如说,可以用如下命令引入宏库中的文件

1
nasm -ic:\marcolib\ -f obj myfile.asm

(通常,-i与路径名之间的空格可有可无)。
NASM 2.14之前,通过该选项给出的路径会直接原样使用,是否添加路径分隔符取决于调用方。此前允许隐式拼接搜索路径与文件名。不过这也只是华而不实。现在则强制保留末尾路径分隔符,因此-ifoo会认为是-ifoo/目录。
如果想要定义标准包含搜索路径,类似Unix系统上的/usr/include,可以在NASMENV环境变量中设置一或多个-i参数(见节2.1.35)。
考虑到Makefile和多数C编译器的兼容性,该选项也可以指定为-I

-p选项:预包含文件

NASM允许通过-p选项指定文件成为源代码的预包含文件。因此运行:

1
nasm myfile.asm -p myinc.inc

等价于运行nasm myfile.asm并在文件的开头放上%include "myinc.inc"
--include选项同样可接受。
考虑到和-I-D-U选项保持一致,该选项也可以指定为-P

-d选项:预定义宏

正如-p选项提供了源文件开头的%include命令的替代,d选项提供了%define命令的替代,可以输入:

1
nasm myfile.asm -dFOO=100。

替代文件开头的下面这条指令:
1
%define FOO 100

也可以忽略宏的值:选项-dFOO等价于代码%define FOO。这种形式的命令适用于配置需要通过%ifdef检测的汇编时选项,例如-dDEBUG
考虑到Makefile和多数C编译器的兼容性,该选项也可以指定为-D

~~~~~~~~~~~~~~ That’s all for now thank you for your reading. ~~~~~~~~~~~~~~