c语言调用约定(x86下的调用栈示意)

调用约定:
1、在执行子函数之前,程序先压入子函数的所有参数,以逆序的方式压入(即先压入最后一个参数)。
2、然后程序执行call指令,指定哪一函数即将执行,call指令主要做了以下两件事情:
   a)第一,将下一指令的地址压入栈(即函数的返回地址);
   b)第二,更改%eip,使其指向函数的起始地址。
该操作后,函数栈如下所示:
Parameter #N
...
Parameter 2
Parameter 1
Return Address <--- (%esp)

3、接下来函数本身需要做以下事情:
   a)首先,执行pushl %ebp保存函数帧指针;
   b)其次,执行movl %esp, %ebp拷贝栈指针到函数帧指针寄存器中;此操作使得用户可以通过%ebp来访问到到函数的参数,%ebp通常是函数开始时的栈指针,每个参数可以用%ebp基址指针寻址的方式进行访问;
   c)然后,函数需要预留一定的栈空间,来存储所有的局部参数,他们的声明周期与该函数相同
执行后,其函数栈如下所示:
Parameter #N <--- N*4+4(%ebp)
...
Parameter 2 <--- 12(%ebp)
Parameter 1 <--- 8(%ebp)
Return Address <--- 4(%ebp)
Old %ebp <--- (%ebp)
Local Variable 1 <--- -4(%ebp)
Local Variable 2 <--- -8(%ebp) and (%esp)

4、当函数结束时,将做以下3件事
   a)将返回值存储至%eax;
   b)恢复栈信息,  (movl %ebp, %esp) (popl %ebp)
   c)执行ret指令。将栈顶值(函数返回地址)弹出,并设置%eip为该值

备注:(%ebp) has the old %ebp 4(%ebp) has the return address, and 8(%ebp) is the location of the first parameter to the function.
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值