引言
什么是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目标文件格式(obj
、win32
和win64
),会将你的源文件名的.asm
扩展名(或其他扩展名——NASM对此无限制)换成.obj
。对于Unix目标文件格式(aout
、as86
、coff
、elf32
、elf64
、elfx32
、ieee
、macho32
与macho64
),会换成.o
。对于dbg
、ith
和srec
,会分别使用.dbg
、.ith
和.srec
。对于bin
格式只是去掉扩展名,例如myfile.asm
生成myfile
文件。
如果输出文件已存在,NASM
会将其覆盖。除非其名称与输入文件相同,这种情况将会给出警告并使用nasm.out
作为输出文件名。
如果不接受该默认行为,NASM提供了-o
命令行选项,用于指定自己想要的的输出文件名。可以在-o
选项后加上自己想要的输出文件名,中间有无空格均可,例如:1
2nasm -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 [+|-]标志...
d
和m
标志,禁用s
标志:出于向前兼容性考虑,未定义的标志将忽略。因此,指定NASM新版本引入的标志并不会影响旧版本。列表文件选项标志始终为单字母数字字符,区分大小写。1
%pragma list options +dm -s
-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
。