nasm初步使用

  • Post author:
  • Post category:其他




nasm初步使用

这篇文章介绍了如何使用nasm开始你的汇编之路,测试平台Ubuntu 18.04。

世界上大概没有比写汇编语言更机械性的工作了,如果有,那大概是在期末考试中默写它们。



汇编器

汇编器是将汇编语言转化为机器码的程序。或许你会以为汇编转化到机器码没什么大不了的,毕竟几乎是一对一的转换。但nasm存在的意义在于它可以很好的适应多种处理器平台,让编写汇编这件事都变得可移植了。

nasm可以在Ubuntu下汇编,使用elf32或者elf64格式(具体取决于你的机器,下同)。在不同的机器下写汇编的影响不是很大,这多亏了nasm所追求的跨平台特性。



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内核机器上执行的文件,需要经历下面四个步骤:

  • 预处理:处理C中的预处理命令,也就是#开头的那些,默认的生成文件格式为.i
  • 编译:将C程序编译为汇编语言, 默认的生成文件格式为.s,这里的.s和我们的.asm没什么区别
  • 汇编:将汇编语言转化为机器码,默认的生成文件格式为.o
  • 链接:链接动态库和静态库

因为我们直接在写汇编程序,当然就不需要第一步和第二步了。

说到GUN,不得不提今天的另一个主角,那就是GDB,GNU symbolic debugger,它是一个在Unix内核中广受好评的调试工具。



NASM的使用方法

nasm作为一个汇编器,定义了自己独特的汇编语言,具体的文档在它的官网可以找到

总的来说,它和我们平时使用的汇编语言(我是指C和C++编译后的那个)差不多。当然它也有一些比较独特的风格,比如

  • 使用[]来表示你的操作数是一个引用,而不是一个具体的指,这会让nasm在汇编你的代码的时候去内存找到相应的值。
  • 将文件分成三部分,.text,.data和.bss,分别表示代码, 常量和变量。
  • 伪指令:

    • 使用RESx和Dx灵活的声明常量和变量。
    • 使用times重复声明。
  • 还有一些有用的预处理指令:
  • 使用宏%macro定义自己的指令。
  • 使用%ifdef自定义代码段,结合Makefile生成不同版本的文件。

然后就是常见的汇编指令,分支跳转、移位、加减乘除什么的。

简单说这些,其实想写好汇编还是要深入的了解计算机内部的结构,以及一些约定俗成的机制,例如程序之间传递参数的方式。



版权声明:本文为qq_43325061原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。