您的位置:首页 > 其它

cdecl&stdcall

2018-01-21 16:55 330 查看

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 
__stdc
925a
all
 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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: