GDB Hacks读书笔记 第二章–调试前的必会知识__必需的栈知识-x86
这部分知识点的理解对于后续调试程序由很大的影响。每个函数自身的栈以及调用者和被调用者之间的栈关系,函数调用时参数传递规则,被调用函数内部变量是如何分配的等。
环境
使用32位虚拟机
ubuntu 14.04 32bit
gcc 4.8.4
使用的函数
使用如下命令编译
gcc -g fun_.c
栈
在调试时,栈是常用的数据结构。栈是一种后进先出的数据结构(LIFO)。向栈内添加数据称为PUSH ,从栈上取出数据称为POP。x86的函数栈是自下而上增长。
函数调用和栈的关系
每个函数都有自己的函数栈,当main函数调用子函数时,子函数拥有自己的函数栈,此时的函数栈称为栈帧。栈上依次保存的数据为
- 函数调用需要的参数
- 通过call指令调用函数时保存的返回地址
- 调用函数的栈ebp
- 供给自己使用的栈空间,这里分配出来的栈空间主要给函数内的变量等使用。
如图,来自DEBUG Hacks 中文版深入调试的技术和工具–图2-12
如图,当main()函数没有调用sum_till_MAX()函数时,存在栈帧A(图a)
发生main()->sum_till_MAX函数,首先将sum_till_MAX函数需要的参数压入栈,接着调用call指令调用sum_till_MAX函数,相关汇编指令
push 0x0
call sum_till_MAX
接着,在sum_till_MAX函数内