跳转到内容

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 仅支持三個區段:文本,数据和 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). 

进一步阅读

[编辑]

外部链接

[编辑]