_stdcall,_cdecl,_fastcall

参数入栈顺序:

  两者都是从右到左。

 

参数出栈区域:

  _stdcall是在函数内部清理释放栈。更好的封装性。

  _cdecl是在调用函数的地方释放,所有每个调用的地方都有一块弹出栈空间的代码,编译出来的程序较大。

 

名称修饰:

  除了与_stdcall, _cdecl有关,还与是否用C或C++导出有关

  1. C方式编辑,即(extern ‘C’)

    a. _stdcall : _函数名@参数字节数

      eg: void func(int a, int b): _func@8

    b. _cdecl: 与原名称相同

      eg:void func(int a, int b):  func

 

  2. C++方式编译,即(extern 'C++')

     a. _stdcall: 

      1) 以?开头

      2) 原名称后接@@YG

      3) 再接返回值代号和参数代号

        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,

      4) 再接@Z表示结束

      eg:void func(int a, int b):  ?func@@YGXHH@Z

    b. _cdecl

      与_stdcall规则相同,只是参数表的开始标识由上面的“@@YG”变为“@@YA”

 

使用场景:

  __stdcall通常用于Windows API中

#elif (_MSC_VER >= 800) || defined(_STDCALL_SUPPORTED)
#define CALLBACK    __stdcall
#define WINAPI      __stdcall

 

  VS中默认的调用方式是_cdecl, 在属性页,C/C++,调用约定下设置。

 

特殊场景;

  对于可变参数,由于函数内部不知道有几个参数,也就无法做清理的工作,只能由调用者来做,所以可变参数是按照cdecl的约定方式。

  

使用较少的调用约定:

  _fastcall:

  特点就是快,因为是前两个参数是通过寄存器传递的

  格式:@函数名@参数字节数

  前两个参数或更小的两个参数的传递顺序是按照从左到右的顺序,其他参数是按照从右到左的顺序。

 

  _vectorcall:

  目的是优化浮点向量运算,intel处理器种有很多浮点向量寄存器,传统的浮点参数需要从栈上获取

  _vectorcall 直接从寄存器上传递参数

  _vectorcall是集成_fastcall的

   

 

posted @ 2021-12-27 17:41  Dylan_Liang  阅读(59)  评论(0编辑  收藏  举报