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中的基址。这里有一个误区就是:我们在数据结构中学的栈顶指针总是指向栈顶元素的下一个位置,但在这里确实指向栈顶元素。这里千万要注意。
esp和ebp详解的更多相关文章
- 栈帧%ebp,%esp详解
首先应该明白,栈是从高地址向低地址延伸的.每个函数的每次调用,都有它自己独立的一个栈帧,这个栈帧中维持着所需要的各种信息.寄存器ebp指向当前的栈帧的底部(高地址),寄存器esp指向当前的栈帧的顶部( ...
- Linux 中断详解 【转】
转自:http://blog.csdn.net/tiangwan2011/article/details/7891818 原文地址 http://www.yesky.com/20010813/1921 ...
- 异常处理与MiniDump详解(4) MiniDump
http://blog.csdn.net/vagrxie/article/details/4398721 异常处理与MiniDump详解(4) MiniDump 分类: [Wi ...
- 异常处理与MiniDump详解(转)
一. 综述 总算讲到MiniDump了. Dump有多有用我都无法尽数,基本上属于定位错误修复BUG的倚天剑.(日志可以算是屠龙刀)这些都是对于那些不是必出的BUG,放在外面运行的时候出现的BUG ...
- gcc/g++等编译器 编译原理: 预处理,编译,汇编,链接各步骤详解
摘自http://blog.csdn.net/elfprincexu/article/details/45043971 gcc/g++等编译器 编译原理: 预处理,编译,汇编,链接各步骤详解 C和C+ ...
- Linux进程上下文切换过程context_switch详解--Linux进程的管理与调度(二十一)
1 前景回顾 1.1 Linux的调度器组成 2个调度器 可以用两种方法来激活调度 一种是直接的, 比如进程打算睡眠或出于其他原因放弃CPU 另一种是通过周期性的机制, 以固定的频率运行, 不时的检测 ...
- C/C++堆、栈及静态数据区详解
转自:https://www.cnblogs.com/hanyonglu/archive/2011/04/12/2014212.html 做略微修改 C/C++堆.栈及静态数据区详解 本文介绍C ...
- ZT --- extern "C"用法详解 2010-08-21 19:14:12
extern "C"用法详解 2010-08-21 19:14:12 分类: C/C++ 1.前言: 时常在cpp的代码之中看到这样的代码: #ifdef __cplusplus ...
- Linux Ptrace 详解
转 https://blog.csdn.net/u012417380/article/details/60470075 Linux Ptrace 详解 2017年03月05日 18:59:58 阅读数 ...
随机推荐
- SQL 实现,如果存在就更新,如果不存在就添加
alter proc proc_DataSummary as begin begin try begin tran --PV --统计的信息存入临时表 ), CreateDate, ) ), Crea ...
- java 中的fanal
三.java中有final final 修饰符 关键字可用于修饰类,变量和方法,final关键字有点类似于C#里的sealed 关键字,用于表示它修饰的类,方法和变量不可改变. fina修饰变量时,表 ...
- C++中rapidxml用法及例子
rapidxml是一个快速的xml库,比tinyxml快了50-100倍.本文给出创建.读取.写入xml的源码. 由于新浪博客不支持文本文件上传,在使用下面代码需要先下载 rapidxml,关于这个库 ...
- ionic cordova file download and load
1.先添加插件 cordova plugin add org.apache.cordova.file cordova plugin add org.apache.cordova.file-transf ...
- 简单的使用AngularJS的解析JSON
使用AngularJS+Struts2进行前后台的数据交互与显示. struts.xml 配置文件需要将设置extends="json-default" type="j ...
- (笔记)angular 事件传递获取当前
- javascript之delete操作符
理解delete 理论 代码段的类型 执行上下文 活动对象 / 变量对象 属性的特性 内置属性与 DontDelete 未声明的赋值 Firebug的困惑 在eval中删除变量 浏览器兼容性 Geck ...
- openssl mac中使用终端生成RSA私钥和公钥文件
RSA密钥生成命令生成RSA私钥openssl>genrsa -out rsa_private_key.pem 1024生成RSA公钥openssl>rsa -in rsa_private ...
- 如何实现Android 中断线程的处理
我现在对一个用户注册的功能1.用ProgressDialog将当前页面设成不可操作(保留返回键 退出ProgressDialog)2.用一个线程clientThread执行数据的提交和返回 问题:考虑 ...
- dedecms 调用channel子栏目的id问题
dedecms 说明文档:http://www.dedecms.com/archives/templethelp/help/taghelp.htm {dede:channel type='son' t ...