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 阅读数 ...
随机推荐
- Selenium2.0介绍
selenium是一个web的自动化测试工具,和其它的自动化工具相比来说其最主要的特色是跨平台.跨浏览器. 支持windows.linux.MAC,支持ie.ff.safari.opera.chrom ...
- SQL where 1=1的作用
浅谈where 1=1 1.简单理解的话where 1=1 永真, where 1<>1 永假 2.1<>1 的用处: 用于只取结构不取数据的场合 例如: ...
- 学习资料 50个常用的sql语句
Student(S#,Sname,Sage,Ssex) 学生表 Course(C#,Cname,T#) 课程表 SC(S#,C#,score) 成绩表 Teacher(T#,Tname) 教师表 问题 ...
- spring HibernateValidator 验证 子类不起作用
spring HibernateValidator 验证 子类不起作用,在要验证的子类前加上@Valid即可. public class UserInfo { private int Id; @Val ...
- android 解析json数据格式(转)
json数据格式解析我自己分为两种: 一种是普通的,一种是带有数组形式的: 普通形式的:服务器端返回的json数据格式如下: {"userbean":{"Uid" ...
- CSS现代字体栈
CSS字体栈是一系列的字体,它包含了能在不同操作系统和平台上战士的字体,以尽可能的使排版保持一致性.浏览器会在font-family规定的所有字体中从前往后一次查找,如果找不到当前字体就查找下一个字体 ...
- call函数心得
今天深深受项目组一老大哥深深的鄙视了一把,在用call的时候,因不理解导致函数之间无法正常调用 function A(){ B.call(XXX,a,b,c); }; function B(a,b,c ...
- md5的一些用法
package md5; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; /* * ...
- iOS 平台开发OpenGL ES程序注意事项
本人最近从Android平台的OpenGL ES开发转到iOS平台的OpenGL ES开发,由于平台不同,所以开发中会有一些区别,再次列出需要注意的几点. 1.首先需要了解iOS主要开发框架,再次仅介 ...
- 修改VS解决方案及工程名,解决如何打开高/版本VS项目
对于VS2008等低版本与高版本VS之间的转换问题: 对照下面2个版本的不同点自由修改,切换到相应的版本文件(红字修改,灰色删除) ---------------------------------- ...