c/c++的函式引數壓棧順序
c/c++的函式引數壓棧順序.
曾看到一篇文章上面說: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)
上述資料**於housisong的一篇文章:http://www.allaboutprogram.com/index.php?option=content&task=view&id=29&itemid=31.
由於能力和資源有限,只能找到這些東西,主要的差異體現在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:本來通過列印引數的值來判斷那個先入棧,結果被乙個朋友批評了,
他說:壓棧順序和引數計算順序不是一回事,所以還是看位址更有確保.
//看過的朋友當作笑談吧。
C C 函式引數壓棧順序
函式引數的壓棧順序,一般由編譯器決定,不同的編譯器可能規則不一樣。但是一般情況下,是從右到左。談一談printf 函式,printf函式的原型是 printf const char format,沒錯,它是乙個不定參函式,那麼我們在實際使用中是怎麼樣知道它的引數個數呢?這就要靠format了,編譯器...
c c 的引數壓棧順序
曾經看到一篇文章上面說 c c 引數壓棧順序是從右到左,pascal引數壓棧是從左到右.為了這句話丟了很多次人.無所謂了,反正咱臉皮厚.總結一下 編譯出來的c c 程式的引數壓棧順序只和編譯器相關 下面列舉了一些常見的編譯器的呼叫約定 vc6 呼叫約定 堆疊清除 引數傳遞 cdecl 呼叫者 從右到...
C C 語言函式中引數的入棧順序
對於函式,之前認為會用就行了,對其中的原理並不是很了解,就比如函式中引數的入棧順序 在這說明一下,函式的引數是儲存在棧中的,還有一些區域性變數也是存放在棧中 這個問題 於某網際網路的面試題,當然答得很不好,查了很多大牛的部落格做一下總結。include using namespace std voi...