Netwide Assembler
Netwide Assembler (簡稱 NASM)是一款基於英特爾 x86 架構的組譯與反組譯工具。它可以用來編寫 16位元、32位元(IA-32)和 64位元(x86-64)的程式。 NASM 被認為是 Linux 平台上最受歡迎的組譯工具之一。[1]
原作者 | 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 |
網站 | www |
NASM 最初是在朱利安·霍爾的協助下由西蒙·泰瑟姆開發的。 截至2016年[update],它被一個由 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
開發者 | 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(包含未初始化的數據)。
另請參見
參考文獻
- ^ 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)
- ^ The Netwide Assembler. [2008-06-27]. (原始內容存檔於2008-07-24).
- ^ NASM Version History. [2009-07-19]. (原始內容存檔於2009-07-04).
- ^ NASM Manual. [2009-08-15]. (原始內容存檔於2009-02-23).
- ^ Randall Hyde. NASM: The Netwide Assembler. [2008-06-27]. (原始內容存檔於2010-09-12).
- ^ NASM Version History. [2017-04-23]. (原始內容存檔於2017-05-01).
- ^ NASM Doc Search Engine. [2009-09-14]. (原始內容存檔於2010-01-23).
- ^ NASM Manual Ch. 6. [2008-06-27]. (原始內容存檔於2008-07-24).
- ^ NASM CVS. 2008-06-08 [2008-06-27]. (原始內容存檔於2022-04-07).
- ^ V1-V2.txt. 2002-12-04 [2008-06-27]. (原始內容存檔於2022-04-07).
進一步閱讀
- Jeff Duntemann. Assembly Language Step by Step. J Wiley and Sons. 2000. ISBN 0-471-37523-3.
外部連結
- Special edition for Win32 and BeOS.
- A comparison of GAS and NASM(頁面存檔備份,存於互聯網檔案館) at IBM
- Freecode上的Netwide Assembler: a converter between the source format of the assemblers NASM and GAS