函数帧栈的创建和销毁(一)

news2024/9/22 21:25:08

目录

什么是函数栈帧

理解函数栈帧能解决什么问题

函数栈帧的创建和销毁

什么是栈

认识相关寄存器和汇编指令

相关寄存器

相关汇编命令

esp和ebp 

解析函数栈帧的创建和销毁

学前补充

函数的调用堆栈  


什么是函数栈帧

        我们在写C 语言代码的时候,经常会把一个独立的功能抽象为函数,所以 C 程序是以函数为基本单位的。那函数是如何调用的?函数的返回值又是如何待会的?函数参数是如何传递的?这些问题都和函数栈帧有关系。
        函数栈帧(stack frame)就是函数调用过程中在程序的调用栈(call stack)所开辟的空间,这些空间是用来存放:
  • 函数参数和函数返回值
  • 临时变量(包括函数的非静态的局部变量以及编译器自动生产的其他临时变量)
  • 保存上下文信息(包括在函数调用前后需要保持不变的寄存器)

理解函数栈帧能解决什么问题

  1. 局部变量是如何创建的?
  2. 为什么局部变量不初始化内容是随机的?
  3. 函数调用时参数时如何传递的?传参的顺序是怎样的?
  4. 函数的形参和实参分别是怎样实例化的?
  5. 函数的返回值是如何带会的?

函数栈帧的创建和销毁

什么是栈

         栈(stack)是现代计算机程序里最为重要的概念之一,几乎每一个程序都使用了栈,没有栈就没有函数,没有局部变量,也就没有我们如今看到的所有的计算机语言。
        在经典的计算机科学中,栈被定义为一种特殊的容器,用户可以将数据压入栈中(入栈,push ),也可将已经压入栈中的数据弹出(出栈,pop ),但是栈这个容器必须遵守一条规则:先入栈的数据后出栈(First In Last Out FIFO )。
        就像叠成一叠的书,先叠上去的书在最下面,因此要最后才能取出。在计算机系统中,栈则是一个具有以上属性的动态内存区域。程序可以将数据压入栈中,也可以将数据从栈顶弹出。压栈操作使得栈增大,而弹出操作使得栈减小。 在经典的操作系统中,栈总是向下增长(由高地址向低地址)的。 在我们常见的i386 或者 x86-64 下,栈顶由成为 esp 的寄存器进行定位的。

认识相关寄存器和汇编指令

相关寄存器

eax :通用寄存器,保留临时数据,常用于返回值
ebx :通用寄存器,保留临时数据
ebp :栈底寄存器
esp :栈顶寄存器
eip :指令寄存器,保存当前指令的下一条指令的地址

相关汇编命令

mov :数据转移指令
push :数据入栈,同时 esp 栈顶寄存器也要发生改变
pop :数据弹出至指定位置,同时 esp 栈顶寄存器也要发生改变
sub :减法命令
add :加法命令
call :函数调用, 1 . 压入返回地址 2. 转入目标函数
jump :通过修改 eip ,转入目标函数,进行调用
ret :恢复返回地址,压入 eip ,类似 pop eip 命令

esp和ebp寄存器

        当函数调用发生时,栈上会为新的函数分配一块新的空间,这个空间通常被称为栈帧(stack frame)。在维护帧栈时,`ebp` 和 `esp` 寄存器通常会指向当前活动函数的栈帧底部和顶部。

        对于第一个空间(即当前活动函数的栈帧),`ebp` 通常会指向该空间的底部地址。而 `esp` 则是指向该空间顶部地址之上一个位置。也就是说,在只有一个空间时,它们都指向同一位置。

        当发生另一个函数调用并创建了新的栈帧后,旧的 `ebp` 的值将被保存到新创建的栈帧中,并且更新为指向新创建栈帧底部地址。此时,早期创建出来但尚未完成执行(即尚未返回)的那个函数所对应之前保留在堆上内存中已经存在了两份数据:一份是原始状态下保存着早期生成代码段信息、静态变量等数据;另外一份则是现场保护压入堆盏信息以及局部变量等数据。

因此,在这种情况下:

  • 早期生成代码段、静态变量等仍然可以通过原始 `ebp+偏移量1/2/3...n*4字节大小(32位系统)` 的方式访问
  • 新创建的栈帧中的局部变量等可以通过新 `ebp+偏移量1/2/3...n*4字节大小(32位系统)` 的方式访问

结论:ebp和 esp 寄存器在维护帧栈时会指向当前活动函数的栈帧底部和顶部

我们也可以将两个寄存器叫做栈顶指针和栈底指针

解析函数栈帧的创建和销毁

学前补充

1. 每一次函数调用,都要为本次函数调用开辟空间,就是函数栈帧的空间。
2. 使用2个寄存器esp和ebp维护函数帧栈空间 , ebp记录栈底地址, esp记录栈顶地址

3. 函数栈帧的创建和销毁过程,在不同的编译器上实现的方法大同小异

函数的调用堆栈  

#include <stdio.h>

int Add(int x, int y)
    {
        int z = 0;
        z = x + y;
        return z;
    }
int main()
{
    int a = 3;
    int b = 5;
    int ret = 0;
    ret = Add(a, b);
    printf("%d\n", ret);
    return 0;
}

        打开调试窗口的调用堆栈,发现在右侧的监视窗口中出现了__taminCRTStartup(),它表示在执行main函数时调用了__taminCRTStartup()这个堆栈,这就证明main也是被调用的,它在__taminCRTStartup()函数中被调用,此外,在监视窗口中还有一个函数mainCRTStartup(),__taminCRTStartup函数是在该函数中被调用的:

结论:main函数也是被其它函数调用的,当调用main函数之前就已经申请调用了两块空间,在mian函数中调用Add函数时,又会在main函数空间的上层为Add函数开辟一块空间,此时原本用于维护main函数的esp、ebp寄存器就会去维护Add函数栈帧的顶部和底部

~over~

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1325192.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

ThinkPad E550c

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、pandas是什么&#xff1f;二、使用步骤 1.引入库2.读入数据总结 前言 提示&#xff1a;这里可以添加本文要记录的大概内容&#xff1a; 例如&#xff1a;…

java8实战 lambda表达式、函数式接口、方法引用双冒号(中)

前言 书接上文&#xff0c;上一篇博客讲到了lambda表达式的应用场景&#xff0c;本篇接着将java8实战第三章的总结。建议读者先看第一篇博客 其他函数式接口例子 上一篇有讲到Java API也有其他的函数式接口&#xff0c;书里也举了2个例子&#xff0c;一个是java.util.functi…

2-高可用-负载均衡、反向代理

负载均衡、反向代理 upstream server即上游服务器&#xff0c;指Nginx负载均衡到的处理业务的服务器&#xff0c;也可以称之为real server,即真实处理业务的服务器。 对于负载均衡我们要关心的几个方面如下&#xff1a; 上游服务器配置&#xff1a;使用upstream server配置上…

mysql 23day DDL常用约束,数据类型

目录 数据库的四种语言常用约束&#xff08;DDL&#xff09;创建格式PRIMARY KEY&#xff1a;主键约束FOREIGN KEY&#xff1a;外键约束主键外键 联合测试开始测试 NOT NULL&#xff1a;非空约束UNIQUE&#xff1a;唯一约束DEFAULT&#xff1a;默认值约束zerofill 零填充auto_i…

vcomp140.dll丢失怎么办,vcomp140.dll丢失解决方法详解

在我多年的电脑使用经历中&#xff0c;我曾经遇到过一个非常棘手的问题&#xff0c;那就是vcomp140.dll丢失。这个问题让我苦恼了很久&#xff0c;但最终我还是找到了解决方法。今天&#xff0c;我想和大家分享一下我的经历&#xff0c;以及vcomp140.dll是什么&#xff0c;它丢…

AI创作系统ChatGPT商业运营网站系统源码,支持AI绘画,GPT语音对话+DALL-E3文生图

一、前言 SparkAi创作系统是基于ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统&#xff0c;支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美&#xff0c;可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如何搭建部署AI创作Ch…

用全志R128复刻自平衡赛车机器人,还实现了三种不同的操控方式

经常翻车的朋友们都知道&#xff0c;能在翻车后快速摆正车身的车才是好车。 就像动画《四驱兄弟》中展现的那样&#xff0c;在比赛中需要跟着赛车一起跑圈&#xff0c;而且赛车如果被撞翻还需要重新用手扶正&#xff0c;所浪费的时间非常影响比赛结果。 如果小豪和小烈可以拥有…

[电子榨菜] js中的闭包closure

0.写在前面: 下学期就打算去实习了,这段时间要密集接收考试和面试的捶打,计网和软工就没有办法为大家继续贡献开源内容了,明年九月份之前的更新内容将会以前端,人工智能,和工程设计为基础, 很抱歉啦,不过我还是希望我这一年来的努力可以帮到一些人.虽然自己这一年过的浑浑噩噩…

Docker容器的优化和性能调优技巧

Docker已经成为了现代应用程序开发和部署的核心工具之一。然而&#xff0c;要确保Docker容器在生产环境中运行稳定、高效&#xff0c;需要一些优化和性能调优的技巧。本文将介绍一些关键的Docker容器优化和性能调优策略&#xff0c;并提供丰富的示例代码&#xff0c;以帮助大家…

【精简】mysql创建自定义函数 sql写法举例

一&#xff0c;举例的sql是查询 某个时间点某个币种的汇率 create function get_rate(idate date,CURRENCY varchar(32)) returns decimal(21,6) begin declare res decimal(21,6) default 1;selec rate into resfromt_exchangerate tewhere ratedate idateand CURRENCYID C…

Apache Pulsar 技术系列 - PulsarClient 实现解析

导语 Apache Pulsar 是一个多租户、高性能的服务间消息传输解决方案&#xff0c;支持多租户、低延时、读写分离、跨地域复制&#xff08;GEO replication&#xff09;、快速扩容、灵活容错等特性。同时为了达到高性能&#xff0c;低延时、高可用&#xff0c;Pulsar 在客户端也…

【Linux C | 文件I/O】文件的打开关闭 | open、creat、colse 函数

&#x1f601;博客主页&#x1f601;&#xff1a;&#x1f680;https://blog.csdn.net/wkd_007&#x1f680; &#x1f911;博客内容&#x1f911;&#xff1a;&#x1f36d;嵌入式开发、Linux、C语言、C、数据结构、音视频&#x1f36d; &#x1f923;本文内容&#x1f923;&a…

windows安装、基本使用vim

标题&#xff1a;windows安装、基本使用vim 1.下载并安装GVIM 百度网盘链接 提取码&#xff1a;2apr 进入安装界面&#xff0c;如下&#xff0c;勾选 其它都是默认即可 参考&#xff1b; 2.在powershell中使用vim 参考blog&#xff1a;window10安装vim编辑器 安装好后&…

SpringBoot+WebSocket

SpringBootWebSocket 1.导入依赖&#xff1a; -- Spring Boot 2.x 使用 javax.websocket-- Spring Boot 3.x 使用 jakarta.websocket<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId&g…

C# WPF上位机开发(业务主流程才是核心)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 前面我们说了很多的c# wpf编程技术&#xff0c;里面有控件&#xff0c;有绘图&#xff0c;有数据库&#xff0c;有多线程等技术。但是他们都属于实…

宝塔Linux面板计划任务:文件夹改名方式天天切割日志脚本

新手第一次操作&#xff0c;目测成功且完美&#xff0c;供大家参考 current_time$(date %Y%m%d%H%M%S) old_folder_name"/www/wwwlogs" new_folder_name"/www/wwwlogs_${current_time}" mv "$old_folder_name" "$new_folder_name" m…

Inkscape SVG 编辑器 导入 Gazebo

概述 本教程描述了拉伸 SVG 文件的过程&#xff0c;这些文件是 2D 的 图像&#xff0c;用于在 Gazebo 中为您的模型创建 3D 网格。有时是 更容易在 Inkscape 或 Illustrator 等程序中设计模型的一部分。 在开始之前&#xff0c;请确保您熟悉模型编辑器。 本教程将向您展示如…

Backend - Django 项目创建 运行

目录 一、配置环境 二、创建 Django 项目 &#xff08;一&#xff09;新建文件夹 &#xff08;二&#xff09;打开文件夹 &#xff08;三&#xff09;打开运行终端 &#xff08;四&#xff09;创建基础项目 &#xff08;五&#xff09;创建app 1. 安装Django &#xf…

app上架-您的应用在运行时,未同步告知权限申请的使用目的,向用户索取(相机)等权限,不符合华为应用市场审核标准。

上架提示 您的应用在运行时&#xff0c;未同步告知权限申请的使用目的&#xff0c;向用户索取&#xff08;相机&#xff09;等权限&#xff0c;不符合华为应用市场审核标准。 测试步骤&#xff1a;管理-添加-点击二维码&#xff0c;申请相机权限 修改建议&#xff1a;APP在调…

Gazebo GUI模型编辑器

模型编辑器 现在我们将构建我们的简单机器人。我们将制作一个轮式车辆&#xff0c;并添加一个传感器&#xff0c;使我们能够让机器人跟随一个斑点&#xff08;人&#xff09;。 模型编辑器允许我们直接在图形用户界面 &#xff08;GUI&#xff09; 中构建简单的模型。对于更复…