跳转至

什么是汇编语言?

汇编语言是一种低级编程语言,它直接对应于计算机的机器语言。汇编语言使用助记符来表示机器指令,每个助记符通常对应一条机器指令。与高级语言相比,汇编语言更加接近计算机硬件,因此程序运行速度更快、效率更高。

1. 最简单的汇编程序

vim hello.s
复制以下内容到文件
#PURPOSE: Simple program that exits and returns a
#     status code back to the Linux kernel
#
#INPUT:   none
#
#OUTPUT:  returns a status code. This can be viewed
#     by typing
#
#     echo $?
#
#     after running the program
#
#VARIABLES:
#     %eax holds the system call number
#     %ebx holds the return status
#
 .section .data

 .section .text
 .globl _start
_start:
 movl $1, %eax  # this is the linux kernel command
        # number (system call) for exiting
        # a program

 movl $4, %ebx  # this is the status number we will
        # return to the operating system.
        # Change this around and it will
        # return different things to
        # echo $?

 int $0x80  # this wakes up the kernel to run
        # the exit command

汇编文件通常以.s为文件后缀,用汇编器(Assembler)as把汇编程序中的助记符翻译成机器指令,生成目标文件hello.o

as hello.s -o hello.o

用链接器(Linker,或Link Editor)ld把目标文件hello.o链接成可执行文件hello

ld hello.o -o hello

为什么要链接? - 符号解析

符号是指程序中的函数和变量被赋予了符号名词,而汇编后的目标文件中,这些符号的具体地址未知,因此需要链接器进行遍历所有文件,为每个符号找到它在内存中的确切地址。然后,链接器会将这些地址更新到目标文件中相应的指令和数据中。 - 地址重定位 汇编语言程序中的许多指令和数据都包含内存地址。例如,一个函数调用指令可能包含被调用函数的地址。然而,在汇编后的目标文件中,这些地址通常是相对地址,即相对于指令本身地址的偏移量。链接器会根据目标文件最终在内存中的加载位置,将这些相对地址转换为绝对地址。 - 将一/多个文件合并为一个可执行文件

#执行,执行的功能是退出,退出状态是4
./hello

#用特殊变量`$?`得到上一条命令的退出状态
echo $?
4

#相当于在C程序的`main`函数中`return 4` 

汇编程序中以.开头的名称并不是指令的助记符,不会被翻译成机器指令,而是给汇编器一些特殊指示,称为汇编指示(Assembler Directive)或伪操作(Pseudo-operation),由于它不是真正的指令所以加个“伪”字。

hello.s代码主要分为两个部分:数据段 .data 和文本段 .text - 数据段 .data: 该段没有定义任何数据,只是用于声明全局符号 _start

数据段用于存储程序中已初始化的全局变量和静态变量,是可读可写的。int global_variable = 10; - 文本段 .text: 该段包含程序的正文,即汇编指令。 文本段用于存储程序的代码,即程序的可执行指令,是只读和可执行的。比如C语言的printf()语句

2. x86的寄存器