当前位置 博文首页 > weixin_30640291的博客:函数调用过程栈帧变化详解

    weixin_30640291的博客:函数调用过程栈帧变化详解

    作者:[db:作者] 时间:2021-09-06 16:11

    函数调用另一个词语表示叫作 过程。一个过程调用包括将数据和控制从代码的一部分传递到另一部分。另外,它还必须在进入时为过程的局部变量分配空间,并在推出时释放这些空间。而数据传递,局部变量的分配和释放通过操纵程序栈来实现。在了解本文章之前,您需要先对程序的进程空间有所了解,即对进程如何使用内存?如果你知道这些,下面的内容将是很easy的事情了。为了您的回顾还是将简单的分布图贴出来,便于您的回顾。

    我们先来了解一个概念,栈帧(stack frame),机器用栈来传递过程参数,存储返回信息,保存寄存器用于以后恢复,以及本地存储。为单个过程(函数调用)分配的那部分栈称为栈帧。栈帧其实是两个指针寄存器,寄存器%ebp为帧指针,而寄存器%esp为栈指针,当程序运行时,栈指针可以移动(大多数的信息的访问都是通过帧指针的)。总之简单一句话,栈帧的主要作用是用来控制和保存一个过程的所有信息的。栈帧结构如下所示:

      

    如果你已经对这个图已经非常了解了,那么就没有必要再看下去了。因为下面的内容都是对这幅图的讲解。

      假设过程P(调用者)调用过程Q(被调用者),则Q的参数放在P的栈帧中。另外,当P调用Q时,P中的返回地址被压入栈中,形成P的栈帧的末尾(返回地址就是当程序从Q返回时应该继续执行的地方)。Q的栈帧从保存的帧指针的值开始,后面到新的栈指针之间就是该过程的部分了。

      过程实例讲解:

    下面以这个程序为例进行简要说明函数调用的基本过程。

    int swap_add(int* xp,int* yp) {
        int x = *xp;
        int y = *yp;
        *xp = y;
        *yp = x;
        return x+y;
    }
    int caller(){
        int arg1 = 534;
        int arg2 = 1057;
        int sum = swap_add(&arg1,&arg2);
        int diff = arg1 - arg2;
        
        return sum * diff;
    }
    cs
    下一篇:没有了