(栈帧和函数调用一)栈帧,函数调用与栈的关系

  • 一,栈帧的介绍
  • 二,函数调用与栈的关系
  • 三,汇编演示
  • 四,总结

在计算机科学中,栈是一个特殊的容器,用户可以将数据压入栈中(入栈,push),也可以将已经压入栈中的数据弹出(出栈,pop),但栈容器必须准守一个规则:先入栈的数据后出栈(First In Last Out,FIFO)。
     在计算机系统中,栈是一个具有以上属性的动态内存区域(这里的动态指的是栈的空间可以动态增长或减小)。程序可以将数据压入栈中,也可以将数据从栈顶弹出。压栈使得栈空间增大,出栈使得栈空间减小。栈的空间总是自顶向下增长的(由高地址向低地址扩展)。

一,栈帧的介绍

栈在程序空间中有着非常重要的地位,栈中保存了一个函数调用所需的维护信息,这就是我们常说的栈帧,栈帧一般包括以下几方面内容:
1) 函数的返回地址(用于返回函数调用处)和参数
2) 临时变量:包括函数的非静态局部变量以及编译器自动生成的其他临时变量
3) 保存的上下文:包括在函数调用前后需要保持不变的寄存器。
     在i386中,一个函数的活动记录范围由ebp和esp两个寄存器来
划定,其中esp寄存器始终指向栈顶,同时也指向当前函数的活动记录的顶部;ebp寄存器指向栈底。ebp又被称为帧指针,esp被称为栈指针。
     栈帧是是相对于每一个函数调用而言的,是独立的。

二,函数调用与栈的关系


     一个函数的调用分为以下几步;
1) 将函数参数按照函数定义约定依次压入栈中(_stdcall,_cdcel等)
2) 将当前指令的下一条指令(也就是函数返回地址)压入栈中
3) 跳转到函数体执行函数
4) 栈帧调整:
a) Push ebp:将ebp压入栈中,(old ebp)
b) Move sbp,esp:将esp的值赋给ebp,这时ebp指向栈顶位置,而栈顶就是old ebp
c) Sub esp,XXX栈上分配临时空间,push XXX/pop XXX保存某些寄存器的值
d) mov eax, xxx:保存被调用函数的返回值到寄存器eax中
e) move esp,ebp:恢复esp栈顶指针,同时回收栈上的局部变量
f) pop ebp:恢复ebp栈底指针
g) ret:从栈中取出返回地址,并jump到该地址

三,汇编演示

以一个简单的函数为例:

Int fun()
{return 1;
}

对该函数反汇编结果如下:(vs编译器调试在函数入口处打断点,调试-窗口-反汇编)

     第1-2行,保存了旧的ebp,并让ebp指向当前的栈顶。
     第3行,将esp栈顶扩展了0XC0个字节,这一大段空出来的空间用来存储局部变量,临时数据或者调试信息。
     第4-6行,将ebx,esi,edi三个寄存器的值保存到了栈上,这三个寄存器的值在函数随后的执行中可能被修改,所以要先保存一下这些寄存器原本的值,以便退出函数时恢复。
     第7-12行,也就是return 1之前是一些调试信息,其中请注意有一步是将eax赋值为0xCCCCCCCC,而eax是用来接受函数返回值的寄存器。
     第13行,将函数返回值1赋值给eax寄存器。
     第14-16行,从栈上恢复ebx,esi,edi三个寄存器的值
     第17行,将esp值加上0XC0个字节,恢复到原先的栈顶
     第18-21行,ebp出栈,恢复原先的栈底
     第22行,使用ret指令返回。

四,总结

1,栈帧是一个函数活动的记录,通过栈帧我们可以进行函数调用参数传递,以及函数返回值调用路径的回溯。
2,函数的返回值是保存在eax寄存器中,在i386中,它是一个32位的寄存器,占4个字节(那么大于4个字节的函数返回值如何传递呢?本系列文章后续揭晓)
3,函数调用的过程中,有进行栈的扩容操作,用于存放函数的入参,临时变量等一些信息,当函数调用结束后,这一部分栈空间会通过栈顶指针(esp寄存器)的移动被回收掉。

参考文献:
1,《程序员的自我修养:链接、装载与库》第十章第二节

(栈帧和函数调用一)栈帧,函数调用与栈的关系相关推荐

  1. 你只知道JVM栈,知不知道栈帧、局部变量表、slot、操作数栈?

    目录 虚拟机栈基础 虚拟机栈出现的背景 栈是运行时的单位,而堆是存储的单位 Java虚拟机栈 栈中可能出现的异常 设置Java栈大小 栈中存储什么? 栈运行原理 栈帧的内部结构 每个栈帧中存储着 局部 ...

  2. 栈帧及EBP、ESP寄存器及出入栈的流程

    接下来咱们以一个例子来说明EBP.ESP寄存器的作用.由于刚是自己理解的,有错误可以提出,共同进步. 这个是栈帧的结构 以下是按调用约定__stdcall 调用函数test(int p1,int p2 ...

  3. 栈 -- 顺序栈、链式栈的实现 及其应用(函数栈,表达式求值,括号匹配)

    文章目录 实现 顺序栈实现 链式栈实现 应用 函数栈 的应用 表达式求值中 的应用 括号匹配中 的应用 我们使用浏览器的时候经常会用到前进.后退功能. 依次访问完一串页面 a – b – c之后点击后 ...

  4. java中栈和堆都存哪些东西_java中栈内存与堆内存(JVM内存模型)

    java中栈内存与堆内存(JVM内存模型) Java中堆内存和栈内存详解1 和 Java中堆内存和栈内存详解2 都粗略讲解了栈内存和堆内存的区别,以及代码中哪些变量存储在堆中.哪些存储在栈中.内存中的 ...

  5. c语言中栈堆,全程剖析C语言中堆和栈的区别

    C语言中堆和栈的区别 1.申请方式 (1)栈(satck):由系统自动分配.例如,声明在函数中一个局部变量int b;系统自动在栈中为b开辟空间. (2)堆(heap):需程序员自己申请(调用mall ...

  6. 【 第2关:双栈的基本操作】【编程题实训-栈】【头歌】【bjfu-241】

    任务描述 本关任务:将编号为0和1的两个栈存放于一个数组空间V[m]中,栈底分别处于数组的两端.当第0号栈的栈顶指针top[0]等于-1时该栈为空:当第1号栈的栈顶指针top[1]等于m时,该栈为空. ...

  7. 函数调用过程详解:函数栈帧的创建与销毁

    前言:我们在学习C语言的过程中,可以会产生很多疑问,比如: 局部变量是怎么创建的 为什么局部变量的值不做初始化就是随机值 函数是怎么传参的?传参的顺序是怎么样的? 形参和实参是什么关系? 函数调用是怎 ...

  8. 给定入栈序列,判断一个串是否为出栈序列

    剑指offer22:给定入栈序列,判断一个串是否为出栈序列 public static boolean isOutStackSequence(int[] Spush, int[] Spop) {if ...

  9. 【计算机网络】数据链路层 : 选择重传协议 SR ( 帧分类 | “发送方“ 确认帧、超时事件 | “接受方“ 接收帧机制 | 滑动窗口长度 | 计算示例 )★

    文章目录 一. 选择重传协议 ( SR ) 引入 二. 选择重传协议 ( SR ) 帧分类 三. 发送方 事件 ( 确认帧.超时事件 ) 四. 接收方 事件 ( 接收帧 ) 五. 滑动窗口长度 五. ...

  10. 顺序栈初始化,判空,进栈,出栈,打印

    #include<iostream>#define maxSize 100 //后面没有分号 ; using namespace std;typedef struct //顺序栈的定义 { ...

最新文章

  1. 访问控制允许原始多个域?
  2. Oracle等待事件之Latch Free
  3. apache rewrite 支持post 数据
  4. shp系列(六)——利用C++进行Dbf文件的写(创建)
  5. 调用外部文件(ShellExecute)
  6. 电子设计大赛作品_第十四届电子设计大赛圆满结束!
  7. python 仪表盘_如何使用Python刮除仪表板
  8. 当前局域网禁止BT下载的常用工具及其弊端。
  9. 极客书的编程教程合集
  10. 前端-h5移动端星空效果登录界面
  11. 计算机键盘正确手势,打字时如何正确放置手指 正确的键盘打字手势(图文)...
  12. 计算机用户名怎么注册,微软账号怎么注册 Microsoft帐户注册使用教程
  13. 三星和华为均发布了5G手机芯片,谁的性能更强?
  14. DataFactory造数-前期准备工作(DF安装、myodbc32的安装与配置、Oracle客户端的安装与配置)
  15. SQL*Net message to client
  16. 主机如何连接到URSim中的客户端接口
  17. kaggle之识别谷歌街景图片中的字母
  18. 基于Linux (RHEL 5.5) 安装Oracle 10g RAC
  19. 如何使用Mojave将APFS卷上的MacOS Catalina Beta安装到双引导
  20. 正版photoshop2022购买体验经历分享

热门文章

  1. 使用高德地图的逆向地址,获取坐标点
  2. pip版本更新的问题
  3. Web前端:实现在一块区域(div)点击链接,在同一页面的指定区域显示链接的内容——基于css与div结合网页布局设计
  4. 量化交易 米筐 因子的打分对比(因子的对比与挑选)
  5. 详解小程序的蓝牙模块
  6. 计算机视觉应用之(四) -眼球跟踪
  7. C/C++ 函数(有序数组插入)
  8. 二、MySQL操作数据库
  9. win11找不到恢复环境怎么恢复出厂设置
  10. 《深度学习入门——基于Python的理论与实现》笔记