gdb调试汇编
首先是函数传参,
先说下edi esi edx ecx 和 rdi rsi rdx rcx的关系
正常的centos x86的架构,
函数的前6个参数一般是用这几个寄存器存储的 edi esi edx ecx r8 r9(也可能是rdi rsi rdx rcx r8 r9),从左依次往右
第7个参数以后,就放在栈上了,也就是通过栈传递,每个参数占用 8 字节(即使类型小于 8 字节,也会对齐填充),从右向左依次压栈(即最右边的参数先入栈,位于低地址)。
计算的时候,第 7 个参数在栈上的位置:%rsp + 8
(调用后的栈顶 + 8 字节,跳过返回地址),第 8 个参数在栈上的位置:%rsp + 16
(依次递增 8 字节)。
下面是测试的demo
下面是使用实例,断点为SITcpServer::is_long_time_call(HString const&, bool)
按照汇编,第一个参数为this指针,第二个就是HString, 第三个是bool
首先我们尝试打印HString
先查看汇编地址
0x7f24af2878b0 是一个 64 位十六进制数地址格式,我们将其转换16进制地址
HString内部有一个指针,占据8为,而且内部数据是宽字符,我们打印的时候需要注意
-------------------------------------------错误示范开始---------------------------------------------------
一定要把0x7f24af2878b0+8用括号括起来,否则结果不同
!!!!注意,因为没括起来,得到的结果是错误的
-------------------------------------------错误示范结束---------------------------------------------------
尝试打印Hstring中宽字符的值
下面的方式也可以打印,但是我不知道为什么
我们再来尝试打印bool
因为bool比较简单,就1和0,我们直接可以认出来
返回值使用的寄存器如下
整数,指针 EAX
浮点数(float/double) ST0(FPU 栈顶)
64 位整数(long long) EAX(低 32 位) + EDX(高 32 位)
结构体或大对象 隐式指针(调用者栈空间)
SIMD 类型(SSE) XMM0(若启用 SSE 优化)
其他的一些命令
disassemble可以展开断点函数的汇编
disassemble 地址
disassemble 函数声明
disassemble 开始地址, 结束地址
disassemble 地址加字节数
disassemble 函数声明加字节数
disassemble /m 地址或者函数声明 反汇编命令将显示与反汇编指令相对应的源代码行
disassemble /r 地址或者函数声明 显示所有反汇编指令的原始字节值
info r 查看寄存器信息
set disassemble-next-line on 显示下一条要执行的汇编代码
si 执行以下一步汇编
b *main+12 在某处汇编地址断点,只能从函数声明处,通过地址偏移实现。例如
除了disassemble可以展开汇编之外,display,x/i等之类的也可以展开汇编,
display /20i function_name/addr display展开main函数的前20行汇编,函数名和地址都行
比如用x/i展开汇编
x/10i function_name/addr 展开main函数的10行汇编 ,函数名和地址都行