快速了解函数栈帧,小白也能看懂(c语言)

目录

前言

基础知识

函数栈帧

例子展示

什么是函数栈帧?

栈帧和栈的关系?


前言

  我作为学c语言不久的小白,在网上查找函数栈帧的学习资料时,发现大多远超出我的知识范围,以至于很难理解。如果你也有同样的困境,那么这篇可以带你轻松了解函数栈帧。

  我提出以下三点问题,这是本文要弄懂的三个点。你先快速浏览,在看完之后,回过头来自问自答,若是思路清晰,那么证明学有所获。

  1. 什么是函数栈帧?

  2. 一个函数的调用过程是怎样的?

  3. 栈帧和栈的关系如何?

基础知识

  在开始之前,我先来介绍两个基本概念。如果你已经知道,那么这部分可跳过不读。

  • 程序计数器(简称PC)

      我们知道,代码是一行一行连续执行下去的,而实现这个过程,依靠的是程序计数器。程序计数器是计算器中的一个寄存器,用于存储当前正在执行的指令的地址 or 下一条指令的地址。

      在计算机的指令执行过程中,CPU需要不断地从内存中取出指令并执行。此时程序计数器存的是当前指令的地址。每当一条指令执行完毕,程序计数器就会自动增加,指向下一条指令的地址,以便CPU可以顺利执行。

      可见,程序计数器与指令的执行顺序密切相关。

      Q: 在main函数中执行到函数Add时,是如何实现跳转的呢? answer:由底层修改程序计数器的值,改成Add的地址,那么下一条指令就会跳转到Add中去了。

  •   栈是一种基于后进先出原则的数据结构。它是一块内存区域,用于存储临时数据、函数调用和局部变量等。 其特点:后进先出。即只能在栈顶进行数据的插入、删除操作。栈常用于函数的调用过程中,用于保存函数的局部变量、返回地址和其他临时数据。每当一个函数被调用时,相关的数据被压入栈中,当函数执行完毕后,这些数据再从栈中弹出,恢复到调用函数之前的状态。

快速了解函数栈帧,小白也能看懂(c语言)_第1张图片

函数栈帧

例子展示

  OK在了解完这两个概念之后,我们来讲一讲函数栈帧。我通过一个小例子来讲解函数的调用过程,进而让大家明白什么是函数栈帧。

int Add(int x,int y)
{
    return x+y;
}
int main()
{
    int a=1;
    int b=2;
    int c=Add(a,b);
    return 0;
}

执行过程

Step 1:  当前程序进入main函数以后,依次把局部变量a,b压入栈中,当main函数要调用Add函数时,会先把Add函数的返回地址压入栈中,(这样Add函数执行完,会按照返回地址回到main函数中相应位置继续往下执行),那压入栈的这一部分,就叫做main函数的函数栈帧。

  main的栈帧只属于它自己,对其他函数不可见。当调用其他函数时,main函数的栈帧是暂时被挂起的。

快速了解函数栈帧,小白也能看懂(c语言)_第2张图片

快速了解函数栈帧,小白也能看懂(c语言)_第3张图片

Step 2:

  1. Add函数被调用,会在栈上创建一个栈帧,为Add所用。(关于栈帧的概念我们一会再说,先知道它的名字就行)

  2. Add有两个参数:x、y,这两个参数分别以从右到左的顺序压入栈帧,即y先,x后。

  3. 执行函数体。将x与y相加,结果保存在寄存器中。

Step 3: Add函数执行完毕,依次将x、y弹出栈帧,栈帧销毁。

Step 4:此时的栈顶是临走前保存的返回地址,取栈顶,通过修改程序计数器的值,又返回到了main函数中。这便完成了对Add函数的调用。

什么是函数栈帧?

  刚刚的例子可以看到,调用一个函数时,需要保存它的一些信息,如局部变量、参数、需要存在寄存器里的值等等,这些信息是这个函数留下的痕迹,叫做活动过程记录。栈帧又叫活动过程记录,或者从逻辑上说,栈帧是函数执行的环境。

  栈帧是计算机内存中的一个独立区域,用于存储程序函数调用过程中的局部变量、参数和返回地址。每当一个函数被调用时,都会在栈上创建一个新的栈帧。函数执行完毕后,对应的栈帧将被销毁。

栈帧和栈的关系?

  看名称我们会觉得,栈和栈帧很相似。

  实际上,两者是不同的概念,彼此间有一定的关联。

  栈是一种数据结构。栈帧是函数在执行时在栈上分配的一块内存区域。两者的联系在于:每当一个函数被调用时,其对应的栈帧会被创建并压入栈中。当函数执行完毕后,其对应的栈帧会被释放,即从栈中弹出。

  因此,栈帧是栈的一部分。是在栈中专门为一个过程或者一个函数分配的栈空间。

  (^ - ^)感谢阅读,如有错误,还望指正。

你可能感兴趣的:(数据结构,c语言)