调用约定(calling convention)和名称修饰(name decoration)

参考: https://blog.csdn.net/bird67/article/details/4019044
调用约定(calling Convention)是指在程序设计语言中为了实现函数调用而建立的一种协议。这种协议规定了该语言的函数中的参数传送方式、参数是否可变和由谁来处理堆栈等问题。不同语言定义了不同的调用约定。
在C++中,为了允许操作符重载和函数重载,C++编译器往往按照某种规则改写每一个入口点的富豪命,以便允许同一个名字(具有不同的参数类型或者是不同的作用域)有多个用法,而不会打破现有的基于C的链接器。这项技术通常被称为名称改编(Name Mangling)或者名称修饰(Name Decoration)许多C++编译器厂商选择了自己的名称修饰方案。
因此,为了使其它语言编写的模块(如Visual Basic应用程序、Pascal或Fortran的应用程序等)可以调用C/C++编写的DLL的函数,必须使用正确的调用约定来导出函数,并且不要让编译器对要导出的函数进行任何名称修饰。
调用约定(Calling Convention)
1. __cdecl
__cdecl是C/C++和MFC程序默认使用的调用约定,也可以在函数声明时加上__cdecl关键字来手动指定。采用__cdecl约定时,函数参数按照
从右到左的顺序入栈
,并且由调用函数者把参数弹出栈以清理堆栈。因此,实现可变参数的函数只能使用该调用约定。由于每一个使用__cdecl约定的函数都要包含清理堆栈的代码,所以产生的可执行文件大小会比较大。__cdecl可以写成_cdecl。
2. __stdcall
__stdcall调用约定用于Win32API函数。采用__stdcal约定时,函数参数按照从右到左的顺序入栈被调用的函数在返回前清理传送参数的栈,函数参数个数固定。由于函数体本身知道传进来的参数个数,因此被调用的函数可以在返回前用一条ret n指令直接清理传递参数的堆栈。__stdcall可以写成_stdcall。
3. __fastcall
__fastcall约定对于性能要求非常高的场合。__fastcall约定将函数的从左边开始的两个大小不大于4个字节(DWORD)的参数分别放在ECX和EDX寄存器,其余的参数仍旧自右向左压栈传送被调用的函数在返回前清理传送参数的堆栈。__fastcall可以写成_fastcall。
4. thiscall
thiscall调用约定是C++中的非静态类成员函数的默认调用约定。thiscall只能被编译器还是用,没有相应的关键字,因此不能被程序员指定。采用thiscall约定时,函数参数按照从右到左的顺序入栈被调用的函数在返回前清理传送的栈,只是另外通过ECX寄存器传送一个额外的参数:this指针。
5. naked属性
采用上面所述的四种调用约定的函数在进入函数时,编译器会产生代码保存ESI、EDI、EBX、EBP寄存器中的值,退出函数时则产生代码恢复这些寄存器的内容。对于定义了naked属性的函数,编译器不会自动产生这样的代码,需要你手动使用内嵌汇编来控制函数实现中的堆栈管理。由于naked属性并不是类型修饰符,故必须和_declspec共同使用
编译时函数名称修饰

当函数使用__cdecl调用约定时,编译器仅在原函数名前加上一个下划线前缀,格式为_functionname。例如:函数int __cdecl Add(int a, int b),输出后为:_Add。

当函数使用__stdcall调用约定时,编译器在原函数名前加上一个下划线前缀,后面加上一个@符号和函数参数的字节数,格式为_functionname@number。例如:函数int __stdcall Add(int a, int b),输出后为:_Add@8。

当函数是用__fastcall调用约定时,编译器在原函数名前加上一个@符号,后面是加一个@符号和函数参数的字节数,格式为@functionname@number。例如:函数int __fastcall Add(int a, int b),输出后为:@Add@8。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值