一、进入debug模式
常见指令
-a 1000:0
用A命令向从1000:0开始的内存单元中写入指令
-t
使用t命令执行CS:IP指向的指令
-u 1000:0
查看从1000:0开始的内存单元中的机器指令和它们所对应的汇编指令
-e
用E命令向内存中写入字符串
-d 1000:0 f
用D命令查看内存1000:0到f处的内容
-r cs
使用R命令查看CPU中各个寄存器中的内容
二、x86_64汇编和8086汇编区别
备注:目前大多都是8086汇编资料,x86汇编方向暂时不清楚
- 在8086汇编中,源操作数(source)在左边,目的操作数(destination)在右边;而在x86汇编中则反之
- MOV AX, DS;8086汇编,方向为“AX ⬅ DS”
- MOV AX, DS;x86汇编,方向为“AX ➡ DS
这种差异是由于x86汇编语法的设计者考虑到人类书写习惯,将源操作数放在右边,从而最大限度地提高代码的可读性。
三、寄存器和栈
- 寄存器是CPU里的组件,内存是挂在CPU外面的数据总线上的。
- %esp(extended stack pointer)是栈指针寄存器,该指针永远指向系统栈最上面一个栈帧的栈顶。
- %ebp(extended base pointer)是基址指针寄存器,该指针永远指向系统栈最上面一个栈帧的底部。
- pushq %rbp 相当于先将 %rbp 压栈再将栈顶位置向低地址移动 8B,即 subq $8, %rsp。
四、汇编代码案例及其分析
endbr64
pushq %rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
movq %rsp, %rbp
.cfi_def_cfa_register 6
subq $32, %rsp
movl %edi, -20(%rbp)
movq %rsi, -32(%rbp)
movq %fs:40, %rax
movq %rax, -8(%rbp)
xorl %eax, %eax
leaq -12(%rbp), %rax
movq %rax, %rdx
leaq func(%rip), %rsi
leaq .LC0(%rip), %rdi
movl $0, %eax
call printf@PLT
movl $0, %eax
movq -8(%rbp), %rcx
xorq %fs:40, %rcx
这是一段x86_64汇编代码,下面是各指令的数据移动方向和意义:
endbr64
- 数据移动方向:无
- 指令意义:该指令用于在执行函数调用时保护返回地址,属于系统级指令。
pushq %rbp
- 数据移动方向:从%rbp寄存器到栈中
- 指令意义:该指令将当前函数栈帧的基址指针%rbp压入栈中,并且更新栈顶指针%rsp。
.cfi_def_cfa_offset 16
- 数据移动方向:无
- 指令意义:该指令定义当前函数栈帧相对于%rsp的偏移量为16字节,用于调试信息。
.cfi_offset 6, -16
- 数据移动方向:无
- 指令意义:该指令定义当前函数中第6个寄存器(即%rbp)在调用前和调用后的状态进行记录,用于调试信息。
movq %rsp, %rbp
- 数据移动方向:从%rsp寄存器到%rbp寄存器
- 指令意义:该指令将当前的栈指针%rsp的值复制到%rbp寄存器中,以便保存当前函数的栈帧指针。
.cfi_def_cfa_register 6
- 数据移动方向:无
- 指令意义:该指令定义当前函数栈帧的基址寄存器为%rbp,用于调试信息。
subq $32, %rsp
- 数据移动方向:从%rsp寄存器到%rsp寄存器
- 指令意义:该指令将栈顶指针%rsp下移32字节,以便为局部变量和临时值留出空间。
movl %edi, -20(%rbp)
- 数据移动方向:从%edi寄存器到栈中
- 指令意义:该指令将第一个参数(整型)复制到相对于%rbp偏移量为-20字节的栈位置中。
movq %rsi, -32(%rbp)
- 数据移动方向:从%rsi寄存器到栈中
- 指令意义:该指令将第二个参数(指针类型)复制到相对于%rbp偏移量为-32字节的栈位置中。
movq %fs:40, %rax
- 数据移动方向:从%fs段寄存器到%rax寄存器
- 指令意义:该指令从%fs寄存器指示的线程本地存储中读取地址偏移量为40字节的位置,并将其复制到%rax寄存器中。
movq %rax, -8(%rbp)
- 数据移动方向:从%rax寄存器到栈中
- 指令意义:该指令将上一条指令读取的线程本地存储地址保存到相对于%rbp偏移量为-8字节的栈位置中。
xorl %eax, %eax
- 数据移动方向:无
- 指令意义:该指令将%eax寄存器中的值与自身进行异或操作,相当于将%eax清零。
leaq -12(%rbp), %rax
- 数据移动方向:从栈中到%rax寄存器
- 指令意义:该指令计算相对于