c c 的引數壓棧順序

2021-05-28 08:02:26 字數 1650 閱讀 5045

曾經看到一篇文章上面說:c/c++引數壓棧順序是從右到左,pascal引數壓棧是從左到右.

為了這句話丟了很多次人.無所謂了,反正咱臉皮厚.

總結一下:編譯出來的c/c++程式的引數壓棧順序只和編譯器相關!

下面列舉了一些常見的編譯器的呼叫約定

vc6:

呼叫約定        堆疊清除    引數傳遞

__cdecl                  呼叫者      從右到左,通過堆疊傳遞

__stdcall                  函式體         從右到左,通過堆疊傳遞

__fastcall                 函式體         從右到左,優先使用暫存器(ecx,edx),然後使用堆疊

thiscall                     函式體         this指標預設通過ecx傳遞,其它引數從右到左入棧

__cdecl是c/c++的預設呼叫約定; vc的呼叫約定中並沒有thiscall這個關鍵字,它是類成員函式預設呼叫約定;

c/c++中的main(或wmain)函式的呼叫約定必須是__cdecl,不允許更改;

預設呼叫約定一般能夠通過編譯器設定進行更改,如果你的**依賴於呼叫約定,請明確指出需要使用的呼叫約定;

c++builder6:

呼叫約定        堆疊清除    引數傳遞

__fastcall                  函式體      從左到右,優先使用暫存器(eax,edx,ecx),然後使用堆疊 (相容delphi的register)

(register與__fastcall等同)

__pascal                     函式體      從左到右,通過堆疊傳遞

__cdecl                    呼叫者    從右到左,通過堆疊傳遞(與c/c++預設呼叫約定相容)

__stdcall                     函式體      從右到左,通過堆疊傳遞(與vc中的__stdcall相容)

__msfastcall                函式體      從右到左,優先使用暫存器(ecx,edx),然後使用堆疊(相容vc的__fastcall)

由於能力和資源有限,只能找到這些東西,主要的差異體現在fastcall上面,vc是前兩個引數放入暫存器,後面的壓棧,bcb是前3哥引數使用暫存器,

更有**的,乙個朋友朋友說有的引數超過7個以後前5個從左到右傳遞,後面的從右到走,上面說的不可不信,不可全信.

如何確定你的編譯採用的那種順序那?

#include

int f(int i,int j,int k);

int main()

int f(int i,int j,int k)

看看k->i的位址的增長順序和l->g的順序是否相同,如果相同則是從右到左,否則從左到右.

ps:本來通過列印引數的值來判斷那個先入棧,結果被乙個朋友批評了,

他說:壓棧順序和引數計算順序不是一回事,所以還是看位址更***.

int __cdecl add(int a,int b) ;

int  add(int a,int b) (__cdecl);

C C 函式引數壓棧順序

函式引數的壓棧順序,一般由編譯器決定,不同的編譯器可能規則不一樣。但是一般情況下,是從右到左。談一談printf 函式,printf函式的原型是 printf const char format,沒錯,它是乙個不定參函式,那麼我們在實際使用中是怎麼樣知道它的引數個數呢?這就要靠format了,編譯器...

c c 的函式引數壓棧順序

c c 的函式引數壓棧順序 c c 的函式引數壓棧順序.曾看到一篇文章上面說 c c 引數壓棧順序是從右到左,pascal引數壓棧是從左到右.為了這句話丟了很多次人.無所謂了,反正咱臉皮厚.總結一下 編譯出來的c c 程式的引數壓棧順序只和編譯器相關 下面列舉了一些常見的編譯器的呼叫約定 vc6 呼...

C語言printf及引數壓棧順序

1.呼叫格式為 printf 格式化字串 參量表 其中格式化字串包括兩部分內容 一部分是正常字元,這些字元將按原樣輸出 另一部分是格式化規定字元,以 開始,後跟乙個或幾個規定字元,用來確定輸出內容格式。參量表是需要輸出的一系列引數,其個數必須與格式化字串所說明的輸出引數個數一樣多,各引數之間用 分開...