c 編譯器常用的巨集

2021-05-24 09:40:50 字數 1310 閱讀 6559

今天,在學習iocp的時候,突然發現對c++編譯器的一些常用的巨集比較陌生,就稍微學習了一下。

ps:在vs 2005環境下,開啟「project → project settings」,選擇 c/c++ 選項卡,在「category」欄選擇「listing files」然後在listing file type欄選擇「assembly with machine code」。重新編譯工程後則可以在輸出目錄看到與每乙個.cpp檔案同名的.cod檔案

1、幾種函式呼叫的宣告方式

example:

_cdecl:全稱為c declaration。這是c 預設的函式呼叫的方式,呼叫這樣的函式時,所有引數從右向左壓棧,由呼叫者進行清棧,呼叫函式時,可以不明確引數的個數和型別,c++編譯器將不檢查這樣的不確定性,像printf和scanf就必須使用這種呼叫方式。

使用int _cdecl maxint(int x,int y)宣告方式編譯後的彙編**如下(關鍵看壓棧和返回階段):

呼叫者的彙編**:

由此,可以看出,所有引數是從右向左壓棧,並且由呼叫者清理棧。

_stdcall:全稱為standard call。是c++標準的呼叫方式,所有引數從右向左壓棧,this指標最後壓棧,被呼叫者自己清理棧,必須確定引數的個數和型別,呼叫者不能傳遞過多或者過少的引數。

使用int _stdcall maxint(int x,int y)宣告方式編譯後的彙編**如下:

呼叫函式時的彙編**:

由此可以看出,引數是從右向左壓棧,而且由被呼叫者自己清理棧。

_fastcall:快速呼叫,由於一般函式的引數個數都很好,所以使用這個方式可以把前面幾個(一般是兩個)引數直接放到暫存器中,其餘引數依然通過棧來傳遞,節省壓棧退棧時間,實現快速呼叫,返回方式和_stdcall一樣。

使用int _fastcall maxint(int x,int y)呼叫方式編譯後的彙編**如下:

呼叫該函式的彙編**如下:

由此可以看出,呼叫函式時,不用壓棧,被呼叫函式返回時,不用退棧。

__thiscall:這種呼叫方式是為了解決成員函式中this指標的傳遞而設定的,this指標被放在特定的暫存器中,這個特定的暫存器在不同的編譯器中式不一樣的,它只能用在c++類成員函式的呼叫方式,返回方式與_stdcall相當。

把example修改後如下:

修改後,maxint編譯後的彙編**如下:

呼叫該函式時的彙編**如下:

由此可以看出,在vs 2005下,使用ecx來傳遞this指標。

(未完待續)

C C 編譯器預定巨集使用

在c c 編譯器中,會有編譯器級別的預定義巨集,file line function date time 等。下面來一一介紹這幾個巨集的含義 file 當前檔案的檔名,linux下gcc只有檔名,而在windows下gcc會包含完整的路徑,可通過編譯選項設定為只有檔名 line 當前行號 funct...

GNU編譯器 gcc中的預編譯巨集

預定義的巨集 nase file 原始檔的完整路徑名,和 file 不同,被引用的檔案仍然是原來檔名 char unsigned 用於指定該機器上 char 是無符號型別 cplusplus 使用 c 編譯器編譯 date 編譯時的日期 file 編譯檔名 func 同 function gnuc ...

c 編譯器編譯過程

編譯過程 編譯過程分為四步 預處理 編譯 彙編 連線 1.預處理 預處理主要處理原始檔中的 include define 等預處理等命令 預處理主要完成的工作有 參考 程式設計師的自我修養 1 刪除 define,展開巨集 2 處理條件編譯指令。預處理程式先判斷條件,再根據條件修改源 3 刪除注釋 ...