天天看點

c語言----棧幀

棧幀

  每一次函數調用都有一個過程,稱為“函數調用過程”,這個過程要為函數開辟棧空間,用于本次函數的調用中臨時變量的儲存,現場保護。這個棧空間稱為函數的調用過程。

  Ⅰ.寄存器

   基址寄存器(棧底寄存器):EBP

   棧頂寄存器:ESP

   通用寄存器:EAX,EDX,EBX,ECX.

Ⅱ.彙編指令:

  call:功能:1.将目前正在執行指令的下一條指令的位址壓人棧中;2.随即call會跳轉至指定函數(jmp)

  ret(傳回):1.彈出(pop)棧頂;2.彈出後的棧頂元素放入EIP。

Ⅲ.研究代碼

#include<stdio.h>

#include<windows.h>

int myadd(int x,int y)

{

int z = x + y;

return z;

}

int main()

{

int a = 0xAAAAAAAA;

int b = 0xBBBBBBBB;

int c = 0;

c = myadd(a,b);

printf("you should run here\n");

printf("result:%d\n",c);

system("pause");

return 0;

}

Ⅳ.棧幀過程:

1.main函數中的棧幀以及main函數調用時形參的執行個體化:

c語言----棧幀

2.傳回把目前執行指令的下一條指令儲存,esp中a的位址比b小:

c語言----棧幀

3.由反彙編得call指令的下一條指令的位址為0040109A,将它壓入棧中,F11後下圖中0019FEDC變為0040109A(小端)

c語言----棧幀
c語言----棧幀

通過jmp到指定函數myadd處  寄存器EIP變為00401020

c語言----棧幀

在myadd函數中:

c語言----棧幀

再把EBP mov 給esp得

mov前為:

c語言----棧幀

mov後為:

c語言----棧幀

此時ebp指向esp

c語言----棧幀

下一條指令00401023為給ESP-4,是以此時ESP要往下移,形成了一個新的空間,這個空間為myadd的棧幀。

c語言----棧幀

上面3條指令所表達的意思:

1.把ebp+8(a) mov 給eax;

2.把 ebp+12(b) 與eax相加為eax;

3.eax mov給 ebp-4,是以此時棧幀如下:

c語言----棧幀

函數調用完成之後

c語言----棧幀

把ESP mov 給ebp,彈出(pop)棧頂給ebp,是以此時的ebp為main函數的ebp,下一步傳回ret,ret作用為彈出(pop)棧頂并把彈出後的棧頂值放入EIP。此時恢複到main函數的棧幀内,如下:

c語言----棧幀

最後如下:

c語言----棧幀

謝謝觀看。

繼續閱讀