C/C++调用约定


       函数调用时,调用者依次把参数压栈,然后调用函数,函数被调用以后,在栈中取得数据,并进行计算。函数计算结束以后,或者调用者,或者函数本身修改堆栈,使堆栈恢复原装。
       由于计算机不知道怎么给函数传递参数(一个函数调用需要多少个、什么样的参数,也没有硬件可以保存这些参数),为此引入栈的概念,以支持参数传递。
       栈是一种先进后出的数据结构,栈有一个存储区、一个栈顶指针。栈顶指针指向堆栈中第一个可用的数据项(栈顶)。用户可以在栈顶上方向栈中加入数据,该操作过程被称为压栈(Push),压栈以后,栈顶自动变成新加入数据项的位置,栈顶指针也随之修改。用户也可以从堆栈中取走栈顶,称为弹出栈(Pop),弹出栈后,栈顶下的一个元素变成栈顶,栈顶指针随之修改。
  在参数传递中,需注意:1、当参数个数多于一个时,按什么顺序把参数压入栈?
                                          2、函数调用后,由谁来把堆栈回复原装。
  在高级语言中,通过函数调用约定来说明这两个问题。常见的调用约定有:_stdcall_cdecl_fastcallthiscallnakedcall


  1、 _stdcall (Pascal方式清理C方式压栈,通常用于Win32 Api中)
     a、函数的参数自右向左压入堆栈。
     b、被调用的函数在返回前清理传送参数的内存栈。
     c、C编译时函数修饰名约定:函数名前自动加下划线,后面紧跟一个@符号,其后紧跟参数的字节数。例如:Add(int a,int b)   修饰名为:_Add@8
     d、C++编译时函数修饰名约定:以“?”标识函数名的开始,后跟函数名;  函数名后面以“@@YG”标识参数表的开始,后面跟参数表;  参数表以代号表示:  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"代表一次重复;参数表的第一项为该函数的返回值类型,其后依次为参数的数据类型,指针标识在其所指数据类型前;参数表后以"@Z"标识整个名字的结束,如果该函数无参数,则以"Z"标识结束。void  test() -----"?test@@YGXXZ"      int  fun(char *a,unsigned long)  -----"?fun@@YGHPADK@Z"

   2、_cdecl(C调用约定.The C default calling convention)          

      a、C/C++ 缺省调用方式。(只能被C/C++调用)

      b、函数采用从右到左的压栈方式。
      c、每一个调用它的函数都包含清空堆栈的代码,所以产生的可执行文件大小比调用_stdcall函数的大。
      d、对于可变参数的成员函数,始终使用_cdcel的转换方式。
      e、C编译时函数修饰名约定:仅在函数名前自动加下划线。例如:void test()---_test
      f、C++编译时函数修饰名约定:规则同_stdcall调用约定,只是参数表的开始标识为"@@YA"

    3、_fastcall (快速调用约定,通过寄存器来传送参数)
      a、它通过寄存器来传送参数,实际上,它用ECX和EDX传送前两个双字(DWORD)或更小的参数,剩下的参数仍旧自右向左压栈。
      b、被调用的函数在返回前清理传送参数的内存栈。
      c、C编译时函数修饰名约定:函数名前自动加下划线,后面紧跟一个@符号,其后紧跟参数的字节数。
      d、C++编译时函数修饰名约定:规则同_stdcall调用约定,只是参数表的开始标识为"@@YI"。

   4、thiscall
      a、本身调用,仅仅应用于“C++”成员函数。
      b、this指针存放于CX寄存器,参数从右到左压栈。
      c、thiscall不是关键词,因此不能被程序员指定。

   5、nakedcall
      a、采用1-4的调用约定时,如果有必要的话,进入函数时编译器会产生代码来保存ESI,EDI,EBX,EBP寄存器,退出函数时则产生代码恢复这些寄存器的内容。
      b、nakedcall不产生这样的代码。
      c、nakedcall不是类型修饰符,故必须和_declspec共同使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值