函数调用惯例

函数的调用方与被调用方对于函数如何调用须要一个明确的约定,这样的约定就叫作调用惯例。

一个调用惯例一般会规定如下几方面的内容:

1. 函数参数的传递顺序及方式

函数参数的传递有多种方式,常见的是通过栈传递。函数的调用方将参数压入栈中,函数自己再从栈中取出参数。对于有多个参数的函数,调用惯例需要约定函数调用方将参数压入栈的顺序:是从左到右,还是从右到左。还有些调用惯例也支持使用寄存器来传递参数。

2. 栈的维护方式

在参数被压入栈后,函数体被调用执行,此后需要将被压入栈的参数再全部弹出,以使得栈在函数调用前后保持一致。这个弹出工作可以由调用方完成,也可以由被调用函数来完成。

3. 名字修饰的策略

为了链接的时候能够对调用惯例进行区分,调用管理要对函数名进行修饰。不同的调用惯例也有不同的修饰策略。

下表列出几个常见的调用惯例:

调用惯例

出栈方

参数传递

名字修饰

cdecl调用方从右至左的顺序压参数入栈下划线+函数名
stdcall函数自身从右至左的顺序压参数入栈下划线+函数名+@+参数的字节数,如函数int func(int a, double b)的修饰名是_func@12
fastcall函数自身头两个DWORD(4字节)类型或者占更少字节的参数被放入寄存器,其他剩下的参数按从右到左的顺序入栈@+函数名+@+参数的字节数
pascal函数自身从左至右的顺序入栈较复杂,参见pascal 文档

其中cdecl 是c 语言默认的调用惯例。

 

此外,C 语言的诸如printf() 这样支持可变参数的函数,也是依赖于cdecl 的从右向左传递参数从而得到实现的。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值