函式呼叫方式簡介

2021-06-13 01:10:21 字數 1917 閱讀 3095

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

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

pascal 是pascal語言的函式呼叫方式,也可以在c/c++中使用,引數壓棧順序與前兩者相反。返回時的清棧方式忘記了。。。

_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, ...);

這兩個關鍵字看起來似乎很少和我們打交道,但是看了下面的定義(來自windef.h

),你一定會覺得驚訝:

#define callback     __stdcall

#define winapi       __stdcall

#define winapiv      __cdecl

#define apientry     winapi

#define apiprivate   __stdcall

#define pascal       __stdcall

#define cdecl _cdecl

#ifndef cdecl

#define cdecl _cdecl

#endif

幾乎我們寫的每乙個windows api函式都是__stdcall型別的,為什麼??

首先,我們談一下兩者之間的區別:

windows的函式呼叫時需要用到棧(stack,一種先入後出的儲存結構)。當函式

呼叫完成後,棧需要清除,這裡就是問題的關鍵,如何清除??

如果我們的函式使用了_cdecl,那麼棧的清除工作是由呼叫者,用com的術語來講

就是客戶來完成的。這樣帶來了乙個棘手的問題,不同的編譯器產生棧的方式不盡相同

,那麼呼叫者能否正常的完成清除工作呢?答案是不能。

如果使用__stdcall,上面的問題就解決了,函式自己解決清除工作。所以,在跨

(開發)平台的呼叫中,我們都使用__stdcall(雖然有時是以winapi的樣子出現)。

那麼為什麼還需要_cdecl呢?當我們遇到這樣的函式如fprintf()它的引數是可變

的,不定長的,被呼叫者事先無法知道引數的長度,事後的清除工作也無法正常的進行

,因此,這種情況我們只能使用_cdecl。

到這裡我們有乙個結論,如果你的程式中沒有涉及可變引數,最好使用__stdcal

l關鍵字

函式呼叫方式

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

函式呼叫方式

現代的程式語言的函式竟然有那麼多的呼叫方式。這些東西要完全理解還得通過彙編 才好理解。他們各自有自己的特點 其實這些呼叫方式的差別在主要在一下幾個方面 1.引數處理方式 傳遞順序,訪問 利用盞還是暫存器 2.函式的結尾處理方式 善後處理 如 棧的恢復由誰恢復?函式內恢復 還是呼叫後恢復 以下是理論 ...

函式呼叫方式

所謂的呼叫方式是指 在呼叫乙個函式時,約定的傳遞引數方式和平衡堆疊方式,例如 有乙個函式,它有兩個引數 xyz first,second 當我們使用stdcall呼叫方式時,也就是windows呼叫api的常見方式 又幾個函式例外 它的呼叫方式如下 x1 push second x2 push fi...