大道之行,天下为公。这篇文章主要讲述[Android Pro]ESP和EBP 栈顶指针和栈底指针相关的知识,希望能为你提供帮助。
cp:
http://blog.csdn.net/hutao1101175783/article/details/40128587
(1)ESP:栈指针寄存器(extended stack pointer),其内存放着一个指针,该指针永远指向系统栈最上面一个栈帧的栈顶。
(2)EBP:基址指针寄存器(extended base pointer),其内存放着一个指针,该指针永远指向系统栈最上面一个栈帧的底部。
【本次重点内容:了解几个常见的寄存器名字,记住eax一般用来保存函数的返回值,记住esp是栈顶指针寄存器,ebp是栈底指针寄存器。】
ESP 中的指针将一直指向这个新位置, 所以 ESP 中的地址数据是动态的.
-----
cp :
http://blog.csdn.net/yeruby/article/details/39780943
esp是栈指针,是cpu机制决定的,push、pop指令会自动调整esp的值;
ebp只是存取某时刻的esp,这个时刻就是进入一个函数内后,cpu会将esp的值赋给ebp,此时就可以通过ebp对栈进行操作,比如获取函数参数,局部变量等,实际上使用esp也可以;
既然使用esp也可以,那么为什么要设定ebp呢?
答案是为了方便程序员。
因为esp在函数运行时会不断的变化,所以保存一个一进入某个函数的esp到ebp中会方便程序员访问参数和局部变量,而且还方便调试器分析函数调用过程中的堆栈情况。前面说了,这个ebp不是必须要有的,你非要使用esp来访问函数参数和局部变量也是可行的,只不过这样会麻烦一些。
通过一段程序理解esp和ebp:
main() {
//执行test前
print(int p1,int p2);
//执行test后
}
分析下上面程序的调用原理,假设执行print前esp=Q:
push p2;
//函数参数p2入栈,esp=Q-4H
push p1;
//函数参数p1入栈,esp=Q-8H
call print;
//函数返回地址入栈,esp=Q-0CH
//现在进入print内,做些准备工作:
push ebp;
//保护先前ebp指针,ebp入栈,esp=Q-10H
mov esp,ebp;
//设置ebp等于当前的esp
// 此时,ebp+0CH=Q-4H,即p2的位置
// 同样,ebp+08H=Q-8H,即p1的位置
// 下面是print内的一些操作:
sub esp,20H;
//设置长度为10H大小的局部变量空间,esp=Q-20H
// ... ...
// 一系列操作
// ... ...
add esp,20H;
//释放局部变量空间,esp=Q-10H
pop ebp;
//出栈,恢复原先的ebp的值,esp=Q-0CH
ret 8;
//ret返回,弹出先前入栈的返回地址,esp=Q-08H,后面加操作数8H为平衡堆栈
// 之后,弹出函数参数,esp=Q,恢复执行print函数前的堆栈;
图示,注意栈在内存中的生长方向是逆向:
![[Android Pro]ESP和EBP 栈顶指针和栈底指针](http://img.readke.com/220502/092J161I-0.jpg)
文章图片
执行push p2; 前,esp=Q;
执行push p2; 过程中,esp-=4H,p2入栈;
执行push p2; 后,esp=Q-4H;
【[Android Pro]ESP和EBP 栈顶指针和栈底指针】
推荐阅读
- android studio环境搭建笔记
- Android Studio 第六十一期 - Android ToastUtil
- UWP Jenkins + NuGet + MSBuild 手把手教你做自动UWP Build 和 App store包
- 小程序会取代Native App吗()
- What happens when you type an URL in the browser and press enter?
- android开发学习 ------- git - 将代码回滚到任意版本
- Android面试收集录 数据库
- 结合实例分析Android MVP的实现
- Expo大作战--expo中的App Icon,expo中的Assets,expo中的ErrorHandling错误处理