目錄
1、為什麼需要指定函式呼叫方式?
2、常見的函式呼叫方式
2.1 stdcall
2.2 cdecl
2.3 fastcall
2.4 thiscall
呼叫函式時,計算機常用棧來儲存傳遞給函式的引數。
在引數傳遞中,有兩個重要的問題必須要明確說明:
1. 當引數個數多於乙個時,按照什麼順序把引數壓入堆疊;2. 函式呼叫後,由誰來把堆疊恢復原狀。
c/c++通過函式的呼叫方式來說明這兩個問題的
stdcall、cdecl、fastcall、thiscall
stdcall呼叫方式又被稱為pascal呼叫方式。在microsoft c++系列的c/c++編譯器中,使用pascal巨集,winapi巨集和callback巨集來指定函式的呼叫方式為stdcall。
stdcall呼叫方式的函式宣告為:
int _stdcall function(int a, int b);
stdcall的呼叫方式意味著:
(1) 引數從右向左一次壓入堆疊cdecl呼叫方式又稱為c呼叫方式,是c語言預設的呼叫方式,它的語法為:(2) 由被呼叫函式自己來恢復堆疊
(3) 函式名自動加前導下劃線,後面緊跟著乙個@,其後緊跟著引數的尺寸
int function(int a, int b) // 不加修飾符就是c呼叫方式
int _cdecl function(int a, int b) // 明確指定用c呼叫方式
cdecl的呼叫方式決定了:
(1) 引數從右向左依次壓入堆疊由於是由呼叫者來恢復堆疊,因此c呼叫方式允許函式的引數個數是不固定的,這是c語言的一大特色。(2) 由呼叫者恢復堆疊
(3) 函式名自動加前導下劃線
fastcall 按照名字上理解就可以知道,它是一種快速呼叫方式。此方式的函式的第乙個和第二個dword引數通過ecx和edx傳遞,
(1)引數從右向左的順序壓入棧其宣告語法為:(2)被呼叫函式清理堆疊
(3) 函式名自動加前導下劃線,後面緊跟著乙個@,其後緊跟著引數的尺寸
int fastcall function(int a, int b);
thiscall 呼叫方式是唯一一種不能顯示指定的修飾符。它是c++類成員函式預設的呼叫方式。由於成員函式呼叫還有乙個this指標,因此必須用這種特殊的呼叫方式。
thiscall呼叫方式意味著:
(1)引數從右向左壓入棧可以看到,對於引數個數固定的情況,它類似於stdcall,不定時則類似於cdecl。(2)如果引數個數確定,this指標通過ecx傳遞給被呼叫者;如果引數個數不確定,this指標在所有引數壓入棧後被壓入棧
(3)引數個數不定的,由呼叫者清理堆疊,否則由函式自己清理堆疊
C C 函式呼叫的幾種方式總結
呼叫函式時,計算機常用棧來儲存傳遞給函式的引數。棧是一種先進後出的資料結構,棧有乙個儲存區 乙個棧頂指標。棧頂指標指向堆疊中第乙個可用的資料項 被稱為棧頂 使用者可以在棧頂上方向棧中加入資料,這個操作被稱為壓棧 push 壓棧以後,棧頂自動變成新加入資料項的位置,棧頂指標也隨之修改。使用者也可以從堆...
C C 函式呼叫的幾種方式
我們知道,呼叫函式時,計算機常用棧來存放函式執行需要的引數,由於棧的空間大小是有限的,在 windows 下棧是向低位址擴充套件的資料結構,是一塊連續的記憶體區域。這句話的意思是棧頂的位址和棧的最大容量是系統預先規定好的,windows下棧的大小是2m 也有的說是1m 如果申請的空間超過棧的剩餘空間...
C C 函式呼叫方式
cdecl 是c declaration的縮寫 declaration,宣告 表示c語言預設的函式呼叫方法 所有引數從右到左依次入棧,這些引數由呼叫者清除,稱為手動清棧。被呼叫函式不會要求呼叫者傳遞多少引數,呼叫者傳遞過多或者過少的引數,甚至完全不同的引數都不會產生編譯階段的錯誤。stdcall 是...