對於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;

相關文章
相關標籤/搜索