日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > c/c++ >内容正文

c/c++

CC++ Calling Convention

發(fā)布時間:2025/3/15 c/c++ 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 CC++ Calling Convention 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

tkorays(tkorays@hotmail.com)

?

調(diào)用約定(Calling Convention) 是計算機編程中一個比較底層的設(shè)計,它主要涉及:

  • 函數(shù)參數(shù)通過寄存器傳遞還是棧?
  • 函數(shù)參數(shù)從左到右還是從右到左壓棧?
  • 是否支持可變參數(shù)函數(shù)(vararg function or variadic function)。
  • 是否需要函數(shù)原型?
  • 怎么修飾函數(shù)名,唯一標(biāo)識函數(shù)?
  • 調(diào)用者(caller)還是被調(diào)用者(called or callee)清理堆棧?

1. Calling Conventions

在C和C++中有幾種調(diào)用約定:__cdecl, __stdcall, __fastcall, __thiscall, __clrcall, __vectorcall。下面首先介紹幾種調(diào)用約定。

1.1 __cdecl

C Declaration Calling Convention,C聲明調(diào)用約定。它是C和C++默認(rèn)的調(diào)用約定。特點:

  • 堆棧由調(diào)用者清除(手動清除)。
  • 參數(shù)從右到左壓棧。
  • 支持可變參數(shù)(函數(shù)自己并不知道自己有多少個參數(shù),因此需要調(diào)用者來清除)。
  • 編譯后函數(shù)名改編為:“_函數(shù)名”。如_funcname。

1.2 __stdcall

Standard Calling Convention,標(biāo)準(zhǔn)調(diào)用約定。又稱為Pascal Convention。特點:

  • 被調(diào)用函數(shù)自動將參數(shù)彈出棧。
  • 參數(shù)從右到坐壓棧(和__cdecl一樣),如果調(diào)用類的成員函數(shù),最后壓入this指針。
  • 需要一個函數(shù)原型,不支持變參函數(shù)。
  • 函數(shù)名改編:“_函數(shù)名@參數(shù)字節(jié)大小十進制”。如_funcname@8。

1.3 __fastcall

Fast Calling Convention,快速調(diào)用約定。通過使用寄存器解決效率問題。特點:

  • 函數(shù)參數(shù)部分通過寄存器傳遞,函數(shù)中最左的兩個DWORD(寄存器大小是雙字)或者更小的參數(shù),通過寄存器傳遞。剩下的從右到左堆棧傳遞。
  • 函數(shù)名改編:“@函數(shù)名@函數(shù)參數(shù)字節(jié)大小十進制”。
  • 返回方式同__stdcall。

1.4 __thiscall

主要用于x86系統(tǒng)中C++的類的成員函數(shù)調(diào)用,使用寄存器ecx來傳遞this指針。參數(shù)從右往左壓棧,返回方式同__stdcall,由被調(diào)用者自己清除堆棧。

1.5 __clrcall

__clrcall是C++ .Net里面的。

1.6 __vectorcall

要求盡可能在寄存器中傳遞參數(shù)。函數(shù)名改編為”@@函數(shù)名@參數(shù)字節(jié)數(shù)十進制”。這是微軟自己添加的標(biāo)準(zhǔn)。 總結(jié)

除了__cdecl(以及__clrcall),其他的都是被調(diào)用者清除堆棧。

2. 函數(shù)名修飾

2.1 C++中函數(shù)名修飾

在C語言中不存在重載,因此不需要擔(dān)心同名函數(shù)問題,但是在C++中,使用C中的函數(shù)名修飾方式就存在問題。對于重載的函數(shù),僅僅憑函數(shù)名和參數(shù)內(nèi)存大小無法完全區(qū)分;類的成員函數(shù)表示并沒有說明。所以在C++中,對于函數(shù)名改編需要一套策略。函數(shù)名格式大致如?FuncName@@YGXZ這種形式。

  • 修飾名以?開始,后面接函數(shù)名。
  • 函數(shù)名后為@@YG、@@YA、@@YI,分別代表stdcall、cdecl、fastcall。
  • @@YG等后面接著參數(shù)類型字符,第一個表示返回值類型。
  • 字符串以@Z結(jié)束,如果函數(shù)沒有參數(shù),則直接以Z結(jié)束。

參數(shù)符號如下:

  • X: void
  • D: char
  • E: unsigned char
  • F: short
  • H: int
  • I: unsigned int
  • J: long
  • K: unsigned long
  • M: float
  • N: double
  • _N: bool
  • PA: 指針
  • PB: const指針
  • U: struct

所以int __stdcall fa();可以改編為:?fa@@YGHXZ;char* fb(int,bool);改編為?fb@@YAPADH_N@Z。

所以在C++中函數(shù)名改編和C不同,如果需要遵循C中的改編方式,可以使用extern "C"{}。

2.2 C++成員函數(shù)名修飾

類的成員函數(shù)的調(diào)用方式為thiscall,其函數(shù)名修飾方式和普通函數(shù)有些差別。成員函數(shù)名改編需在函數(shù)名和參數(shù)中間插入類名。且需要指定函數(shù)一些性質(zhì),如

  • public為@@QAE,protected為@@IAE,private為@@AAE
  • 如果函數(shù)聲明為const,則public為@QBE,protected為@@IBE,private為@@ABE
  • 如果參數(shù)類型是類實例的引用,則使用“AAV1”,const引用則為ABV1

如:

  • ?FuncA@ClassA@@QAEXH@Z表示void ClassA::FuncA(int);。
  • ?FuncB@ClassA@@QAEXABV1@Z表示void ClassA::FuncB(const ClassA&);

轉(zhuǎn)載于:https://www.cnblogs.com/tkorays/p/C_Cpp_Calling_Convention.html

總結(jié)

以上是生活随笔為你收集整理的CC++ Calling Convention的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。