幾種函式呼叫方式

2021-06-08 00:30:54 字數 2112 閱讀 4444

以下是baidu給出的解釋,果斷mark,也作為自己的乙個知識點吧:

__cdecl 是c declaration的縮寫(declaration,宣告),表示c語言預設的函式呼叫方法:所有引數從右到左依次入棧,這些引數由呼叫者清除,稱為手動清棧。被呼叫函式不會要求呼叫者傳遞多少引數,呼叫者傳遞過多或者過少的引數,甚至完全不同的引數都不會產生編譯階段的錯誤。

_stdcall 是standardcall的縮寫,是c++的標準呼叫方式:所有引數從右到左依次入棧,如果是呼叫類成員的話,最後乙個入棧的是this指標。這些堆疊中的引數由被呼叫的函式在返回後清除,使用的指令是 retnx,x表示引數占用的位元組數,cpu在ret之後自動彈出x個位元組的堆疊空間。稱為自動清棧。函式在編譯的時候就必須確定引數個數,並且呼叫者必須嚴格的控制引數的生成,不能多,不能少,否則返回後會出錯。

pascal 是

pascal語言

的函式呼叫方式,也可以在c/c++中使用,引數壓棧順序與前兩者相反。返回時的清棧方式與_stdcall相同。

_fastcall是

編譯器指定的快速呼叫方式。由於大多數的函式引數個數很少,使用堆疊傳遞比較費時。因此_fastcall通常規定將前兩個(或若干個)引數由暫存器傳遞,其餘引數還是通過堆疊傳遞。不同編譯器編譯的程式規定的暫存器不同。返回方式和_stdcall相當。

_thiscall 是為了解決類成員呼叫中this指標傳遞而規定的。_thiscall要求把this指標放在特定暫存器中,該暫存器由編譯器決定。vc使用ecx,borland的c++編譯器使用eax。返回方式和_stdcall相當。

_fastcall 和 _thiscall涉及的暫存器由編譯器決定,因此不能用作跨編譯器的介面。所以windows上的com物件介面都定義為_stdcall呼叫方式。

c中不加說明預設函式為_cdecl方式(c中也只能用這種方式),c++也一樣,但是預設的呼叫方式可以在ide環境中設定。

帶有可變引數的函式必須且只能使用_cdecl方式,例如下面的函式:

int printf(char * fmtstr, ...);

int scanf(char * fmtstr, ...);

*/幾種呼叫約定的區別

__cdecl __fastcall與 

__stdcall

,三者都是呼叫約定(calling convention),它決定以下內容:1)函式引數的壓棧順序,2)由呼叫者還是被呼叫者把引數彈出棧,3)以及產生函式修飾名的方法。

1、__stdcall呼叫約定:函式的引數自右向左通過棧傳遞,被呼叫的函式在返回前清理傳送引數的記憶體棧,

2、_cdecl是c和c++程式的預設呼叫方式。每乙個呼叫它的函式都包含清空堆疊的**,所以產生的

可執行檔案

大小會比呼叫_stdcall函式的大。函式採用從右到左的壓棧方式。注意:對於可變引數的成員函式,始終使用__cdecl的轉換方式。

3、__fastcall呼叫約定:它是通過暫存器來傳送引數的(實際上,它用ecx和edx傳送前兩個雙字(dword)或更小的引數,剩下的引數仍舊自右向左壓棧傳送,被呼叫的函式在返回前清理傳送引數的記憶體棧)。

5、nakedcall採用1-4的呼叫約定時,如果必要的話,進入函式時編譯器會產生**來儲存esi,edi,ebx,ebp暫存器,退出函式時則產生**恢復這些暫存器的內容。naked call不產生這樣的**。naked call不是型別修飾符,故必須和_declspec共同使用。

1、修飾名(decoration name):"c"或者"c++"函式在內部(編譯和鏈結)通過修飾名識別

2、c編譯時函式名修飾約定規則:

__stdcall呼叫約定在輸出函式名前加上乙個下劃線字首,後面加上乙個"@"符號和其引數的位元組數,格式為_functionname@number,例如 :function(int a, int b),其修飾名為:_function@8

__cdecl呼叫約定僅在輸出函式名前加上乙個下劃線字首,格式為_functionname。

__fastcall呼叫約定在輸出函式名前加上乙個"@"符號,後面也是乙個"@"符號和其引數的位元組數,格式為@functionname@number。

2 在ms-vc++6.0中,呼叫約定也可以通過工程設定:setting...\c/c++ \code generation項進行選擇,預設狀態為__cdecl。名字修飾約定。

幾種函式呼叫方式

目錄幾種函式呼叫方式 幾種呼叫約定的區別 名字修飾約定 設定方法 cdecl 是c declaration的縮寫 declaration,宣告 表示c語言預設的函式呼叫方法 所有引數從右到左依次入棧,這些引數由呼叫者清除,稱為手動清棧。被呼叫函式不需要求呼叫者傳遞多少引數,呼叫者傳遞過多或者過少的引...

幾種函式呼叫方式

cdecl 是c declaration的縮寫 declaration,宣告 表示c語言預設的函式呼叫方法 所有引數從右到左依次入棧,這些引數由呼叫者清除,稱為手動清棧。被呼叫函式不會要求呼叫者傳遞多少引數,呼叫者傳遞過多或者過少的引數,甚至完全不同的引數都不會產生編譯階段的錯誤。stdcall 是...

C C 函式呼叫的幾種方式

我們知道,呼叫函式時,計算機常用棧來存放函式執行需要的引數,由於棧的空間大小是有限的,在 windows 下棧是向低位址擴充套件的資料結構,是一塊連續的記憶體區域。這句話的意思是棧頂的位址和棧的最大容量是系統預先規定好的,windows下棧的大小是2m 也有的說是1m 如果申請的空間超過棧的剩餘空間...