函式呼叫約定:當乙個函式被呼叫時,函式的引數會被傳遞給被呼叫的函式和返回值會被返回給呼叫函式。函式的呼叫約定就是描述引數是怎麼傳遞和由誰平衡堆疊的,當然還有返回值。
函式呼叫約定的主要約束事件:
引數傳遞順序:
1.從右到左依次入棧:__stdcall,__cdecl,__thiscall
2.從左到右依次入棧:__pascal,__fastcall(__簡寫為乙個_)
清除棧:
1.呼叫者清除棧。
2.被呼叫函式返回後清除棧。
在windows中,我們常用的兩種呼叫約定就是:_cdecl &_stdcall,另外在vc中,_stdcall又被定義為:winapi callback
他們的壓棧順序都為從右到左,但是他們的清除棧者是不同的。_cdecl由呼叫者清除棧,而_stdcall由被呼叫者清除棧。他們的作用在哪呢?_cdecl主要用到變參函式,例如printf(),被調函式並不知道將來會有多少個引數,所以只能由呼叫者來清理堆疊;而_stdcall則用於定引數,他把處理許可權交予被調函式,這樣有利於跨平台;
下面主要看看這兩種呼叫約定的區別:
#include using namespace std;
int _cdecl add(int a,int b)
int winapi reduce(int a,int b)
void main()
15: result=add(a,b);
004010c6 mov eax,dword ptr [ebp-8]
004010c9 push eax //入棧
004010ca mov ecx,dword ptr [ebp-4]
004010cd push ecx //入棧
004010ce call @ilt+0(add) (00401005)
004010d3 add esp,8 //清除棧
004010d6 mov dword ptr [ebp-0ch],eax
16: result=reduce(a,b);
004010d9 mov edx,dword ptr [ebp-8]
004010dc push edx//入棧
004010dd mov eax,dword ptr [ebp-4]
004010e0 push eax//入棧
004010e1 call @ilt+20(reduce) (00401019)
004010e6 mov dword ptr [ebp-0ch],eax
4:
0040105e pop edi
0040105f pop esi
00401060 pop ebx
00401061 mov esp,ebp
00401063 pop ebp
00401064 ret//恢復指令位址
8:
0040108e pop edi
0040108f pop esi
00401090 pop ebx
00401091 mov esp,ebp
00401093 pop ebp
00401094 ret 8 //恢復指令位址和清理棧
//主要是想鞏固一下自己的記憶
C 呼叫約定
cdecl fastcall與 stdcall,三者都是呼叫約定 calling convention 它決定以下內容 1 函式引數的壓棧順序,2 由呼叫者還是被呼叫者把引數彈出棧,3 以及產生函式修飾名的方法。1 stdcall呼叫約定 函式的引數自右向左通過棧傳遞,被呼叫的函式在返回前清理傳送引...
C 呼叫約定和名字約定
c 呼叫約定和名字約定 呼叫約定 cdecl fastcall與 stdcall,三者都是呼叫約定 calling convention 它決定以下內容 1 函式引數的壓棧順序,2 由呼叫者還是被呼叫者把引數彈出棧,3 以及產生函式修飾名的方法。1 stdcall呼叫約定 函式的引數自右向左通過棧傳...
C 呼叫約定和名字約定
呼叫約定是指程式在函式呼叫時傳遞引數和獲取返回值所採用的方法 通過暫存器 或通過棧 或者是兩者的混合。用於指定calling convention的修飾符主要有 cdecl,stdcall,fastcall等。呼叫約定可以通過工程設定 setting.c c advanced callingconv...