跳至內容

Netwide Assembler

本頁使用了標題或全文手工轉換
維基百科,自由的百科全書
Netwide Assembler
NASM logo
原作者Simon Tatham, Julian Hall
開發者H. Peter Anvin, et al.
目前版本2.15.05(2020年8月28日,​4年前​(2020-08-28
源碼儲存庫 編輯維基數據連結
作業系統Windows, Unix-like, OS/2, MS-DOS
語言English
類型x86 assembler
許可協定BSD 2-clause
網站www.nasm.us

Netwide Assembler (簡稱 NASM)是一款基於英特爾 x86 架構的組譯與反組譯工具。它可以用來編寫 16位元32位元IA-32)和 64位元x86-64)的程式。 NASM 被認為是 Linux 平台上最受歡迎的組譯工具之一。[1]

NASM 最初是在朱利安·霍爾的協助下由西蒙·泰瑟姆開發的。 截至2016年 (2016-Missing required parameter 1=month!),它被一個由 H.Peter Anvin 領導的小團隊所維護。[2] 它是一款基於簡化版(二句版)BSD授權條款開放原始碼軟件[3]

功能

NASM 可以輸出包括 COFF、OMF、a.out、可執行與可連結格式(ELF)、Mach-O 和二進制檔案(.bin,二進制磁碟映像,用於編譯作業系統)等多種二進制格式,而地址無關程式碼僅支援 ELF 目的檔案。 NASM 也有自己的二進位格式,稱為 RDOFF。[4]

輸出格式的廣泛性允許將程式重新導向到任何 x86 作業系統(OS)。 此外,NASM 可以建立浮動二進制檔案,它可用於寫入引導載入程式、唯讀記憶體(ROM)映像以及作業系統開發的各個方面。 NASM 可以作為交叉組譯程式(如 PowerPC 和 SPARC)在非 x86 平台上執行,儘管它不能生成這些機器可用的程式。

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

用於各種作業系統的範例程式

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

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 下的範例:

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 下的等價程式:

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 位元程式,用於輸入按鍵並將其顯示在螢幕上:

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月。[6]

2007年11月28日,2.00版本發佈,增加對 x86-64 擴充的支援。 開發版本不再上載到 SourceForge.net;相反,它們會被檢入到專案自己的 Git 儲存庫中,而其二進制程式的快照可在專案官網上找到。

一個用於 NASM 文件的搜尋引擎也已可用。[7]

截至 2.07 版本,NASM 在簡化 BSD 許可證(二句版)下發佈。

RDOFF

RDOFF
開發者Julian Hall
格式類型Object file format
作為容器Object code

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

直到1996年10月發佈 0.90 版,NASM 才支援只輸出浮動格式的可執行檔案(例如 DOS 的 COM 檔案)。在版本 0.90 中,Simon Tatham 增加了對一個目標文件輸出介面的支援,並且只支援用於 16 位元程式碼的 DOS 的 .OBJ 檔案。[9]

NASM 因此缺少一個 32 位元的目的檔格式。 為了解決這個問題,作為學習目的檔案介面的練習,開發人員朱利安·霍爾將第一版 RDOFF 發佈於 NASM 0.91 版本。

自從這個初始版本以來,對 RDOFF 格式進行了一次重大更新,它在每個標題記錄上增加了一個記錄長度指示器,[10] 允許程式跳過它們無法辨識格式的記錄,並支援多個區段;RDOFF1 僅支援三個區段:text,data和 bss(包含未初始化的數據)。

另請參見

參考文獻

  1. ^ Ram Narayan. Linux assemblers: A comparison of GAS and NASM. [2018-03-29]. (原始內容存檔於2013-10-03). two of the most popular assemblers for Linux, GNU Assembler (GAS) and Netwide Assembler (NASM) 
  2. ^ The Netwide Assembler. [2008-06-27]. (原始內容存檔於2008-07-24). 
  3. ^ NASM Version History. [2009-07-19]. (原始內容存檔於2009-07-04). 
  4. ^ NASM Manual. [2009-08-15]. (原始內容存檔於2009-02-23). 
  5. ^ Randall Hyde. NASM: The Netwide Assembler. [2008-06-27]. (原始內容存檔於2010-09-12). 
  6. ^ NASM Version History. [2017-04-23]. (原始內容存檔於2017-05-01). 
  7. ^ NASM Doc Search Engine. [2009-09-14]. (原始內容存檔於2010-01-23). 
  8. ^ NASM Manual Ch. 6. [2008-06-27]. (原始內容存檔於2008-07-24). 
  9. ^ NASM CVS. 2008-06-08 [2008-06-27]. (原始內容存檔於2022-04-07). 
  10. ^ V1-V2.txt. 2002-12-04 [2008-06-27]. (原始內容存檔於2022-04-07). 

進一步閱讀

外部連結