函数调用约定:__stdcall、__cdecl和__fastcall介绍

想深入了解可学习汇编语言去了解内存机制

一、问题引导:C语言中函数参数的入栈顺序

C程序栈底为高地址,栈顶为低地址。

C方式参数入栈顺序(从右至左)的好处就是可以动态变化参数个数。通过栈堆分析可知,自左向右的入栈方式,最前面的参数被压在栈底。除非知道参数个数&c#软件#xff0c;否则是无法通过栈指针的相对位移求得最左边的参数。这样就变成了左边参数的个数不确定&c语言编译器#xff0c;正好和动态参数个数的方向相反。

因此,C语言函数参数采用自右向左的入栈顺序,主要原因是为了支持可变长参数形式。

二、、函数调用约定(Calling Convent程序员ion)

函数调用约定不仅决定了发生函数调用时函数参数的入栈顺序,还决定了是由调用者函数还是被调用函数负责清除栈中的参数&程序员工作一年后工资#xff0c;还原堆栈。函数调用约定有很多方式,除了常见的__cdecl,__fastcall和__stdcall之外c#是什么,C++的编译器还支持thiscall方式,不少C/C++编译器还支持 naked call方式。这么多函数调用约定常常令许多程序员很迷惑ÿ程序员客栈0c;到底它们是怎么回事,都是在什么情况下使用呢?下面就分别介绍这几种函数调用约定。

1.__cd程序员那么可爱电视剧免费观看ecl

编译器的命令行阿飘参数是/Gd.__cdecl方式是C/C++编译器默认的函数调用约定,c#反射所有非C++成员函数和那些没有用__stdcall或__fastcall声明的函数都默认是__cdecl方式,程序员工作一年后工资它使用C函数调用方c语言编译器式,函数参数按照从右向左的顺序入栈,函数调用者负责清除栈中的参c语言基础知识数,由于每次函数调用都要由编译器产生清除&#xc语言在线编译器ff08;还原)堆栈的代码,所以使用__cdecl方式编译的程序比使用__stdcall方式编windows10激活密钥译的程序要大很多,但是 __cdecl调用方式是由函数调用者c#是什么负责c#怎么读清除栈中的函数参数ÿc语言软件0c;所以这编译器和解释器种方式支持可变参数,比如printf和windowsAPI wsprintf就是__cdecl调用方式。对于C函数,__cdecl方式的名字修饰约定是在函数名称前添加一个下划线;对于C程序员那么可爱免费观看3;api接口+函数,除非特别编译器下载使用extern “C”,C++函数使用不同的名字修饰方式。c语言基础知识入门

2.__fastcall

编译器的命令行参阿飘是什么意思数是/Gr.__fastcall编译器和解释器windows更新有必要吗数调用约定在可能的情况下使用寄存器传递参数&#c语言在线编译器xff0c;通常是前两个 DWORD类型的参数或较小的参数使用ECX和windows7旗舰版EDX寄存器传递,其余参数按照从右向左的顺序入栈apinkf0c;被调用函数在返回之前负责清除栈中的参数。编译器使用两个@修饰函数名字,后跟十进制数表示的函数参数列表大小&#编译器的英文xff0c;例如:@function_name@numbeAPIr.需要注意的是__fastcall函数调用约定程序员那么可爱免费观看在不同的编译器阿飘上可能有不同的实现,比如16位的编译器和32位的编译器,另外,在使用内嵌汇编代码时,还要注意不能和编译器使用的寄存器有编译器的英文冲突。

3.__s编译器下载tdcall

编译器的命令行参数是/Gz,__sc#酒店客房管理系统tdcall是Pascal程序的缺省调用方式,大多数Windows的API也apicloud是__stdcall调用约定。__std编译器比解释器效率call函数调用约定将函数参数从右向左入栈,除非使用指针或引用类型的参数,所有参数采用传值方式传递,由被调用函数负责清除栈中的参数。对于C函数,__stdcall的名称修饰方式是在函数名字前添windows7旗舰版加下划线,在函数名api是什么意思字后添加@和函数参编译器原理数的大小,例如&阿飘是什么意思#xff1a;_functionname@number

三、三者区别

__stdcall、__cdecl和__fastcall是三种函数阿飘调用协议,函数调用协议会影响函数参数的c语言修仙入栈方式、栈内数据的清除方式、编译器函数名的修饰规则等。

1c#反射、调用协议常用场合

__stdcall:Win编译器原理dows API默认的函数调用协议。

__cdecl:C/C++默认的函数调用协议。

__fastcall:适用于对性能要求较高的场合。

2、函数参数入栈方式

__stdcall:函数参数由右向左入栈。

__cdecl:函数参数由右向左入栈。

__fastcall:从左开阿飘始不大于4字节的参数放入CPU的ECX和EDX寄存器&API#xff0c;其余参数从右向左入栈。

问题一:windows更新有必要吗;__fastcall在寄存器中放入不大于windows7旗舰版4字节的参数&#程序员需要什么学历xff0c;故性能较高,适用于需要高性能的场合。

3、栈内数据清除方式

__stdcall:函数调用结束c#是什么后由被调用函数清除栈内数据。

__cdecl:函数调用结束后由函数调用者清除栈内数据。

_编译器是怎么写出来的_fastcall:函数调用结束后由被调用程序员工作一年后工资函数清除栈内数据。

问题一:不同编译器设定的栈结构不尽c语言基础知识相同,跨开发平台时由函数调api是什么用者清除栈内数据不可行。

问题二:某些函数的参数是程序员是做什么的可变的,如printf函数,这样windows10激活密钥的函数只能由函数调用者清除栈内数据。

问题三:由调用者清除栈内数据时&#windows10激活密钥xff0c;每次调用都包含清除栈内数apink据的代码,故可执行文件较大。api是什么

4、C语言编译器函数名称修饰规则

__stdcall:编译后程序员工作一年后工资f0c;函数名被修饰为“_functionnc语言程序设计ame@number”。

__cdecl:编译后,函数名被修饰为“_functionname”。

__fac#反射stcall:编译后,函数名给修饰为“@functionname@nmuber”。

注:“functionname”为函数名,“number”为参数字节数。

注&#程序员工资一般多少xff1a;函数实现和函数定义时如果使用了程序员那么可爱不同的函数调用协议,则无法实现函数调用。

5、C++语言编译器函数名称修饰规则

__stdcall:编译后&c语言#x阿飘军人老公二爷ff0c;函数名被修饰为“?functionnamc语言软件e@@YG******@Z程序员那么可爱”。

__cdecl:编译后,函数名被c#修饰为“?functionname@@YA******@Z”。

__fastcall:编译后,函数名被修饰为“?functionname@@YI******@Z”。

注:“******”为函数返回值类型和参数类型表。

注:函数实现和函数定义时如果使用了不同的函数调用协议&#xwindows11有必要升级吗ff0c;则无法实现函数调用。

C语言和C++语言间如果不进行特殊处理,也无法实现函数的互相调用。