X86 X64 函式呼叫約定

2022-07-16 15:54:09 字數 2304 閱讀 2465

c 語言有 __cdecl、__stdcall、__fastcall、naked、__pascal。

c++ 語言有 __cdecl、__stdcall、__fastcall、naked、__pascal、__thiscall,比 c 語言多出一種 __thiscall 呼叫方式。

下面詳細介紹如上六種呼叫方式:

1、__cdecl

__cdecl呼叫約定又稱為 c 呼叫約定,是 c/c++ 語言預設的呼叫約定。表示c語言預設的函式呼叫方法,引數按照從右至左的方式入棧,函式本身不清理棧,此工作由呼叫者負責,返回值在eax中。由於由呼叫者清理棧,所以允許可變引數函式存在,如int sprintf(char* buffer,const char* format,...);。

2、__stdcall

__stdcall 很多時候被稱為 pascal 呼叫約定。是standardcall的縮寫,是c++的標準呼叫方式。pascal 語言是早期很常見的一種教學用計算機程式語言。所有引數從右到左依次入棧,如果是呼叫類成員的話,最後乙個入棧的是this指標。這些堆疊中的引數由被呼叫的函式在返回時清除,使用的指令是 retnx,x表示引數占用的位元組數,cpu在ret之後自動彈出x個位元組的堆疊空間。稱為自動清棧。函式在編譯的時候就必須確定引數個數,並且呼叫者必須嚴格的控制引數的生成,不能多,不能少,否則返回後會出錯。返回值在eax中

3、__fastcall

顧名思義,__fastcall 的特點就是快,因為它通過 cpu 暫存器來傳遞引數。他用 ecx 和 edx 傳送前兩個雙字(dword)或更小的引數,剩下的引數按照從右至左的方式入棧,函式自身清理堆疊,返回值在 eax 中。

4、naked

naked 是乙個很少見的呼叫約定,一般不建議使用。編譯器不會給這種函式增加初始化和清理**,更特殊的是,你不能用return返回返回值,只能用插入彙編返回結果,此呼叫約定必須跟 __declspec 同時使用。例如定義乙個求和程式,如__declspec(naked) int  add(int a,int b);。

5、__pascal

這是 pascal 語言的呼叫約定,跟 __stdcall 一樣,引數按照從右至左的方式入棧,函式自身清理堆疊,返回值在eax中。vc 中已經廢棄了這種呼叫方式,因此在寫 vc 程式時,建議使用 __stdcall 代替。

6、__thiscall

這是 c++ 語言特有的一種呼叫方式,用於類成員函式的呼叫約定。如果引數確定,this 指標存放於 ecx 暫存器,函式自身清理堆疊;如果引數不確定,this指標在所有引數入棧後再入棧,呼叫者清理棧。__thiscall 不是關鍵字,程式設計師不能使用。引數按照從右至左的方式入棧。

注意

_fastcall 和 __thiscall涉及的暫存器由編譯器決定,因此不能用作跨編譯器的介面。所以windows上的com物件介面都定義為_stdcall呼叫方式。

針對引數列表型別的函式。即可變引數函式:

為什麼只有__cdecl的呼叫約定支援可變引數,而__stdcall就不支援?

實際上__cdecl和__stdcall函式引數都是從右到左入棧,它們的區別在於由誰來清棧,__cdecl由外部呼叫函式清棧,而__stdcall由被呼叫函式本身清棧, 顯然對於可變引數的函式,函式本身沒法知道外部函式呼叫它時傳了多少引數,所以沒法支援被呼叫函式本身清棧(__stdcall), 所以可變引數只能用__cdecll.

1.從右到左依次入棧:__stdcall,__cdecl,__thiscall,__fastcall

2.從左到右依次入棧:__pascal

1.呼叫者清除棧。

2.被呼叫函式返回後清除棧。

x64下

呼叫約定簡化了:一律使用__fastcall,前四個引數用 rcx、rdx、r8 和 r9傳遞,除了這四個外加rax、r10、r11,其他暫存器都是非易失的。

x86,x64表示什麼含義

簡單的說x86代表32位作業系統 x64代表64位作業系統 windows7 32位和64位的區別主要有以下兩個方面 1.兩種系統對cpu gprs的資料寬度要求不同,乙個是64位,乙個是32位 如果你的cpu是雙核以上,那肯定支援64位作業系統了 2.對記憶體的要求,64位支援4g及以上記憶體的電...

X86 X64 讀取rflags的方法

工作中遇到的問題,需要讀取rflags的值然後顯示的列印出來。翻了sdm的指令卷,找到了lahf指令,這個指令可以把rflags的值寫入ah暫存器中,那麼問題來了,ah暫存器只有8位,但是rflags在保護模式或者x64模式是32位 64位的,來看下sdm的說明 可知,確實只擷取了rflags的低8...

《x86 x64體系探索及程式設計》試讀

現在正在和一些朋友研究 os 核心 基於haiku 當然,這些研究只是作為興趣 有興趣的朋友可以在iteye上發郵件給我,一起研究,編譯器方向的也熱烈歡迎!在研究的過程中,需要對像 x86 64 的底層要有一定的了解。現在還是在看的 深入理解計算機系統 intel 處理器等書還沒接觸到。在看了這本書...