【学习笔记】2. 函数调用的栈的管理

记在最初,若是发现有专业术语的错误,请记得及时改正。 这个真的很重要。

1. 无参数传递的函数调用

本例会实际演示一个 只有函数局部变量赋值的demo
会先看一下C语言源代码和编译代码,而后一步一步的推演栈的空间使用

1.1 函数源码

C语言源码:html

clipboard.png

注释: 这个脚本中,main 函数调用 f 函数,各自函数里面有局部变量的定义,函数调用没有参数传递。segmentfault

编译代码:函数

clipboard.png

clipboard.png

汇编指令:学习

clipboard.png

1.2 编译step过程

0. 确认栈的地址

clipboard.png

为了方便记忆和观看,咱们先假设栈的其实地址是 9000优化

1. 肯定main函数的栈帧

clipboard.png

2. 保存局部变量

clipboard.png

若是变量 < 4 个,直接保存到寄存器。spa

变量数量 > 4 的部分放入到栈中。3d

具体的地址参数是视频

clipboard.png

3. 跳转到f函数

f 函数的第一步压栈处理htm

clipboard.png

4. 确认f函数的栈帧

clipboard.png

5. 返回参数变量

返回的值,会直接放到 r0 寄存器上blog

若是值比较大,会开辟一个地址单元,把地址返回给主函数

clipboard.png

6. 返回到main函数

clipboard.png

clipboard.png

而后直接返回

经过这样的操做,函数返回到 main 函数,上一个函数

7. 返回执行函数

可执行文件 使用 exec fork 子进程

main的上一个函数 是 execve

clipboard.png

把 execve 的地址 给 pC,下一条执行的 地址

clipboard.png

每一个栈帧上一个函数的起始地址 好比 9000

bl b 指令自动会函数 下一条地址 压入栈

压栈的都是在下一级须要改变的,要不编译器会优化掉

2. 有传参的函数调用

2.1 运行实例代码

clipboard.png

对应的汇编代码

clipboard.png

2.2 执行步骤

一、main 函数压栈和入栈

clipboard.png

2. 存储局部变量

clipboard.png

3. 传参的入栈

clipboard.png

clipboard.png

4. 跳转到f函数

clipboard.png

5. f函数的压栈和入栈

clipboard.png

6. 传参在f函数的保存

clipboard.png

clipboard.png

初始化 sum 值

clipboard.png

7. f函数变量的赋值

clipboard.png

clipboard.png

能够发现此时改变的不是形参 n 而是 传参的栈地址

8. 加法运算

clipboard.png

clipboard.png

9. 返回main函数

clipboard.png

fp 返回的是栈帧保存的上一个函数的地址

而后从新回到了 main 函数

因此并无改变实际参数的值,由于存储到不一样的位置单元。 传参和定义的局部变量。 会保存栈或者寄存器的不一样位置

3.形参和实参

结合上面 第二段的内容 形参和实参的分析
能够看出,在调用函数进行参数传递的时候,会从新分配栈空间或者寄存器进行管理。
而同时被调用的函数(好比f函数),在初始化中,会先把寄存器中的值取出来,放到本身的栈里面进行管理。

因此被传入的参数和main函数中的,属于不一样的地址。所以也不会相互影响。

100. 致敬

若有不详,请参考王老师的精彩讲解 堆栈管理
学习过程当中,得到了极大的知足感,把以前的一些东西串联了起来。十分感谢 王利涛老师。在此表示感谢。PS:本文中全部的资源和图片均来自视频中

相关文章
相关标签/搜索