20145312 GDB调试汇编堆栈过程分析

20145312 GDB调试汇编堆栈过程分析

参考资料

卢肖明同学的博客:《GDB调试汇编堆栈过程分析》: http://www.cnblogs.com/lxm20145215----/p/5982554.html

分析过程

  • 使用vim example.c命令编写C程序

    20145312 GDB调试汇编堆栈过程分析

  • 保存退出后使用gcc -S example.c命令生成example.s文件,并使用cat example.s命令查看汇编文件

    20145312 GDB调试汇编堆栈过程分析

    20145312 GDB调试汇编堆栈过程分析

  • 打开example.s文件进行修改:删去所有.*的语句,并保存,再次使用cat example.s命令查看汇编代码

    20145312 GDB调试汇编堆栈过程分析

  • 使用gcc example.c -o example生成example.o文件,并使用objdump -d example命令进行反汇编

    20145312 GDB调试汇编堆栈过程分析

  • 这里出现了一个错误:我先是按照书上的步骤输入objdump -d example.o命令进行反汇编,出现错误:objdump:example.o:无此文件,于是我打开目录文件夹,发现 example.o文件的命名为 example,重新修改命令,成功。

  • 使用gcc - g example.c -o example -m32指令在64位的机器上产生32位汇编,然后使用gdb example指令进入gdb调试器

    20145312 GDB调试汇编堆栈过程分析

    20145312 GDB调试汇编堆栈过程分析

  • 进入之后先在main函数处设置一个断点,再run一下,使用disassemble指令获取汇编代码,用i(info) r(registers)指令查看各寄存器的值:

    20145312 GDB调试汇编堆栈过程分析

    20145312 GDB调试汇编堆栈过程分析

  • 使用display /i $pc命令,这样在每次执行下一条汇编语句时,都会显示出当前执行的语句。

    20145312 GDB调试汇编堆栈过程分析

    20145312 GDB调试汇编堆栈过程分析

  • 执行call指令将下一条指令的地址入栈

    20145312 GDB调试汇编堆栈过程分析

    20145312 GDB调试汇编堆栈过程分析

    20145312 GDB调试汇编堆栈过程分析

    20145312 GDB调试汇编堆栈过程分析

分析如下

  • 从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
上一篇:Selenium自动化测试Python四:WebDriver封装


下一篇:《手把手教你》系列进阶篇之2-python+ selenium自动化测试 - python基础扫盲(详细教程)