简介
Nasm编译器是一款x86、x86_64的汇编器,使用Intel汇编格式。模块化设计、可移植。
官网地址
安装
Ubuntu系统下可以使用apt show nasm
来查看nasm
的版本
root@000d3fada0b3:~/asm# apt show nasm
Package: nasm
Version: 2.13.02-0.1
Priority: optional
Section: universe/devel
Origin: Ubuntu
Maintainer: Ubuntu Developers <ubuntu-devel-discuss@lists.ubuntu.com>
Original-Maintainer: Anibal Monsalve Salazar <anibal@debian.org>
Bugs: https://bugs.launchpad.net/ubuntu/+filebug
Installed-Size: 2831 kB
Depends: dpkg (>= 1.15.4) | install-info, libc6 (>= 2.14)
Homepage: http://www.nasm.us/
Download-Size: 359 kB
APT-Sources: http://archive.ubuntu.com/ubuntu bionic/universe amd64 Packages
Description: General-purpose x86 assembler
可以使用sudo apt-get install nasm
来下载
输入nasm -v
查看是否安装成功。
使用方法
- -f 格式化-o 输出文件名
- -O : 编译器优化开关,-O0表示关闭。默认为开启
- -E : 预处理
- -g : 生成调试信息
- -F : 调试信息的格式
查看Nasm支持的格式
nasm -hf
可以查看到支持的格式
valid output formats for -f are (`*' denotes default):
* bin flat-form binary files (e.g. DOS .COM, .SYS)
ith Intel hex
srec Motorola S-records
aout Linux a.out object files
aoutb NetBSD/FreeBSD a.out object files
coff COFF (i386) object files (e.g. DJGPP for DOS)
elf32 ELF32 (i386) object files (e.g. Linux)
elf64 ELF64 (x86_64) object files (e.g. Linux)
elfx32 ELFX32 (x86_64) object files (e.g. Linux)
as86 Linux as86 (bin86 version 0.3) object files
obj MS-DOS 16-bit/32-bit OMF object files
win32 Microsoft Win32 (i386) object files
win64 Microsoft Win64 (x86-64) object files
rdf Relocatable Dynamic Object File Format v2.0
ieee IEEE-695 (LADsoft variant) object file format
macho32 NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X (i386) object files
macho64 NeXTstep/OpenStep/Rhapsody/Darwin/MacOS X (x86_64) object files
dbg Trace of all info passed to output stage
elf ELF (short name for ELF32)
macho MACHO (short name for MACHO32)
win WIN (short name for WIN32)
实际操作
创建文件
我们创建一个hello.s
文件,将下面的汇编代码粘贴到文件内。
global _start
section .data
hello : db `hello, world!\n`
section .text
_start:
mov rax, 1 ; system call number should be stored in rax
mov rdi, 1 ; argument #1 in rdi: where to write (descriptor)?
mov rsi, hello ; argument #2 in rsi: where does the string start?
mov rdx, 14 ; argument #3 in rdx: how many bytes to write?
syscall ; this instruction invokes a system call
mov rax, 60 ; 'exit' syscall number
xor rdi, rdi ;
syscall
汇编命令
将汇编代码汇编成目标文件(使用.s文件 生成.o文件 )
nasm -g -f elf64 -o hello.o hello.s
-g 生成debuging信息
-f 指定输出格式
-o 输出文件的名字
链接命令
使用目标文件生成可执行文件
ld -o hello hello.o
执行
root@000d3fada0b3:~/asm# ./hello
hello, world!
总结
生成的hello.o为什么不能执行?
我们反汇编一下,看看程序的内容
root@000d3fada0b3:~/asm# objdump -d -M intel hello.o
hello.o: file format elf64-x86-64
Disassembly of section .text:
0000000000000000 <_start>:
0: b8 01 00 00 00 mov eax,0x1
5: bf 01 00 00 00 mov edi,0x1
a: 48 be 00 00 00 00 00 movabs rsi,0x0
11: 00 00 00
14: ba 0e 00 00 00 mov edx,0xe
19: 0f 05 syscall
1b: b8 3c 00 00 00 mov eax,0x3c
20: 48 31 ff xor rdi,rdi
23: 0f 05 syscall
我们可以观察到,没有给程序的入口分配地址。
我们再观察一下可执行文件hello
root@000d3fada0b3:~/asm# objdump -d -M intel hello
hello: file format elf64-x86-64
Disassembly of section .text:
00000000004000b0 <_start>:
4000b0: b8 01 00 00 00 mov eax,0x1
4000b5: bf 01 00 00 00 mov edi,0x1
4000ba: 48 be d8 00 60 00 00 movabs rsi,0x6000d8
4000c1: 00 00 00
4000c4: ba 0e 00 00 00 mov edx,0xe
4000c9: 0f 05 syscall
4000cb: b8 3c 00 00 00 mov eax,0x3c
4000d0: 48 31 ff xor rdi,rdi
4000d3: 0f 05 syscall
在这里可以看到程序的入口时分配了地址的。
网友评论