1. 程式人生 > >函式的開始和結束標誌

函式的開始和結束標誌

.text:00401010 ; void *__thiscall CtmpApp___vector deleting destructor_(CtmpApp *this, unsigned int)
.text:00401010 [email protected]@[email protected] proc near        ; DATA XREF: .rdata:004034D8o
.text:00401010
.text:00401010 arg_0           = byte ptr  8
.text:00401010
.text:00401010 this = ecx
.text:00401010                 push    ebp
.text:00401011                 mov     ebp, esp
.text:00401013                 push    esi
.text:00401014                 mov     esi, this
.text:00401016                 call    ds:
[email protected]
@[email protected] ; CWinApp::~CWinApp(void) .text:0040101C test [ebp+arg_0], 1 .text:00401020 jz short loc_40102C .text:00401022 push esi .text:00401023 call ds:[email protected]@Z ; operator delete(void *) .text:00401029 add esp, 4 .text:0040102C .text:0040102C loc_40102C: ; CODE XREF: CtmpApp::`vector deleting destructor'(uint)+10j .text:0040102C mov eax, esi .text:0040102E pop esi .text:0040102F pop ebp .text:00401030 retn 4 .text:00401030
[email protected]
@[email protected] endp

先不說別的,隨便貼一段反彙編程式碼,然後進行分析:

可以看到,一般而言函式都是以

push ebp;

mov  ebp,esp;

開始的因為在函式內部要使用區域性變數,而所有的變數都是要有地址記錄的,所以要使用ebp,而在新的函式使用ebp之前要壓入堆疊,否則會導致父函式崩潰,使用之前先將

其儲存到堆疊當中,同時因為esp是指向棧頂的,其次mov ebp,esp是要將之前的棧頂變棧底,因為之後根據函式內部的區域性變數的分配,esp不斷減小,所以要將函式呼叫之

前的內容儲存起來,也就是,當前函式的起始地址,之後的函式區域性變數要在esp之後,隨著函式內部變數的不斷分配,同時esp的值也會不斷減小,我們會看到,在該函式內

部,push和pop並不是成對出現的,但是在

.text:00401022 push esi;

.text:00401023 call ds:operator delete(void*);

這是一步函式呼叫,push  esi為函式 delete提供引數,在該函式完成後,會自行彈出esi的值,

.text:00401013 push esi;壓入堆疊,使用完畢後,在

.text:0040102E pop esi;  彈出堆疊,恢復之前的現場

該函式執行完畢後,.text 將 在函式使用之前壓入堆疊的棧頂地址彈出到ebp當中,然後 retn 4說明函式執行完畢,4表示在該函式中彈出4個位元組,可能該函式中有佔據4個位元組

的引數。

所以 函式執行完畢有兩種:

pop ebp;                                                                                                      mov esp,ebp;

add esp,64h;//將之前的壓入堆疊的空間收回                                         pop ebp;

retn                                                                                                                    retn

函式在執行完畢後通過將堆疊的指標向下移動,恢復ebp,而關閉堆疊,對應之前的mov ebp,esp;開啟堆疊,或者通過esp的增加實現關閉堆疊的同樣效果。