c 函式呼叫約定

2021-09-01 07:39:45 字數 2406 閱讀 2768

函式的呼叫約定,當乙個函式被呼叫時,引數的傳遞以及返回值以什麼樣的方式回到呼叫函式;函式的呼叫約定就是指引數和返回值是怎麼樣傳遞的,以及是由誰平衡堆疊的。

函式的呼叫約定主要針對三個問題:

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中,計算機沒有辦法知道乙個函式呼...