[C++反汇编] 栈帧(函数调用过程)

该系列文章是依据本人平时对反汇编的学习,归纳总结,所做的学习笔记。如有错误或待改善之处,请留下您宝贵的意见或建议。

 

栈帧也叫过程活动记录,是编译器用来实现过程/函数调用的一种数据结构。栈帧是在程序的运行时栈中分配内存块,专门用于特定的函数调用。

 

当一个函数没有执行时,它可能并不需要内存;但是当一个函数被执行后,它就可能因为某种原因需要用到内存。原因有:1.函数的调用方可能希望以参数(实参)的方式向该函数内传递信息,这些参数需要存储在函数能够找得到他们的地方。2.在执行任务的过程中,函数可能需要临时的存储空间。程序员通常会通过声明局部变量来分配这类临时空间,这些变量将只在函数内部使用,函数执行结束后,将被销毁,不能在访问他们。

 

编译器通过栈帧(也叫做激活记录)使得对函数参数和局部变量进行分配和释放的过程对程序员透明。在将控制权交给函数之前,编译器会插入代码,将函数参数放入栈帧内,并分配足够的内存,以保存函数的局部变量。鉴于栈帧的结构,函数的返回地址也被存储在新的栈帧中。使用栈帧使得使用递归成为可能,因为每个递归函数调用都有它自己的栈帧,这恰好将当前的调用和之前的调用分隔开来。下面是调用一个函数的详细过程

 

1.   调用方将调用函数所需的任何参数放入该函数所采用的调用约定指定的位置。如果参数被放入运行时栈上,该操作可能引起程序栈指针的变化。

2.   调用方将控制权交给被调用函数,这个过程有X86 CALLMIPS JAL等指令实现。然后返回地址被保存到程序栈或寄存器中。

3.   如果必要,被调用函数会配置一个栈指针,并保存调用方希望保持不变的任何寄存器值。

4.   被调用的函数为它可能需要的任何局部变量分配空间。一般,通过调用程序栈指针在运行时栈上保留空间来实现。

5.   被调用函数执行其操作,可能产生一个结果。在执行操作过程中,被调用函数可能会访问调用函数传递过来的参数,如果函数返回一个结果,此结果通常被放在一个特定的寄存器中,或者放置在函数返回后调用方可立即访问的寄存器中。

6.   函数完成其操作后,任何存放局部变量的栈空间将被释放。通常,逆向执行第4步的操作即可完成相应的工作。

7.   如果某个寄存器的值还为调用方保存(第3步)着,那么将其恢复到原始值。这包括恢复调用方的栈指针寄存器的值。

8.   被调用的函数将控制权返回给调用方。实现这一步的主要指令包括X86 RETMIPS JR。根据所使用的调用约定,这一操作可能会从程序栈中清除一个或多个参数。

9.   调用方一旦重新获得控制权,它可能需啊哟删除程序栈中的参数。这时,可能需啊哟对程序栈进行调整,将程序栈指针恢复到第一步之前的值。

3步和第4步通常在进入函数时执行,它们共同称为函数的序言。同样,第6步到第8步一般在函数结束时执行,它们共同称为函数的尾声,而第5步则代表函数的主体,它们是调用函数时执行的全部操作。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值