Netwide Assembler

Netwide Assembler （簡稱 NASM）是一款基於英特爾 x86 架構的彙編與反彙編工具。它可以用來編寫 16位、32位（IA-32）和 64位（x86-64）的程序。NASM 被認為是 Linux 平台上最受歡迎的彙編工具之一。

NASM 最初是在朱利安·霍爾的協助下由西蒙·泰瑟姆開發的。它被一個由 H.Peter Anvin 領導的小團隊所維護。它是一款基於簡化版（二句版）BSD許可證的開放原始碼軟體。

## 功能

NASM 可以輸出包括 COFF、OMF、a.out、可執行與可連結格式（ELF）、Mach-O 和二進位文件（.bin，二進位磁碟映像，用於編譯作業系統）等多種二進位格式，而地址無關代碼僅支持 ELF 對象文件。NASM 也有自己的二進位格式，稱為 RDOFF。

輸出格式的廣泛性允許將程序重定向到任何 x86 作業系統（OS）。此外，NASM 可以創建浮動二進位文件，它可用於寫入引導加載程序、只讀存儲器（ROM）映像以及作業系統開發的各個方面。NASM 可以作為交叉彙編程序（如 PowerPC 和 SPARC）在非 x86 平台上運行，儘管它不能生成這些機器可用的程序。

NASM 使用英特爾組合語言語法的變體而不是 AT&T 語法（GNU 彙編器採用的語法）。它還避免了 MASM 和兼容彙編器使用的自動生成區段覆蓋（以及相關的 ASSUME 指令）等功能。

## 用於各種作業系統的示例程序

這是一個 DOS 作業系統下的 "Hello world!" 程序：

```nasm
section .text
org 0x100
	mov	ah, 0x9
	mov	dx, hello
	int	0x21

	mov	ax, 0x4c00
	int	0x21

section .data
hello:	db 'Hello, world!', 13, 10, '$'
```

一個類似程序在 Microsoft Windows 下的示例：

```nasm
global _main
extern _MessageBoxA@16
extern _ExitProcess@4

section code use32 class=code
_main:
	push	dword 0      ; UINT uType = MB_OK
	push	dword title  ; LPCSTR lpCaption
	push	dword banner ; LPCSTR lpText
	push	dword 0      ; HWND hWnd = NULL
	call	_MessageBoxA@16

	push	dword 0      ; UINT uExitCode
	call	_ExitProcess@4

section data use32 class=data
	banner:	db 'Hello, world!', 0
	title:	db 'Hello', 0
```

一段 Linux 下的等價程序：

```nasm
global _start

section .text
_start:
	mov	eax, 4 ; write
	mov	ebx, 1 ; stdout
	mov	ecx, msg
	mov	edx, msg.len
	int	0x80   ; write(stdout, msg, strlen(msg));

	mov	eax, 1 ; exit
	mov	ebx, 0
	int	0x80   ; exit(0)

section .data
msg:	db	"Hello, world!", 10
.len:	equ	$ - msg
```

下面是一個用於蘋果 macOS（原為 OS X）的 64 位元程序，用於輸入按鍵並將其顯示在螢幕上：

```nasm
global _start

section .data

	query_string:		db	"Enter a character:  "
	query_string_len:	equ	$ - query_string
	out_string:			db	"You have input:  "
	out_string_len:		equ	$ - out_string

section .bss

	in_char:			resw 4

section .text

_start:

	mov	rax, 0x2000004	 	; put the write-system-call-code into register rax
	mov	rdi, 1				; tell kernel to use stdout
	mov	rsi, query_string	; rsi is where the kernel expects to find the address of the message
	mov	rdx, query_string_len	; and rdx is where the kernel expects to find the length of the message 
	syscall

	; read in the character
	mov	rax, 0x2000003		; read system call
	mov	rdi, 0				; stdin
	mov	rsi, in_char		; address for storage, declared in section .bss
	mov	rdx, 2				; get 2 bytes from the kernel's buffer (one for the carriage return)
	syscall

	; show user the output
	mov	rax, 0x2000004		; write system call
	mov	rdi, 1				; stdout
	mov	rsi, out_string
	mov	rdx, out_string_len
	syscall

	mov	rax, 0x2000004		; write system call
	mov	rdi, 1				; stdout
	mov	rsi, in_char
	mov	rdx, 2				; the second byte is to apply the carriage return expected in the string
	syscall

	; exit system call
	mov	rax, 0x2000001		; exit system call
        xor     rdi, rdi
	syscall
```

## 連結

NASM 主要輸出目標文件（擴展名一般為 .obj），這些目標文件通常不能自行執行。唯一的例外是浮動二進位文件（例如 .COM），它們在現代使用中固有地受到限制。要將目標文件轉換為可執行程序，必須使用適當的連結程序，例如用於 Windows 的 Visual Studio「LINK」實用程序或用於類 Unix 系統的 ld。

## 發展

第一版（版本號0.90）發布於1996年10月。

2007年11月28日，2.00版本發布，增加對 x86-64 擴展的支持。開發版本不再上傳到 SourceForge.net；相反，它們會被檢入到項目自己的 Git 存儲庫中，而其二進位程序的快照可在項目官網上找到。

一個用於 NASM 文檔的搜尋引擎也已可用。

截至 2.07 版本，NASM 在簡化 BSD 許可證（二句版）下發布。

## RDOFF

開發人員使用可重定位的動態對象文件格式（RDOFF）來測試 NASM 的目標文件輸出能力的完整性。它很大程度上基於 NASM 的內部結構，主要由一個頭部組成，頭部包含輸出驅動程序函數調用的序列化，後跟包含可執行代碼或數據的部分數組。NASM 發行版中包含了使用該格式的工具，包括連結程序 (linker) 和加載程序 (loader)。

直到1996年10月發布 0.90 版，NASM 才支持只輸出浮動格式的可執行文件（例如 DOS 的 COM 文件）。在版本 0.90 中，Simon Tatham 增加了對一個目標文件輸出接口的支持，並且只支持用於 16 位元代碼的 DOS 的 .OBJ 文件。

NASM 因此缺少一個 32 位元的目的檔格式。為了解決這個問題，作為學習對象文件接口的練習，開發人員朱利安·霍爾將第一版 RDOFF 發布於 NASM 0.91 版本。

自從這個初始版本以來，對 RDOFF 格式進行了一次重大更新，它在每個標題記錄上增加了一個記錄長度指示器，允許程序跳過它們無法識別格式的記錄，並支持多個區段；RDOFF1 僅支持三個區段：text，data和 bss（包含未初始化的數據）。

## 另請參見

- 彙編語言
- 彙編器列表
- Yasm

## 外部連結

- www.nasm.us
- nasm
- Special edition for Win32 and BeOS.
- A comparison of GAS and NASM at IBM
- intel2gas: a converter between the source format of the assemblers NASM and GAS

Freshmeat1intel2gas

## 基本資料

- 作者：Simon Tatham, Julian Hall
- 開發者：H. Peter Anvin, et al.
- 軟體版本週期：2.15.05
- 軟體版本週期：2020年8月28日
- 作業系統：Windows, Unix-like, OS/2, MS-DOS
- 語言：English
- 類型：x86 assembler
- 許可協議：BSD 2-clause
- 日語原文：RDOFF
- 開發者：Julian Hall
- 格式類型：Object file format
- 作為容器：Object code