汇编
大约 4 分钟
汇编
流程
.file "example.c" #定义文件名称
.text #定义文件类型
.globl add_a_and_b #定义变量名称为全局变量名称
.type add_a_and_b, @function #定义类型为函数
add_a_and_b: #定义
.LFB0: #局部函数块的开始.lfb[x] 这里[x]指代的是区域编号
.cfi_startproc #起始调用帧指令
pushq %rbp # pushq为指令 %rbp为寄存器 目的是将寄存器压入栈中
.cfi_def_cfa_offset 16 #定义当前堆栈指针
.cfi_offset 6, -16 #定义堆栈偏移量 目标是6号寄存器空间 -16是堆栈指针
movq %rsp, %rbp #将%rbq寄存器移动到%rsp中
.cfi_def_cfa_register 6 #定义当前指针使用的寄存器 在这里6号寄存器指的是%rbp
movl %edi, -4(%rbp) #将%edi寄存器的值移动到%rbp偏移4个字节的内存地址位置
movl %esi, -8(%rbp) #将%esi寄存器的值移动到%rbp偏移8个字节的内存地址位置
movl -4(%rbp), %edx #将%rbp寄存器偏移4个字节的值移动到%edx的内存地址位置
movl -8(%rbp), %eax #将%rbp寄存器偏移8个字节的值移动到%eax的内存地址位置
addl %edx, %eax #把两个寄存器的值相加
popq %rbp #rbq退出堆栈
.cfi_def_cfa 7, 8 #在当前堆栈定义七号寄存器,8个字节的偏移量
ret #函数返回指令
.cfi_endproc #标记函数结束
.LFE0: #定义局部函数块结束
.size add_a_and_b, .-add_a_and_b #指定函数大小 首先定义符号为函数名,其次返回当前位置,那么就可以得到函数大小了
.globl main #声明全局变量 这里则是声明入口变量
.type main, @function #将main定义为函数
main:
.LFB1:#1号局部函数域
.cfi_star tproc #声明堆栈开始
pushq %rbp #将寄存器%rbp压入堆栈中
.cfi_def_cfa_offset 16 #定义堆栈大小为16个字节
.cfi_offset 6, -16 #定义偏移量
movq %rsp, %rbp #同上
.cfi_def_cfa_register 6 #注册6号寄存器至堆栈中
movl $3, %esi #将立即数3添加到%esi
movl $2, %edi #将立即数2添加到%edi中
call add_a_and_b #函数调用
popq %rbp #%rbp退出函数
.cfi_def_cfa 7, 8 #定义7号寄存器,8个字节的偏移量
ret #函数变量
.cfi_endproc #函数结束
.LFE1:#1号函数域结束
.size main, .-main #定义函数大小
.ident "GCC: (Debian 10.2.1-6) 10.2.1 20210110" #定义程序元信息
.section .note.GNU-stack,"",@progbits #定义新的代码段或数据段
gpt解释:
这段代码的大致结构是:
定义文件信息(
.file和.ident)定义代码段(
.text)声明全局变量
add_a_and_b为函数类型定义函数
add_a_and_b定义局部函数块
.LFB0一系列汇编指令用于设置堆栈帧和执行函数的操作
.cfi_endproc标记函数结束使用
.size定义函数大小声明全局变量
main为函数类型定义函数
main定义局部函数块
.LFB1一系列汇编指令用于设置堆栈帧、调用函数和执行函数的操作
.cfi_endproc标记函数结束使用
.size定义函数大小定义程序元信息
定义新的代码段(
.note.GNU-stack)
根据上下文,第 34 行和第 35 行的代码针对立即数的作用如下:
34 行:movl $3, %esi 这一行的作用是将立即数值 3 移动到寄存器 %esi 中。在 x86 汇编中,$ 符号用于表示立即数(即直接的数值),这表示不是从内存中读取数据,而是直接将数值加载到寄存器。因此,movl $3, %esi 将数值 3 直接加载到 %esi 寄存器,这里可能表示一个参数或临时变量的赋值。
35 行:movl $2, %edi 这一行的作用是将立即数值 2 移动到寄存器 %edi 中。同样,$ 符号表示立即数,这里将数值 2 直接加载到 %edi 寄存器,可能表示另一个参数或临时变量的赋值。 综合来看,这两行指令在上下文中可能是为了准备函数 add_a_and_b 的参数。它们将数值 3 和 2 分别加载到 %esi 和 %edi 寄存器,以便在后续的函数调用中使用。根据上下文,这可能是将这两个值传递给 add_a_and_b 函数进行计算。
总结
- 定义文件信息和元信息。
- 定义代码段和全局变量。
- 定义函数
add_a_and_b:- 设置堆栈帧并保存寄存器。
- 计算两个参数之和。
- 恢复堆栈和寄存器状态。
- 返回结果。
- 定义函数
main:- 设置堆栈帧并保存寄存器。
- 设置函数参数。
- 调用函数
add_a_and_b。 - 恢复堆栈和寄存器状态。
- 返回。
- 结束程序。