函式的呼叫約定,當乙個函式被呼叫時,引數的傳遞以及返回值以什麼樣的方式回到呼叫函式;函式的呼叫約定就是指引數和返回值是怎麼樣傳遞的,以及是由誰平衡堆疊的。
函式的呼叫約定主要針對三個問題:
1.函式符號的生成與編譯後的名稱
2.實參的入棧順序
3.形參的開闢與清理方式
一、__cdecl呼叫約定
cdecl是c標準的呼叫約定;宣告方式為:
int function(int a,int b) //不加修飾就是採用預設的c呼叫約定
int __cdecl function(int a,int b) //明確指出c排程約定
__cdecl約定下的函式符號的生成:int __cdecl sum(int,int) =》 (?sum@@yahhh@z)
?sum@@yahhh@z
sum指的是函式名
a指的呼叫約定 __cdecl
第乙個h返回值的型別,後面的h是引數的型別
__cdecl約定下的函式編譯後的名稱:_sum
由呼叫函式中的彙編指令可以看出,__cdecl呼叫約定中,形參是由呼叫函式清理的;
二、__stdcall
__stdcall是windows標準呼叫約定,也被稱為pascal呼叫約定,因為使用pascal方式清棧c方式壓棧,在win32應用程式裡,巨集apientry,winapi,都表示_stdcall;宣告方式為:
__stdcall呼叫約定下函式符號的生成:int __stdcall sum(int a, int b) =》?sum@@yghhh@z
?sum@@yghhh@z
sum指的是函式名
g指的呼叫約定 __stdcall
第乙個h返回值的型別,後面的h是引數的型別
__stdcall呼叫約定下編譯後的名稱:_sum@4 @後跟引數型別的位元組數
在呼叫函式的彙編指令中,先push14h將十進位制數字20入棧,push 0ah將十進位制數字10入棧,所以在stdcall呼叫約定下形參是呼叫函式開闢棧的,形參入棧的順序是從右向左入棧;由call函式跳轉到被調函式,返回值由暫存器帶入呼叫函式中;注意在被調函式中有:
00a2297a ret 8 //被調函式中
ret指令是對棧頂指標esp進行操作,所以__stdcall呼叫約定中形參是由被調函式清理的
三、__fastcall
顧名思義,其特點就是快;_fastcall函式呼叫約定表明了引數應該放在暫存器中,而不是棧中,使用vc編譯器呼叫約定傳遞引數時,最左邊的兩個不大於4個位元組(deord)的引數分別放在ecx和edx暫存器,像浮點值還是通過堆疊來傳遞
__fastcall呼叫約定下函式符號的生成:extern int __fastcall sum(int , int ,int) =》?sum@@yihhhh@z
?sum@@yihhhh@z
sum指的是函式名
i指的呼叫約定 __fastcall
第乙個h返回值的型別,後面的h是引數的型別
__fastcall呼叫約定下編譯後的名稱:@sum@8
在呼叫函式中,引數有3個,push 1eh將十進位制的30入棧,將十進位制的20與10分別放入edx和ecx暫存器中;所以在fastcall呼叫約定下,當引數個數不大於兩個,並且引數不大於32位元組時,則形參只需要暫存器(edx與ecx)傳遞(也就是不需要開闢棧),如果引數個數大於兩個時,從第三個數起,從右往左進行入棧;在本例中有三個引數,所以第三個引數入棧;然後依舊從call函式跳轉到被調函式中,返回值放在eax暫存器中帶出,在被調函式中有:
00f12985 ret 4 //被調函式中
在被調函式中對esp進行操作,被調函式恢復棧頂指標,因為只有乙個int型別的數值入棧,所以這裡是4
四、__thiscall
thiscall是唯一乙個不能明確指明的函式修飾,因為thiscall只能用於c++類成員函式的呼叫;由於成員函式呼叫還有乙個this指標,因此必須特殊處理。thiscall意味著:
1.採用棧傳遞引數,引數從右向左入棧。如果引數個數確定,this指標通過ecx傳遞給被呼叫者;如果引數個數不確定,this指標在所有引數壓棧後被壓人堆疊;
2.對引數個數不確定的,呼叫者清理堆疊,否則由被調函式清理堆疊
C 函式呼叫約定
stdcall是 函式呼叫約定的一種,函式呼叫約定主要約束了兩件事 1.引數傳遞順序 2.呼叫 堆疊由誰 呼叫函式或 被呼叫函式 清理 常見的 函式呼叫約定 stdcall cdecl fastcall thiscall naked call stdcall表示 1.引數從右向左壓入堆疊 2.函式被...
C語言函式呼叫約定
在c語言中,假設我們有這樣的乙個函式 int function int a,int b 調 用時只要用result function 1,2 這樣的方式就可以使用這個函式。但是,當高階語言被編譯成計算機可以識別的機器碼時,有乙個問題就凸現出來 在cpu中,計算 機沒有辦法知道乙個函式呼叫需要多少個 ...
C語言函式呼叫約定
馨榮家園blog 在c語言中,假設我們有這樣的乙個函式 int function int a,int b 呼叫時只要用result function 1,2 這樣的方式就可以使用這個函式。但是,當高階語言被編譯成計算機可以識別的機器碼時,有乙個問題就凸現出來 在cpu中,計算機沒有辦法知道乙個函式呼...