esp和ebp详解

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

esp和ebp详解
最近在研究栈帧的结构,但总是有点乱,所以写了⼀个⼩程序来看看esp和ebp在栈帧中的作⽤。

这个程序如下:
这个程序很简单,就是求两个数的值,然后输出即可。

所以⾸先把它⽤gcc编译链接成a.out,进⼊gdb进⾏调试。

⾸先在main和add两处设置断点。

运⾏到第⼀个断点,查看main的汇编代码:
我们主要是观察调⽤add后我们的esp和ebp的变化,于是输⼊命令:c,继续运⾏到add处,观察add的汇编:
其实也就是运⾏到了main的call指令处进⼊add函数了。

这时到了观察esp和ebp的时刻了。

上图其实已经很明显了。

我们来看下⾯的图,这样⽴体观察(栈帧结构图)就会瞬间明⽩了:
我把栈帧的每个字节都拆开来看就会有下⾯的结论,通过GDB,查找出这时esp和ebp的值,均为0xbffff0a8。

详解如下:
我们知道调⽤call指令后会有下⾯的三件事:
call指令保存返回地址:所谓保存返回地址(return address)其实就是 call指令将那⼀时刻的PC(%eip值,即call的下⼀条指令的地址)压⼊栈(如上图中的0x8048447)。

还记得吗?因为PC⾃增在先,指令执⾏在后。

所以执⾏完add的所有代码后,ret指令会恢复PC的值,程序就可以继续执⾏main的剩余代码了。

add()保存main()的%ebp:将add()栈帧的base地址压⼊到栈上。

这时查看从0xbffff0a8开始每个字节⾥的内容,从上⾯看出从0xbffff0a8开始向上的16个字节的内容(我把其中的8个放到了栈帧结构图中了)。

main栈帧的最后4个字节代表着返回地址,通过gdb的查看也可以明显看出⾥边的内容就是main中call指令的下⼀条指令的地址。

当我们读取0xbffff08a中的内容时(按双字节读)结果显⽰0xbffff0d8.可见这⾥是⼩端存储,读取是从⾼地址开始读取,其值表⽰main中的基
址。

这⾥有⼀个误区就是:我们在数据结构中学的栈顶指针总是指向栈顶元素的下⼀个位置,但在这⾥确实指向栈顶元素。

这⾥千万要注意。

相关文档
最新文档