先来一段能够输出“Hello, World”的汇编代码:
section .datastringShowing db "Hello, World",10,0stringShowingLength equ 13
section .bss
section .textglobal mainmain:push rbpmov rbp,rspmov rax,1mov rdi,1mov rsi,stringShowingmov rdx,stringShowingLengthsyscallmov rsp,rbppop rbpmov rax,60mov rdi,0syscall

nasm -f elf64 -g -F dwarf helloworld.asm -o helloworld.o使用64位汇编器进行汇编。
gcc -o helloworld helloworld.o进行链接。
./helloworld进行执行。
下边进行代码的分解:
push rbp
mov rbp,rsp
这两段代码相当于把父程序调用子程序的栈保存下来,方便再回到父程序。
mov rax,1
寄存器 rax 中存放系统调用号,在其他情况下,返回值也存放在 eax 中。这段汇编代码表明让rax=1,表明会使用write(int fd,char *buf,int n)系统调用,可以看到这个系统调用需要传入3个参数,第一个参数是文件描述符,0表示标准输入,1表示标准输出,2表示标准错误;第2个参数是读入的字符数组;第三个参数是要传输的字节数。
mov rdi,1mov rsi,stringShowingmov rdx,stringShowingLength
往write(int fd,char *buf,int n)系统调用传递参数,当系统调用参数小于等于6个时,参数则必须按顺序放到寄存器rdi,rsi,rdx,r10,r8,r9中。当系统调用参数大于6个时,全部参数应该依次放在一块连续的内存区域里,同时在寄存器rbx中保存指向该内存区域的指针。可以看到在这段代码中rdi放入的是文件描述符——1,代表标准输出,rsi中放入的是stringShowing这个字符串的首字母地址,rdx放入的是stringShowing的长度stringShowingLength,为13。
syscall
就是真正系统调用。
mov rsp,rbp
pop rbp
把堆栈还原。
mov rax,60
mov rdi,0
syscall
退出程序,返回给操作系统0。
此文章为3月Day 7学习笔记,内容来源于极客时间《操作系统实战 45 讲》。
下一篇:【Python安装配置教程】