函数调用过程-栈帧 和 进程的关系

程序中,一个函数是一个过程,这个过程可以分为包括传入参数、过程代码、返回三部分构成。由于一个函数过程需要用到内部变量、临时变量等,所以需要在进程空间的栈空间分配一段存储片段来存储函数过程中的这些参数,该内存片段即为栈帧。

栈帧的由来:

        为一个函数的过程提供一个存储函数局部变量,参数,返回地址和其他临时变量;

栈帧的结构:


 图片来源(现代编译原理)


栈帧的周期:

    进入函数~函数返回,该阶段内栈帧作为

    不同的语言具体的实现方式略有不同,但是,总体上,fun(a,b);


局部变量:

    包括函数传入的形参和函数内部定义的变量;


返回地址:

    指令指针P指向call fun,那么fun栈帧存储的返回地址为P+1;现今的编译器的一个约定是将返回地址存到一个固定的寄存器中,这样比读取栈帧(内存)效率要高。


临时变量:

    主要为计算,运算过程中的中间临时变量;


参数传递:

    其一:如果fun中调用另一个函数k(a,b...n);那么,传递的参数是形参,按照现代编译规定,前k个形参是通过寄存器传递,后n-k个形参通过栈帧的实参部分(栈帧的尾部)来传递;

    其二:主要为在fun中要调用函数g(&a,&b),那么为g()函数传出实参(形参是通过寄存器来传递的)是通过“传出实参”区块进行的,这么做主要是为了保证该实参能够被内层嵌套的函数访问。比如,g函数由调用一个k(a地址)函数,同样需要用到a的地址,所以fun在传递参数时必须为实参(&a)传递申请固定的内存存储空间(而非用寄存器)这样k函数可以通过固定的内存地址(fun的形参列表来获取参数值)。这时的g的栈帧为fun栈帧的下一帧(相邻的空间地址),即调用者和被调用者的栈帧是相连的;

    

保护的寄存器:

    栈帧作为函数过程的一个临时内存存储区块,同时负责函数调用过程中寄存器值的保存和还原。即:假设fun函数目前占用了寄存器Ri存储一个临时变量t,而此时调用了函数g(),在g()函数中可能需要用到寄存器Ri做运算的临时存储,那么如何确保g()函数调用返回后,Ri恢复到fun中t的原来值。这就需要在调用者或者被调用者中选择其一来保存原有Ri的值,即caller-save或者callee-save。


最后一个问题:进程空间中栈帧的体现是什么?

进程的栈空间 & 栈帧的增长:

调用函数和被调用函数间的栈帧是相邻的,即如果进程进入一个递归函数f(),递归k层。那么在第k层嵌套时,进程的的栈空间已产生出新的k个连续的f()函数的栈帧,当然每个栈帧的内存储的变量值是因函数过程而定的。


原创:Ordeder  http://blog.csdn.net/ordeder/article/details/20405197


### C语言函数调用过程解释 #### 函数定义与声明 在C语言中,函数可以看作是一段完成特定任务的代码集合。为了使程序能够识别并正确调用这些功能模块,需要先对其进行声明或定义。例如,在`main()`之前声明了一个名为`Min`的函数[^3]。 ```c int Min(int x, int y); ``` 此行告诉编译器存在这样一个接受两个整型参数并返回一个整数值的方法签名。 #### 参数传递机制 当实际发生函数调用时,会涉及到参数如何从调用方传入目标方法内部的问题。对于像`Min`这样的简单例子来说,采用的是按值传递的方式——即把原始变量的具体数值复制一份作为新创建局部变量(形式参数)的初始值[^4]。 #### 调用构建 每当有新的子程序被执行之际,操作系统会在内存堆区划出一片区域来保存当前上下文环境以及即将使用的资源信息;这片空间被称为“活动记录”或者更通俗地讲就是“桢”。它不仅包含了上述提到的形式参数副本,还可能涉及临时寄存器状态备份、旧基址指针BP等重要数据结构[^1]。 #### 控制权转移至被叫端 一旦准备就绪,则CPU指令流将按照预先设定好的地址跳转过去继续执行那里所描述的操作序列直到遇见终止符为止。在这个阶段里,所有关于源位置的记忆都被暂时搁置一边等待后续处理完毕后再做恢复工作[^2]。 #### 执行具体逻辑操作 以寻找最小值为例: ```c if (x < y) { return x; } else { return y; } ``` 这里通过条件判断选出较小的那个数并通过`return`关键字将其送出给外界使用。 #### 返回至上层调用点 随着最后一句有效命令被执行过之后,意味着整个计算周期接近尾声。此时除了要把最终成果反馈回去之外,更重要的一件事是要清理掉刚才预留出来的那部分存储单元以便释放宝贵的硬件资源供其他进程共享利用。随后控制路径重新回到最初发起请求的地方继续往下走。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值