cdecl&stdcall

cdecl

cdecl的caller才回去清理stack。生成的exe会比较大。

参数传递方式是从右到左,caller有责任pop stack

规范上,Underscore character (_) is prefixed to names, except when __cdecl functions that use C linkage are exported.

放在函数名之前来修饰,默认是C语言的调用规范,如果加了其他的调用规范参数需要在函数名之前添加修饰。

其他的调用规范为/ /Gv (vectorcall), /Gz (stdcall), or /Gr (fastcall) 

The /Gd compiler option forces the __cdecl calling convention.

在arm 或者是x64的cpu上,_cdecl能接受,但是会被忽略。

因为在arm或者是x64上会尽可能的使用寄存器来传参,剩余的会使用stack

x64的代码中,使用__cdecl来重载/Gv 编译器选项,然后会默认使用x64默认的规范

使用:

// Example of the __cdecl keyword on function  
int __cdecl system(const char *);  
// Example of the __cdecl keyword on function pointer  
typedef BOOL (__cdecl *funcname_ptr)(void * arg1, const char * arg2, DWORD flags, ...);

stdcall

The __stdcall calling convention is used to call Win32 API functions. The callee cleans the stack, so the compiler makes vararg functions __cdecl. Functions that use this calling convention require a function prototype.

入栈是从右到左。

传值立即数,除非是指针引用

callee被调用者自己弹栈stack

命名修饰上

An underscore (_) is prefixed to the name. The name is followed by the at sign (@) followed by the number of bytes (in decimal) in the argument list. Therefore, the function declared as int func( int a, double b ) is decorated as follows: _func@12

函数名之前有_func之后跟@ ,之后跟参数的字节数

例如

int  func(int a,double b)的就是_func@12

/Gz编译器指定__stdcall约定。

同样arm和x64会被接收但是会被忽略,传值优先寄存器之后stack

非静态调用下,不用再dll ,so那一层来添加修饰__stdcall。

只用在使用的一层添加就好了,比如头文件声明部分。

例如

// Example of the __stdcall keyword

#define WINAPI __stdcall

// Example of the __stdcall keyword on function pointer

typedef BOOL (__stdcall *funcname_ptr)(void * arg1, const char * arg2, DWORD flags, ...);

__fastcall

x86下,尽可能使用fastcalll

The first two DWORD or smaller arguments that are found in the argument list from left to right are passed in ECX and EDX registers; all other arguments are passed on the stack from right to left.

在参数表从左到右中找到两个dword或者小的参数,会传入ECX和EDX寄存器,

所有其他的会被传入stack从右到左。

依然是被调用的函数自己pop栈

修饰是依照上边的例子func函数的修饰后是@func@12

用/Gr来制定编译器选项,

The __fastcall keyword is accepted and ignored by the compilers that target ARM and x64 architectures; on an x64 chip, by convention, the first four arguments are passed in registers when possible, and additional arguments are passed on the stack. For more information, see Overview of x64 Calling Conventions. On an ARM chip, up to four integer arguments and eight floating-point arguments may be passed in registers, and additional arguments are passed on the stack.

例如


// Example of the __fastcall keyword  
#define FASTCALL    __fastcall  


void FASTCALL DeleteAggrWrapper(void* pWrapper);  
// Example of the __ fastcall keyword on function pointer  
typedef BOOL (__fastcall *funcname_ptr)(void * arg1, const char * arg2, DWORD flags, ...);

REFER:

https://docs.microsoft.com/en-us/cpp/cpp/results-of-calling-example


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值