当前位置: 首页 > news >正文

【C语言】函数栈帧的创建与销毁

 

Yan-英杰的主页

悟已往之不谏 知来者之可追


目录

​0.ebp和esp是如何来维护栈帧的呢?

1.为什么局部变量的值不初始化是随机的?

​2.局部变量是怎么创建的?

​3 .函数是如何传参的?传参的顺序是怎样的

4.函数是如何调用的

​5.形参和实参的关系

​6.函数调用结束后如何返回?


 

         在学习函数栈帧的创建与销毁前,我们应该理解寄存器的概念作为铺垫:esp ebp  eax ebx ecx(本质是一个计数器) edx等寄存器,其中esp ebp尤为重要,这是因为这两个寄存器中存放的是地址,而这两个地址是用来维护栈帧的   

0.ebp和esp是如何来维护栈帧的呢?

        当我们调用Main函数时

        当我们调用Add函数时

        注:通常我们成ebp为栈底指针,esp为栈顶指针,此外在32位环境下是ebp和esp而到了64位环境下栈底指针和栈顶指针变为rbp和rsp

        当我们弄懂了寄存器的概念,此时我们就正式开始学习函数的栈帧和创建,在学习前,带着疑问,进入学习:

1.为什么局部变量的值不初始化是随机的?

2.局部变量是怎么创建的?

3.函数是如何传参的?传参的顺序是怎样的?

4..函数是如何调用的?

5.形参和实参的关系?

6.函数调用结束后如何返回?

1.为什么局部变量的值不初始化是随机的?

 

        其他编辑器调用过程过于繁琐,不利于我们观察堆栈的调用过程,为了方便观察和学习,我们以VS2013为例,查看函数在堆栈中的调用情况

         通过该调用过程,我们不难看出,在调用main函数之前,我们首先调用了mainCRTStartup函数,通过mainCRTStartup函数调用了__tmainCRTStartup函数调用了main函数

        我们使用ebp(rbp)和esp(rsp)来维护main函数的栈帧空间,首先进行压栈,此时esp栈顶指针的位置上移,而后将esp的地址赋给ebp,使得ebp指向了esp

         而后我们开辟出了一块大为0E4h大小的栈帧空间,该空间即为main函数的栈帧空间,esp随着栈帧空间的开辟也随之发生了改变

而后我们再对其进行压栈,esp(栈顶指针)依旧随之发生改变

        通过这步操作,我们将ebp-24h的空间地址存储到edi中,也就是main函数的栈帧空间地址,往下看发现,其实该步真正起作用的地方为rep,它的意思就是,从edi开始,ecx次将eax的内容初始化为CCCCCCCC

        其实在这一步就证明了,为什么我们不对新创建的变量进行初始化,而其内容为随机值,就是因为其默认初始值为CCCCCCCC

2.局部变量是怎么创建的?

        我们将0Ah的内容放入ebp-8中,其实这0Ah所代表的就是变量a的值10,将14h的值放入epb-14h地址处(图像大小有限,我们很难准确画出,图中画出的只是大致范围)

3 .函数是如何传参的?传参的顺序是怎样的

        传参时我们将ebp-14h和ebp-8的地址分别传给eax和ecx寄存器,并进行压栈,esp的地址也随之发生改变

         我们通过该步骤调用了call命令,并将该地址保存在栈帧空间内部,esp再次发生改变,维护函数空间

        

4.函数是如何调用的

 

        通过该步骤,我们进行操作,将main函数的栈底进行压栈,esp的随栈帧空间发生改变,将esp的地址赋给ebp,我们开辟一块0CCh大小的空间,用来维护add函数的栈帧,对ebx,esi,edi等寄存器进行压栈,将epb-0Ch处的地址加载到edi中,同时初始化add函数栈帧空间的内容为0CCCCCCCCCh

5.形参和实参的关系

        我们常说形参其实是实参的临时拷贝,改变形参其实是无法改变实参的,具体原因是怎样的?

         该步骤,寻找到ebp-8的位置开辟变量Z的栈帧,将其初始化为0,将ebp+8和ebp+12的内容相加得出了x+y的和,其实我们这一步不难发现,我们在main函数中调用add函数进行传参,其实仅仅只是将实参的值放到两个寄存器内,进行压栈,我们在add函数中调用形参时,访问的其实是寄存器中的内容,这也是为什么,我们常说,形参是实参的临时拷贝,修改形参无法对实参造成任何影响

6.函数调用结束后如何返回?

         当调用结束后,将ebp-8的内容存储到eax寄存器中,同时将edi esi ebx出栈,此时esp维护空间也发生了变化,esp+00Ch,此时销毁了add函数的栈帧空间,将ebp的地址赋给esp,但是我们在main函数中留有call函数的地址,将其弹出,回头main函数中,同时esp+8,栈顶指针再次发生改变,同时将eax中add函数的返回值放到ebp-20中,此时才是真正意义的返回

 

相关文章:

【C语言】函数栈帧的创建与销毁

Yan-英杰的主页 悟已往之不谏 知来者之可追 目录 ​0.ebp和esp是如何来维护栈帧的呢? 1.为什么局部变量的值不初始化是随机的? ​2.局部变量是怎么创建的? ​3 .函数是如何传参的?传参的顺序是怎样的 4.函数是如何调用的 ​…...

【Git】使用Git上传项目到远程仓库Gitee码云步骤详解

电脑里存放了很多项目,有的备份,有的没备份,如果不仔细分类管理的话,时间一长,到时看到那就会觉得非常杂乱,很难整理,这里有一个叫源代码托管,用过它的都知道,方便管理和…...

Head First设计模式---3.装饰者模式

3.1装饰者模式 亦称: 装饰者模式、装饰器模式、Wrapper、Decorator 装饰模式是一种结构型设计模式, 允许你通过将对象放入包含行为的特殊封装对象中来为原对象绑定新的行为。 举个例子:天气很冷,我们一件一件穿衣服&#xff0c…...

Python 算法交易实验48 表字段设计

说明 虽然说的是表,实际上用的是Mongo集合 基于ADBS(APIFunc DataBase Service)可以构造一个供后续研究、生产长时间使用的数据基础,这个基础包括了: 1 队列服务。通过队列,数据可以通过API实现零担和批量两种模式的快速存储。2 …...

库存管理系统-课后程序(JAVA基础案例教程-黑马程序员编著-第六章-课后作业)

【案例6-1】 库存管理系统 【案例介绍】 1.任务描述 像商城和超市这样的地方,都需要有自己的库房,并且库房商品的库存变化有专人记录,这样才能保证商城和超市正常运转。 本例要求编写一个程序,模拟库存管理系统。该系统主要包…...

【极海APM32替代笔记】HAL库低功耗STOP停止模式的串口唤醒(解决进入以后立马唤醒、串口唤醒和回调无法一起使用、接收数据不全的问题)

【极海APM32替代笔记】HAL库低功耗STOP停止模式的串口唤醒(解决进入以后立马唤醒、串口唤醒和回调无法一起使用、接收数据不全的问题) 【STM32笔记】低功耗模式配置及避坑汇总 前文: blog.csdn.net/weixin_53403301/article/details/128216…...

Python类变量和实例变量(类属性和实例属性)

无论是类属性还是类方法,都无法像普通变量或者函数那样,在类的外部直接使用它们。我们可以将类看做一个独立的空间,则类属性其实就是在类体中定义的变量,类方法是在类体中定义的函数。 在类体中,根据变量定义的位置不…...

Glide加载图片

使用Glide加载图片,默认情况下在内存中缓存该图片。这样的情况下如果我们保存头像在某个路径,当再次更换头像时可能由于缓存问题,UI上更新的不及时。 默认加载图片方式: Glide.with(context).load(coverPath).error(R.drawable.a…...

有关时间复杂度和空间复杂度的练习

目录 一、消失的数字 二、轮转数组 三、 单选题 一、消失的数字 数组nums包含从0到n的所有整数,但其中缺了一个。请编写代码找出那个缺失的整数。你有办法在 O(n) 时间内完成吗? 注意:本题相对书上原题稍作改动 示例 1: 输入…...

linux服务器nfs数据挂载

参考:https://blog.csdn.net/qq_43721935/article/details/119889841?from_wecom1 1、NFS 介绍 NFS 即网络文件系统(Network File-System),可以通过网络让不同机器、不同系统之间可以实现文件共享。通过 NFS,可以访问…...

Python 自动化测试必会技能板块—unittest框架

说到 Python 的单元测试框架,想必接触过 Python 的朋友脑袋里第一个想到的就是 unittest。的确,作为 Python 的标准库,它很优秀,并被广泛应用于各个项目。但其实在 Python 众多项目中,主流的单元测试框架远不止这一个。…...

mysql存储引擎、事务、索引

目录MySQL进阶存储引擎什么是存储引擎常用存储引擎事务什么是事务怎么理解提交事务 和回滚事务事务特性事务的隔离级别索引什么是索引索引的实现原理什么条件下,我们会考虑给字段添加索引呢?什么条件下,索引会失效?索引分类MySQL进阶 存储引…...

毕业论文图片格式、分辨率选择及高质量Word转PDF方法

已知1:毕业论文盲评通常需要提交PDF文件。 已知2:PDF文件太大可能会导致翻页卡顿以及上传盲评网站失败。 已知3:Word转PDF方法不当可能会导致图像模糊。 已知4:打印机分辨率通常为300dpi。 问题1:论文插图分辨率设置…...

华为外包测试2年,不甘被替换,168天的学习转岗成正式员工

我25岁的时候,华为外包测试,薪资13.5k,人在深圳。 内卷什么的就不说了,而且人在外包那些高级精英年薪大几十的咱也接触不到,就说说外包吧。假设以我为界限,25岁一线城市13.5k,那22-24大部分情况…...

简单的C++:【运算符重载】新手易学

学过C语言的同志们应该都知道位运算符>> 和 << &#xff08;右移左移&#xff09;&#xff0c;但是这两个运算符在C中还是我们的输入和输出流操作符&#xff0c;那么这是为什么呢&#xff1f;&#xff0c;了解完本篇文章之后&#xff0c;我们再来回答这个问题。 C为…...

NPE:记一次脑残NPE的排查过程

目录 碎碎念&#xff1a; 如下这行报NPE&#xff1a; 排查过程&#xff1a; 解解方案&#xff1a; 小结&#xff1a; 空指针出现的几种情况&#xff1a; 如何从根源避免空指针&#xff1a; 赋值时自动拆箱出现空指针&#xff1a; 1、变量赋值自动拆箱出现的空指针 2、…...

canvas样式与颜色,字体,图片,状态,形变

色彩 fillStyle color 设置图形的填充颜色。 strokeStyle color 设置图形轮廓的颜色。 备注&#xff1a; 一旦您设置了 strokeStyle 或者 fillStyle 的值&#xff0c;那么这个新值就会成为新绘制的图形的默认值。如果你要给每个图形上不同的颜色&#xff0c;你需要重新设置…...

重识html

html 重识html 万维网用url统一资源定位符标识分布因特网上的各种文档 各种概念 URL: 统一资源定位器 它是WWW的统一资源定位标志&#xff0c;就是指网络地址 在WWW上&#xff0c;每一信息资源都有统一的且在网上唯一的地址 网页: 由文字 图片 视频 音乐各种元素排列组…...

Redis:缓存一致性问题(缓存更新策略)

Redis缓存的一致性1. 缓存1.1 缓存的作用&#xff1a;1.2 缓存的成本&#xff1a;2. 缓存模型3. 缓存一致性问题3.1 引入3.2 解决(1) 先更新数据库&#xff0c;再手动删除缓存(2) 使用事务保证原子性(3) 以Redis中的TTL为兜底3.3 案例&#xff1a;商铺信息查询和更新(1) 查询商…...

spring之声明式事务开发

文章目录一、声明式事务之全注解式开发1、新建springConfig类2、测试程序3、测试结果二、声明式事务之XML实现方式1、配置步骤2、测试程序3、运行结果附一、声明式事务之全注解式开发 基于之前的银行转账系统&#xff0c;将spring.xml配置文件嘎掉&#xff0c;变成全注解式开发…...

页面渲染流程与性能优化

页面渲染流程与性能优化详解&#xff08;完整版&#xff09; 一、现代浏览器渲染流程&#xff08;详细说明&#xff09; 1. 构建DOM树 浏览器接收到HTML文档后&#xff0c;会逐步解析并构建DOM&#xff08;Document Object Model&#xff09;树。具体过程如下&#xff1a; (…...

实现弹窗随键盘上移居中

实现弹窗随键盘上移的核心思路 在Android中&#xff0c;可以通过监听键盘的显示和隐藏事件&#xff0c;动态调整弹窗的位置。关键点在于获取键盘高度&#xff0c;并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...

python执行测试用例,allure报乱码且未成功生成报告

allure执行测试用例时显示乱码&#xff1a;‘allure’ &#xfffd;&#xfffd;&#xfffd;&#xfffd;&#xfffd;ڲ&#xfffd;&#xfffd;&#xfffd;&#xfffd;ⲿ&#xfffd;&#xfffd;&#xfffd;Ҳ&#xfffd;&#xfffd;&#xfffd;ǿ&#xfffd;&am…...

C# 求圆面积的程序(Program to find area of a circle)

给定半径r&#xff0c;求圆的面积。圆的面积应精确到小数点后5位。 例子&#xff1a; 输入&#xff1a;r 5 输出&#xff1a;78.53982 解释&#xff1a;由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982&#xff0c;因为我们只保留小数点后 5 位数字。 输…...

【SpringBoot自动化部署】

SpringBoot自动化部署方法 使用Jenkins进行持续集成与部署 Jenkins是最常用的自动化部署工具之一&#xff0c;能够实现代码拉取、构建、测试和部署的全流程自动化。 配置Jenkins任务时&#xff0c;需要添加Git仓库地址和凭证&#xff0c;设置构建触发器&#xff08;如GitHub…...

深度剖析 DeepSeek 开源模型部署与应用:策略、权衡与未来走向

在人工智能技术呈指数级发展的当下&#xff0c;大模型已然成为推动各行业变革的核心驱动力。DeepSeek 开源模型以其卓越的性能和灵活的开源特性&#xff0c;吸引了众多企业与开发者的目光。如何高效且合理地部署与运用 DeepSeek 模型&#xff0c;成为释放其巨大潜力的关键所在&…...

篇章二 论坛系统——系统设计

目录 2.系统设计 2.1 技术选型 2.2 设计数据库结构 2.2.1 数据库实体 1. 数据库设计 1.1 数据库名: forum db 1.2 表的设计 1.3 编写SQL 2.系统设计 2.1 技术选型 2.2 设计数据库结构 2.2.1 数据库实体 通过需求分析获得概念类并结合业务实现过程中的技术需要&#x…...

电脑桌面太单调,用Python写一个桌面小宠物应用。

下面是一个使用Python创建的简单桌面小宠物应用。这个小宠物会在桌面上游荡&#xff0c;可以响应鼠标点击&#xff0c;并且有简单的动画效果。 import tkinter as tk import random import time from PIL import Image, ImageTk import os import sysclass DesktopPet:def __i…...

边缘计算网关提升水产养殖尾水处理的远程运维效率

一、项目背景 随着水产养殖行业的快速发展&#xff0c;养殖尾水的处理成为了一个亟待解决的环保问题。传统的尾水处理方式不仅效率低下&#xff0c;而且难以实现精准监控和管理。为了提升尾水处理的效果和效率&#xff0c;同时降低人力成本&#xff0c;某大型水产养殖企业决定…...

2.2.2 ASPICE的需求分析

ASPICE的需求分析是汽车软件开发过程中至关重要的一环&#xff0c;它涉及到对需求进行详细分析、验证和确认&#xff0c;以确保软件产品能够满足客户和用户的需求。在ASPICE中&#xff0c;需求分析的关键步骤包括&#xff1a; 需求细化&#xff1a;将从需求收集阶段获得的高层需…...