C/C++函数调用约定

函数调用过程

调用函数的时候,用栈来存放函数执行所需要的参数。

而第一个进栈的使主函数中的第一条指令,然后是函数的各个参数,在大多数C的编译器里,参数是由右往左入栈的,然后是函数中的局部变量。

为什么采取从右往左入栈的顺序?
1、这样可以保证出栈时的顺序和我们函数里写的参数顺序一致
2、为了方便使用C/C++的“函数参数长度可变”的特性,举个例子,有函数printf("%d %d",1,2,3,4);如果从左边开始压栈,出栈的顺序是4,3,2,1,%d,%d,这样就还要多两个空间来存储4,3,然后再判断出4,3是不需要的,显然这样操作耗时耗空间。

约定内容

  • 当参数个数多于一个的时候,按照什么什么熟悉呢把参数压入堆栈(入栈)
  • 函数调用后,由谁来把堆栈恢复原状(出栈)

调用方法

C 语言: __cdecl、__stdcall、__fastcall、naked、__pascal。C++在C的基础上多出一种_thiscall。

使用的方法一般为(thiscall例外):

int _cdecl function(int a,int b);
  • stdcall

    C++的标准调用方式

    • 参数从右向左依次入栈
    • 由被调函数自己来恢复堆栈,称为自动清栈
    • 函数名自动加前导下划线,后面紧跟一个@,其后再跟着参数的大小
  • cdecl

    (C语言缺省时的调用方式)

    • 参数从右向左依次压入堆栈.
    • 由调用者恢复堆栈,称为手动清栈。(由于是由调用者来挥发堆栈,所以该调用方式允许函数的参数个数不固定)
    • 函数名自动加前导下划线。
  • pascal
    • 从左向右传递参数
    • 通过EAX返回
    • 堆栈由被调用者清除
  • fastcall

    快速调用方式,通过CPU寄存器来传递参数

    • 参数以从右向左入栈
    • 被调用函数清理堆栈
  • thiscall

    C++类成员函数缺省的调用方式,因为成员函数的调用还有一个this指针

    • 参数从右向左入栈
    • 如果参数个数确定,this指针通过ecx(CPU中的计数寄存器)传递给被调用者;如果参数个数不确定,this指针在所有参数压入栈后被压入栈。参数个数不定的,由调用者清理堆栈,否则由函数自己清理堆栈。可以看到,对于参数个数固定的情况,它类似于stdcall,不定时则类似于cdecl。
  • naked call(不常见)

参考:
函数约定
入栈顺序

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值