20145312 GDB调试汇编堆栈过程分析
20145312 GDB调试汇编堆栈过程分析
参考资料
卢肖明同学的博客:《GDB调试汇编堆栈过程分析》: http://www.cnblogs.com/lxm20145215----/p/5982554.html
分析过程
-
使用
vim example.c
命令编写C程序
-
保存退出后使用
gcc -S example.c
命令生成example.s文件,并使用cat example.s
命令查看汇编文件
-
打开example.s文件进行修改:删去所有
.*
的语句,并保存,再次使用cat example.s
命令查看汇编代码
-
使用
gcc example.c -o example
生成example.o文件,并使用objdump -d example
命令进行反汇编
-
这里出现了一个错误:我先是按照书上的步骤输入
objdump -d example.o
命令进行反汇编,出现错误:objdump:example.o:无此文件
,于是我打开目录文件夹,发现example.o
文件的命名为example
,重新修改命令,成功。 -
使用
gcc - g example.c -o example -m32
指令在64位的机器上产生32位汇编,然后使用gdb example
指令进入gdb调试器
-
进入之后先在main函数处设置一个断点,再run一下,使用
disassemble
指令获取汇编代码,用i(info) r(registers)
指令查看各寄存器的值:
-
使用
display /i $pc
命令,这样在每次执行下一条汇编语句时,都会显示出当前执行的语句。
-
执行call指令将下一条指令的地址入栈
分析如下
- 从main:开始执行,保存%ebp,并设置新的帧指针
pushl %ebp
movl %esp,%ebp
- pushl $8分配4字节的栈空间,并且设置arg1=8,相当于
subl $4,%esp
movl $8,(%esp)
- call调用b,b同样初始化帧指针,分配栈空间
pushl %ebp
movl %esp,%ebp
- pushl 8(%ebp)将%esp中的8存入栈中,相当于
subl $4,%esp
movl 8(%ebp),%eax
- call调用a,a被调用,初始化栈指针,分配栈空间,将 %eax 与立即数 1 相加
addl $1,%eax
分析如下
- 从main:开始执行,保存%ebp,并设置新的帧指针
pushl %ebp
movl %esp,%ebp
- pushl $8分配4字节的栈空间,并且设置arg1=8,相当于
subl $4,%esp
movl $8,(%esp)
- call调用b,b同样初始化帧指针,分配栈空间
pushl %ebp
movl %esp,%ebp
pushl 8(%ebp)将%esp
中的8存入栈中,相当于
subl $4,%esp
movl 8(%ebp),%eax
- call调用a,a被调用,初始化栈指针,分配栈空间将 %eax 与立即数 1 相加
addl $1,%eax
- 在a结束前弹栈
popl %ebp
- ret返回b中call的调用位置
- b也结束,return返回main中call调用的位置
- main继续 %eax 加14的操作
addl $14,%eax
- leave为返回准备栈,相当于%ebp出栈,最后ret结束
popl %ebp
- ret返回b中call的调用位置
- b也结束,return返回main中call调用的位置
- main继续 %eax 加14的操作
addl $14,%eax
- leave为返回准备栈,相当于%ebp出栈,最后ret结束
执行过程中%ebp、%esp、堆栈值的变化
指令 | %esp | %ebp | 堆栈 |
---|---|---|---|
push $0x8 | 0xbffff098 | 0xbffff098 | 0x0 |
call 0x8048401 | 0xbffff094 | 0xbffff098 | 0x8 0x0 |
push %ebp | 0xbffff090 | 0xbffff098 | 0x8048412 0x8 0x0 |
mov %esp,%ebp | 0xbffff08c | 0xbffff098 | 0xffffd068 0x8048412 0x8 0x0 |
mov 0x804a020,%edx | 0xbffff08c | 0xbffff08c | 0xffffd068 0x8048412 0x8 0x0 |
call 0x80483ed | 0xbffff088 | 0xbffff08c | 0xa 0xffffd068 0x8048412 0x8 0x0 |
push %ebp | 0xbffff084 | 0xbffff08c | 0x8048403 0xa 0xffffd068 0x8048412 0x8 0x0 |
mov %esp,%ebp | 0xbffff080 | 0xbffff08c | 0xffffd05c 0x8048403 0xa 0xffffd068 0x8048412 0x8 0x0 |
Pop %ebp | 0xbffff080 | 0xbffff080 | 0xffffd05c 0x8048403 0xa 0xffffd068 0x8048412 0x8 0x0 |
ret | 0xbffff084 | 0xbffff08c | 0x8048403 0xa 0xffffd068 0x8048412 0x8 0x0 |
leave | 0xbffff09c | 0xbffff08c | 0xffffd068 0x8048412 0x8 0x0 |
ret | 0xbffff090 | 0xbffff098 | 0x8048412 0x8 0x0 |
add $0x4,%esp | 0xbffff094 | 0xbffff098 | 0x8 0x0 |
mov $0x3,%edx | 0xbffff098 | 0xbffff098 | 0x0 |
ret | 0xbffff09c | 0x0 |