C/C++函数调用规则

来源:互联网 发布:初音秘密警察知乎 编辑:程序博客网 时间:2024/05/02 02:21

面试中被问到函数调用规则,不懂,所以查了资料,总结如下:


调用规则

__cdecl

__stdcall

__fastcall

__pascal

__thiscall

参数压栈顺序

从右到左

从右到左

用ECX和EDX传送前两个双字(DWORD)或更小的参数,剩下的参数仍旧自右向左压栈传送

从左到右

从右到左

栈维护

函数调用者

函数本身

函数本身

函数本身

函数本身

返回值存放

EAX

EAX

EAX

EAX

EAX

C编译器名称修饰

函数名前加上一个下划线前缀

函数名前加上一个下划线前缀

函数名前加上一个"@"符号,后面也是一个"@"符号和其参数的字节数

 

 

C++编译器名称修饰

规则与_stdcall调用约定相同,只是参数表的开始标识由上面的"@@YG"变为"@@YA"。

见表下面

规则与_stdcall调用约定相同,只是参数表的开始标识由上面的"@@YG"变为"@@YI"

 

 


VC++ __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,

PA--表示指针,后面的代号表明指针类型,如果相同类型的指针连续出现,以"0"代替,一个"0"代表一次重复;

4)、参数表的第一项为该函数的返回值类型,其后依次为参数的数据类型,指针标识在其所指数据类型前;

5)、参数表后以"@Z"标识整个名字的结束,如果该函数无参数,则以"Z"标识结束。

 

说明一下:之所以搞清楚栈的维护者很重要,因为有的约定需要函数自己来清除堆栈,如果都是使用c的话,倒是没太大问题,因为编译器都会帮你搞定,但是如果编写汇编代码提供给c使用,那汇编代码就要注意了,如果所使用的调用约定需要自己清除堆栈空间,则一定要清楚,否则后面的代码都会认为该函数已经清空了堆栈,后果当然很严重,大家都懂得:)
原创粉丝点击