这篇文章介绍了如何使用nasm开始你的汇编之路,测试平台Ubuntu 18.04。
世界上大概没有比写汇编语言更机械性的工作了,如果有,那大概是在期末考试中默写它们。
汇编器是将汇编语言转化为机器码的程序。或许你会以为汇编转化到机器码没什么大不了的,毕竟几乎是一对一的转换。但nasm存在的意义在于它可以很好的适应多种处理器平台,让编写汇编这件事都变得可移植了。
nasm可以在Ubuntu下汇编,使用elf32或者elf64格式(具体取决于你的机器,下同)。在不同的机器下写汇编的影响不是很大,这多亏了nasm所追求的跨平台特性。
在Ubuntu下可以通过apt安装
sudo apt install nasm
安装后就可以对文件进行汇编了,以helloworld.asm为例
hello.asm 32-bit
section .text ;section declaration
;we must export the entry point to the ELF linker or
global _start ;loader. They conventionally recognize _start as their
;entry point. Use ld -e foo to override the default.
_start:
;write our string to stdout
mov edx,len ;third argument: message length
mov ecx,msg ;second argument: pointer to message to write
mov ebx,1 ;first argument: file handle (stdout)
mov eax,4 ;system call number (sys_write)
int 0x80 ;call kernel
;and exit
mov ebx,0 ;first syscall argument: exit code
mov eax,1 ;system call number (sys_exit)
int 0x80 ;call kernel
section .data ;section declaration
msg db "Hello, world!",0xa ;our dear string
len equ $ - msg ;length of our dear string
在Ubuntu下
nasm -f elf32 hello.asm
ld -m elf_i386 -s -o hello hello.o
然后运行./hello
即可输出"Hello, world!"。
简单解释一下,hell.o是目标文件,它几乎就是可执行文件,它离我们完整的可执行程序只差了链接这一步。
而ld正是GUN自带的链接工具,可以将目标文件链接起来,我们这里因为只有一个文件因此不需要额外的指令。
这里要注意一下我们是用的32位模式。
复习一下,我们将一个写好的C程序转化为一个可以在Unix内核机器上执行的文件,需要经历下面四个步骤:
因为我们直接在写汇编程序,当然就不需要第一步和第二步了。
说到GUN,不得不提今天的另一个主角,那就是GDB,GNU symbolic debugger,它是一个在Unix内核中广受好评的调试工具。
nasm作为一个汇编器,定义了自己独特的汇编语言,具体的文档在它的官网可以找到
总的来说,它和我们平时使用的汇编语言(我是指C和C++编译后的那个)差不多。当然它也有一些比较独特的风格,比如
然后就是常见的汇编指令,分支跳转、移位、加减乘除什么的。
简单说这些,其实想写好汇编还是要深入的了解计算机内部的结构,以及一些约定俗成的机制,例如程序之间传递参数的方式。