欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C/C++函數(shù)調(diào)用的幾種方式總結(jié)

 更新時間:2013年12月20日 08:48:03   作者:  
本篇文章主要是對C/C++函數(shù)調(diào)用的幾種方式進行了詳細的總結(jié)介紹,需要的朋友可以過來參考下,希望對大家有所幫助

調(diào)用函數(shù)時,計算機常用棧來存儲傳遞給函數(shù)的參數(shù)。

棧是一種先進后出的數(shù)據(jù)結(jié)構(gòu),棧有一個存儲區(qū)、一個棧頂指針。棧頂指針指向堆棧中第一個可用的數(shù)據(jù)項(被稱為棧頂)。用戶可以在棧頂上方向棧中加入數(shù)據(jù),這個操作被稱為壓棧(Push),壓棧以后,棧頂自動變成新加入數(shù)據(jù)項的位置,棧頂指針也隨之修改。用戶也可以從堆棧中取走棧頂,稱為彈出棧(pop),彈出棧后,棧頂下的一個元素變成棧頂,棧頂指針隨之修改。函數(shù)調(diào)用時,調(diào)用者依次把參數(shù)壓棧,然后調(diào)用函數(shù),函數(shù)被調(diào)用以后,在堆棧中取得數(shù)據(jù),并進行計算。函數(shù)計算結(jié)束以后,或者調(diào)用者、或者函數(shù)本身修改堆棧,使堆棧恢復(fù)原裝。

在參數(shù)傳遞中,有兩個重要的問題必須要明確說明:

1. 當(dāng)參數(shù)個數(shù)多于一個時,按照什么順序把參數(shù)壓入堆棧;

2. 函數(shù)調(diào)用后,由誰來把堆?;謴?fù)原狀。


在高級語言中,就是通過函數(shù)的調(diào)用方式來說明這兩個問題的。常見的調(diào)用方式有:

stdcall

cdecl

fastcall

thiscall

thiscall

naked call


下面就分別介紹這幾種調(diào)用方式:
 

1. stdcall

stdcall調(diào)用方式又被稱為Pascal調(diào)用方式。在Microsoft C++系列的C/C++編譯器中,使用PASCAL宏,WINAPI宏和CALLBACK宏來指定函數(shù)的調(diào)用方式為stdcall。

stdcall調(diào)用方式的函數(shù)聲明為:

int _stdcall function(int a, int b);

stdcall的調(diào)用方式意味著:

(1) 參數(shù)從右向左一次壓入堆棧

(2) 由被調(diào)用函數(shù)自己來恢復(fù)堆棧

(3) 函數(shù)名自動加前導(dǎo)下劃線,后面緊跟著一個@,其后緊跟著參數(shù)的尺寸

上面那個函數(shù)翻譯成匯編語言將變成:

push b     先壓入第二個參數(shù)

push a     再壓入第一個參數(shù)

call function   調(diào)用函數(shù)


在編譯時,此函數(shù)的名字被翻譯為_function@8


2. cdecl

cdecl調(diào)用方式又稱為C調(diào)用方式,是C語言缺省的調(diào)用方式,它的語法為:

int function(int a, int b)  // 不加修飾符就是C調(diào)用方式

int _cdecl function(int a, int b)  // 明確指定用C調(diào)用方式

cdecl的調(diào)用方式?jīng)Q定了:

(1) 參數(shù)從右向左依次壓入堆棧

(2) 由調(diào)用者恢復(fù)堆棧

(3) 函數(shù)名自動加前導(dǎo)下劃線

由于是由調(diào)用者來恢復(fù)堆棧,因此C調(diào)用方式允許函數(shù)的參數(shù)個數(shù)是不固定的,這是C語言的一大特色。

此方式的函數(shù)被翻譯為:

push b   // 先壓入第二個參數(shù)

push a   // 在壓入第一個參數(shù)

call funtion  // 調(diào)用函數(shù)

add  esp, 8   // 清理堆棧


在編譯時,此方式的函數(shù)被翻譯成:_function
 

3. fastcall

fastcall 按照名字上理解就可以知道,它是一種快速調(diào)用方式。此方式的函數(shù)的第一個和第二個DWORD參數(shù)通過ecx和edx傳遞,

后面的參數(shù)從右向左的順序壓入棧。

被調(diào)用函數(shù)清理堆棧。

函數(shù)名修個規(guī)則同stdcall

其聲明語法為:

int fastcall function(int a, int b);


4. thiscall

thiscall 調(diào)用方式是唯一一種不能顯示指定的修飾符。它是c++類成員函數(shù)缺省的調(diào)用方式。由于成員函數(shù)調(diào)用還有一個this指針,因此必須用這種特殊的調(diào)用方式。

thiscall調(diào)用方式意味著:

參數(shù)從右向左壓入棧。

如果參數(shù)個數(shù)確定,this指針通過ecx傳遞給被調(diào)用者;如果參數(shù)個數(shù)不確定,this指針在所有參數(shù)壓入棧后被壓入棧。

參數(shù)個數(shù)不定的,由調(diào)用者清理堆棧,否則由函數(shù)自己清理堆棧。

可以看到,對于參數(shù)個數(shù)固定的情況,它類似于stdcall,不定時則類似于cdecl。
 

5. naked call

是一種比較少見的調(diào)用方式,一般高級程序設(shè)計語言中不常見。


函數(shù)的聲明調(diào)用方式和實際調(diào)用方式必須一致,必然編譯器會產(chǎn)生混亂。


函數(shù)名字修改規(guī)則:

1. C編譯時函數(shù)名修飾約定規(guī)則:

__stdcall調(diào)用約定在輸出函數(shù)名前加上一個下劃線前綴,后面加上一個“@”符號和其參數(shù)的字節(jié)數(shù),格式為_function@8。

__cdecl調(diào)用約定僅在輸出函數(shù)名前加上一個下劃線前綴,格式為_function。

__fastcall調(diào)用約定在輸出函數(shù)名前加上一個“@”符號,后面也是一個“@”符號和其參數(shù)的字節(jié)數(shù),格式為@function@8。

它們均不改變輸出函數(shù)名中的字符大小寫,這和PASCAL調(diào)用約定不同,PASCAL約定輸出的函數(shù)名無任何修飾且全部大寫。

2. C++編譯時函數(shù)名修飾約定規(guī)則:

__stdcall調(diào)用約定:

(1)以“?”標(biāo)識函數(shù)名的開始,后跟函數(shù)名;

(2)函數(shù)名后面以“@@YG”標(biāo)識參數(shù)表的開始,后跟參數(shù)表;

(3)參數(shù)表以代號表示:

X--void ,

D--char,

E--unsigned char,

F--short,

H--int,

I--unsigned int,

J--long,

K--unsigned long,

M--float,

N--double,

_N--bool,

....

PA--表示指針,后面的代號表明指針類型,如果相同類型的指針連續(xù)出現(xiàn),以“0”代替,一個“0”代

表一次重復(fù);

(4)參數(shù)表的第一項為該函數(shù)的返回值類型,其后依次為參數(shù)的數(shù)據(jù)類型,指針標(biāo)識在其所指數(shù)據(jù)類型前;

(5)參數(shù)表后以“@Z”標(biāo)識整個名字的結(jié)束,如果該函數(shù)無參數(shù),則以“Z”標(biāo)識結(jié)束。

其格式為“?functionname@@YG*****@Z”或“?functionname@@YG*XZ”,例如

int Test1(char *var1,unsigned long)-----“?Test1@@YGHPADK@Z”

void Test2() -----“?Test2@@YGXXZ”


__cdecl調(diào)用約定:

規(guī)則同上面的_stdcall調(diào)用約定,只是參數(shù)表的開始標(biāo)識由上面的“@@YG”變?yōu)椤癅@YA”。
 

__fastcall調(diào)用約定:

規(guī)則同上面的_stdcall調(diào)用約定,只是參數(shù)表的開始標(biāo)識由上面的“@@YG”變?yōu)椤癅@YI”。


VC++對函數(shù)的省缺聲明是"__cedcl",將只能被C/C++調(diào)用。

相關(guān)文章

  • C++單例模式應(yīng)用實例

    C++單例模式應(yīng)用實例

    這篇文章主要介紹了C++單例模式應(yīng)用實例,詳細講述了單例模式的原理與結(jié)構(gòu),及相關(guān)的打印機應(yīng)用實例,需要的朋友可以參考下
    2014-10-10
  • 詳析C++中的auto

    詳析C++中的auto

    這篇文章主要介紹了詳析C++中的auto,auto是具有自動存儲器的局部變量,C++11中,標(biāo)準(zhǔn)委員會賦予了auto全新的含義即:auto不再是一個存儲類型指示符,而作為一個新的類型指示符來指示編譯器,下面來看看文章的詳細介紹吧
    2022-01-01
  • c++結(jié)構(gòu)體排序方式(1條件,多條件)

    c++結(jié)構(gòu)體排序方式(1條件,多條件)

    這篇文章主要介紹了c++結(jié)構(gòu)體排序方式(1條件,多條件),具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • C語言?八大排序算法的過程圖解及實現(xiàn)代碼

    C語言?八大排序算法的過程圖解及實現(xiàn)代碼

    排序是數(shù)據(jù)結(jié)構(gòu)中很重要的一章,本文主要為大家介紹了常用的八個排序算法(插入,希爾,選擇,堆排,冒泡,快排,歸并,計數(shù))的過程及代碼實現(xiàn),需要的朋友可以參考一下
    2021-12-12
  • Windows進程崩潰問題的定位方法

    Windows進程崩潰問題的定位方法

    這篇文章主要介紹了Windows進程崩潰問題的定位方法,本文使用nstd工具進行進程崩潰時內(nèi)存和堆棧轉(zhuǎn)儲的方法查明問題所在,需要的朋友可以參考下
    2015-04-04
  • C++初階教程之缺省參數(shù)與函數(shù)重載

    C++初階教程之缺省參數(shù)與函數(shù)重載

    缺省參數(shù)是聲明或定義函數(shù)時為函數(shù)的參數(shù)指定一個缺省值,在調(diào)用該函數(shù)時如果沒有指定實參則采用該形參的缺省值,否則使用指定的實參,這篇文章主要給大家介紹了關(guān)于C++初階之缺省參數(shù)與函數(shù)重載的相關(guān)資料,需要的朋友可以參考下
    2023-04-04
  • 淺談C語言之字符串處理函數(shù)

    淺談C語言之字符串處理函數(shù)

    下面小編就為大家?guī)硪黄獪\談C語言之字符串處理函數(shù)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2016-08-08
  • C++異常捕捉與處理的深入講解

    C++異常捕捉與處理的深入講解

    這篇文章主要給你大家介紹了關(guān)于C++異常捕捉與處理的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-10-10
  • C語言實現(xiàn)交換排序算法(冒泡,快速排序)的示例代碼

    C語言實現(xiàn)交換排序算法(冒泡,快速排序)的示例代碼

    這篇文章主要為大家詳細介紹了如何利用C語言實現(xiàn)交換排序算法(冒泡排序、快速排序),文中的示例代碼講解詳細,感興趣的小伙伴可以了解一下
    2022-07-07
  • 關(guān)于C/C++中typedef的定義與用法總結(jié)

    關(guān)于C/C++中typedef的定義與用法總結(jié)

    在C還是C++代碼中,typedef都使用的很多,在C代碼中尤其是多,typedef與#define有些相似,其實是不同的,特別是在一些復(fù)雜的用法上,需要的朋友可以參考下
    2012-12-12

最新評論