图解c语言程序函数调用过程中栈的变化

演示程序代码:

int m = 8;
int fun(int a,int b)
{
    int c = 0;
    c = a + b;
    return c;
}
int main()
{
    int i = 4;
    int j = 5;
    m = fun(i, j);
    return 0;
}

1.程序在内存分布区域
image1.png
2.全局变量m赋值
image2.png
3.保存进入main之前的栈底, bp-sp之间是当前函数栈
image3.png
4.函数main的栈已经准备好了
image4.png
5.i入栈
image5.png
6.j入栈
image6.png
7.准备函数fun的调用, 形参反向入栈 先形参b入栈
image7.png
8.形参a入栈
image8.png
9.留空一个地址作为fun返回值, 待后面返回时填入
image9.png
10.fun返回地址入栈, 通常是main函数当前pc指针的下一个
image10.png
11. main函数的栈底地址入栈
image11.png
12. pc指针跳转fun代码
image12.png
13. c入栈
image13.png
14. 可以看到函数fun的数据 形参a,b 在上一层函数的栈中. 一部分在自己的栈上.
此步取值到加法器中进行加法运算,再赋值给c
image14.png
15. c赋给返回值,填入上面的留空位置
image15.png
16. 栈底恢复上一层
image16.png
17. lr赋值给pc, 实现了跳转
image17.png
18. 返回值赋值给全局变量m
image18.png
19. 前面函数调用的形参已经无用,回滚sp
image19.png
20. 函数返回,清理main的栈空间
image20.png

上面的例子事实上没有罗列出寄存器的参与, 这需要根据实际汇编代码进行. ARM上的函数调用前面四个形参默认使用R0,R1,R2,R3, 多于4个参数才使用栈保存. 寄存器是连接运算器的中转站, 也一定程度上避免了频繁访问内存.

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值