__stdcall 、__cdecl、__fastcall三者的區別

今天重讀《windows程序設計 第五版》(作者:Charles Petzold) 時,WINAPI 被定義爲__stdcall,一回想發現忘記了__stdcall的集體含義。於是查閱下相關資料。

學習過彙編的童鞋都知道,函數調用要用到stack(棧:一種後進先出的線性結構)。先簡單回憶下函數的調用過程(以X86結構爲例):

1.將函數的參數按照從右往左的順序依次壓入stack(棧)中。

2.將當前IP寄存器(調用者當前指令地址(從com角度來說叫客戶的當前的客戶指令地址))的值壓入stack(棧)中,將IP寄存值改變爲被調用函數的地址。

3.將被調用函數的局部變量壓入stack(棧)中。

4.將被調用函數的局部變量從stack(棧)中彈出。

5.將壓入棧的調用者當前指令地址+1存入IP寄存器中。

6.將EAX寄存器(一般用EAX保存函數的返回值)中的值存入被調用這的局部變量(或者全局變量中)。

7.將函數的參數從stack(棧)中彈出。

   __stdcall、__cdecl、__fastcall都是函數調用的協議(約束條件)。

1.__stdcall可以寫成_stdcall,參數採用從右至左邊入棧順序,由被調用函數本身將函數的參數從stack(棧)中彈出。

2.__cdecl可以寫成_cdecl,參數採用從右至左的順序的入棧順序,由函數的調用者將函數的參數從stack(棧)中彈出,一般用於變長參數的函數例如:printf。因爲被調用函數本身並不知道參數的個數,無法自身清楚堆棧。

3.__fastcall可以寫成_fastcall,將函數最左邊的兩個不超過2個雙字節(DWORD)參數存入ECX和EDX兩個寄存器中,其他參數仍按從右到左的順序壓入棧中。一般用於效率要求較高的場合。




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章