1. 程式人生 > >esp和ebp暫存器

esp和ebp暫存器

首先說明,在堆疊中變數分佈是從高地址到低地址分佈,EBP是指向棧底的指標,在過程呼叫中不變,又稱為幀指標。ESP指向棧頂,程式執行時移動,ESP減小分配空間,ESP增大釋放空間,ESP又稱為棧指標。

下面來逐步分析函式的呼叫過程

1.函式main執行,main各個引數從右向左逐步壓入棧中,最後壓入返回地址

2.執行第15行,3個引數以從左向右的順序壓入堆疊,及從param3到param1,棧內分佈如下圖:

 3.然後是返回地址入棧:此時的棧內分佈如下:

4.第3行函式呼叫時,通過跳轉指令進入函式後,函式地址入棧後,EBP入棧,然後把當前ESP的值給EBP,對應的彙編指令

push
ebp mov ebp esp

   此時棧頂和棧底指向同一位置,棧內分佈如下:

5.第5行開始執行, int var1 = param1; int var2 = param2; int var3 = param3;按申明順序依次儲存。對應的彙編:

mov 0x8(%ebp),%eax
mov %eax,-0x4(%ebp)

  其中將[EBP+0x8]地址裡的內容賦給EAX,即把param的值賦給EAX,然後把EAX的中的值放到[EBP-4]這個地址裡,即把EAX值賦給var1,完成C程式碼 int var1 = param1,其他變數雷同。

6.第9行,輸出結果,第10行執行 對應的彙編程式碼:

mov  -0x4(%ebp),%eax

 最後通過eax暫存器儲存函式的返回值

7.呼叫執行函式完畢,區域性變數var3,var2,var1一次出棧,EBP恢復原值,返回地址出棧,找到原執行地址,param1,param2,param3依次出棧,函式呼叫執行完畢

三、例項分析2

http://blog.csdn.net/hudashi/article/details/7820338

一直對暫存器ESP和EBP的概念總是有些混淆,檢視定義ESP是棧頂指標,EBP是存取堆疊指標。還是不能很透徹理解。之後借於一段彙編程式碼,總算是對兩者有個比較清晰的理解。 下面是按呼叫約定__stdcall 呼叫函式test(int p1,int p2)的彙編程式碼 假設執行函式前堆疊指標ESP為NN push   p2    ;引數2入棧, ESP -= 4h , ESP = NN - 4h push   p1    ;引數1入棧, ESP -= 4h , ESP = NN - 8h call test    ;壓入返回地址 ESP -= 4h, ESP = NN - 0Ch   ;//進入函式內
{ push   ebp                        ;保護先前EBP指標, EBP入棧, ESP-=4h, ESP = NN - 10h mov    ebp, esp                   ;設定EBP指標指向棧頂 NN-10h mov    eax, dword ptr  [ebp+0ch]  ;ebp+0ch為NN-4h,即引數2的位置 mov    ebx, dword ptr  [ebp+08h]  ;ebp+08h為NN-8h,即引數1的位置 sub    esp, 8                     ;區域性變數所佔空間ESP-=8, ESP = NN-18h ... add    esp, 8                     ;釋放區域性變數, ESP+=8, ESP = NN-10h pop    ebp                        ;出棧,恢復EBP, ESP+=4, ESP = NN-0Ch ret    8                          ;ret返回,彈出返回地址,ESP+=4, ESP=NN-08h, 後面加運算元8為平衡堆疊,ESP+=8,ESP=NN, 恢復進入函式前的堆疊. } 看完彙編後,再看EBP和ESP的定義,哦,豁然開朗, 原來ESP就是一直指向棧頂的指標,而EBP只是存取某時刻的棧頂指標,以方便對棧的操作,如獲取函式引數、區域性變數等。