对于ESP、EBP寄存器的理解

原文:http://blog.csdn.net/yeruby/article/details/39780943程序员

esp是栈指针,是cpu机制决定的,push、pop指令会自动调整esp的值;ruby

ebp只是存取某时刻的esp,这个时刻就是进入一个函数内后,cpu会将esp的值赋给ebp,此时就能够经过ebp对栈进行操做,好比获取函数参数,局部变量等,实际上使用esp也能够;函数

既然使用esp也能够,那么为何要设定ebp呢?spa

答案是为了方便程序员。.net

由于esp在函数运行时会不断的变化,因此保存一个一进入某个函数的esp到ebp中 会方便程序员访问参数和局部变量,并且还方便调试器分析函数调用过程当中的堆栈状况。前面说了,这个ebp不是必需要有的,你非要使用esp来访问函数参数 和局部变量也是可行的,只不过这样会麻烦一些。指针


经过一段程序理解esp和ebp:调试

main() {blog

//执行test前内存

print(int p1,int p2);get

//执行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函数前的堆栈;


图示,注意栈在内存中的生长方向是逆向:

 


 

执行push p2;前,esp=Q;

 

执行push p2;过程当中,esp-=4H,p2入栈;

 

执行push p2;后,esp=Q-4H;

相关文章
相关标签/搜索