cdel和thiscall呼叫約定

2021-07-12 07:28:48 字數 2510 閱讀 1878

函式呼叫約定的作用

(1)規定了引數壓棧的順序;

(2) 規定由誰來清理堆疊

(3)規定函式返回值所放置的地方

1 _cdel呼叫(它是c語言預設的函式呼叫方法)

1)它的引數從右到左依次壓棧,函式本身並不清理堆疊,這些引數由呼叫者清理,是c語言預設的呼叫約定,它的定義語法是:

int

function (int a ,int b) // 不加修飾就是c呼叫約定

int __cdecl function(int a,int b) // 明確指出c呼叫約定

所以c呼叫約定允許函式的引數的個數是不固定的,這也是c語言的一大特色。對於前面的function函式,使用cdecl後的彙編碼變成:

呼叫處

push

2 // 第二個引數入棧

push

1 // 第乙個引數入棧

call function

add esp,8 //注意:這裡呼叫者在恢復堆疊

被呼叫函式_function處

push ebp // 儲存ebp暫存器,該暫存器將用來儲存堆疊的棧頂指標,可以在函式退出時恢復

mov ebp,esp // 儲存堆疊指標

mov eax,[ebp + 8h] //堆疊中ebp指向位置之前依次儲存有ebp,cs:eip,a,b,ebp +8指向a

add eax,[ebp + 0ch] 堆疊中ebp + 12處儲存了b

mov esp,ebp //恢復esp

pop ebp

ret //注意,這裡沒有修改堆疊

msdn中說,該修飾自動在函式名前加前導的下劃線,因此函式名在符號表中被記錄為_function。 由於引數按照從右向左順序壓棧,因此

最開始的引數在最接近棧頂的位置,因此當採用不定個數引數時,第乙個引數在棧中的位置肯定能知道,只要不定的引數個數能夠根據第乙個

後者後續的明確的引數確定下來,就可以使用不定引數,例如對於sprintf函式,定義為:

int sprintf(char* buffer,constchar* format,…)

由於所有的不定引數都可以通過format確定,因此使用不定個數的引數是沒有問題的。

具體的執行步驟是:

呼叫方的函式呼叫->被呼叫函式的執行->被呼叫函式的結果返回->呼叫方清除調整堆疊

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

thiscall是唯一乙個不能明確指明的函式修飾,因為thiscall不是關鍵字。它是c++類成員函式預設的呼叫約定。由於成員函式呼叫還有乙個預設的this指標,因此必須特殊處理,thiscall意味著:

1) 引數從右向左入棧;

2) 如果引數個數確定,this指標通過ecx傳遞給被呼叫者;如果引數個數不確定,this指標在所有引數壓棧後被壓入堆疊;

3) 對引數個數不定的,呼叫者清理堆疊,否則函式自己清理堆疊。

為了說明這個呼叫約定,定義如下類和使用**:

class a

;int a::function1 (int a,int b)

int a::function2(int a,...)

void callee()

callee函式被翻譯成彙編後就變成:

// 函式function1呼叫

0401c1d push 2

00401c1f push 1

00401c21 lea ecx,[ebp-8]

00401c24 call function1 注意,這裡this沒有被入棧

// 函式function2呼叫

00401c29 push 3

00401c2b push 2

00401c2d push 1

00401c2f push 3

00401c31 lea eax,[ebp-8] 這裡引入this指標

00401c34 push eax

00401c35 call function2

00401c3a add esp,14h

所依在引數個數不確定的時候thiscall的呼叫方式類似於—cdel

注意:

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

(2)帶有可變引數的函式必須且只能用—cdel的方式

thiscall與 cdecl呼叫方式

首先,thiscall 是關於類的一種呼叫方式,它與其他呼叫方式的最大區別是 thiscall對每個函式都增加了乙個類指標引數 class aa 實際上bb的函式原形是void bb aa this,int cc 這就是 thiscall的呼叫方式 cdecl c和c 預設呼叫方式 例子 void ...

輕鬆搞定 JS 的this call和apply

年前最後一篇文章,提前祝大家春節快樂。對了,還有369就要2018年了,提前祝大家2018年春節快樂。vr qbmbbbmbmy 8bbbbbobmbmv imbmm5voy bmbbv r,obm rbbbbby vul 7bb 7.lbmmbbm.wwz.uvir i ilmomobm.vv r...

簡單快速理解js中的this call和apply

注 本文案例環境為非嚴格模式,嚴格模式下禁止關鍵字this指向全域性物件 一 方法是怎麼執行的?首先說一下js中方法的執行,在window全域性下宣告乙個方法a function a a window全域性中執行這個方法普遍的方法是直接a 這個方法的執行環境是window,控制台會列印出window...