函数栈桢的创建和销毁

函数栈桢的创建和销毁

  • 一、解决的问题
  • 二、认识常用的寄存器及其指令操作
  • 三、函数栈桢解析
  • 三、回答问题

一、解决的问题

1.局部变量是怎么创建的?
2.为什么局部变量的值是随机值?
3.函数是怎么传参的?传参的顺序是怎样的?
4.形参和实参是什么关系?
5.函数调用是怎么做的?
6.函数调用是结束后怎么返回的?
7.return语句的本质是什么?

二、认识常用的寄存器及其指令操作

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

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

三、函数栈桢解析

  栈区(stack):1.在执⾏函数时,函数内局部变量的存储单元都可以在栈上创建,函数执⾏结束时这些存储单元⾃动被释放。栈内存分配运算内置于处理器的指令集中,效率很⾼,但是分配的内存容量有限。 栈区主要存放运⾏函数⽽分配的局部变量、函数参数、返回数据、返回地址等。
我的评价是:是说人话,虽然我现在理解的不是很清楚,栈这个区域是函数栈桢开辟的一块空间,在这一块空间里面主要是为函数来服务的,比如在函数内存的局部变量,函数的参数,函数的返回值,返回的地址,这些都是在栈这个空间服务的。至于说“”“栈内存分配运算内置于处理器的指令集中”这句话,我现在还感受不到,学的知识太浅,下来问老师。
栈桢开辟
下面我详细介绍函数栈桢的开辟与销毁过程,有写汇编指令看不懂,但是不影响看懂整个流程
1
先说一下,两个重要的寄存器,esp是栈顶寄存器,也就是存储栈顶地址的寄存器,ebp是栈底寄存器,这个寄存器维护的区域就是函数栈开辟的区域。
下面是在vs2022,x86下函数的开辟过程。
首先明白main也是函数,也是在栈区占用了一块空间,main函数是函数,它也是要被其它函数调用启动,具体是一个__tmainCRTStartup这个函数来调用main,在这一点具体的细节不讨论,以后学的知识多了在说。
看汇编代码,首先是把__tmainCRTStartup这个函数的栈底的地址压栈,存入栈区,为的是在函数返回过来,能够找到这个地方,然后是esp和ebp指向同一块区域,esp-0e4h,esp向上指,开辟了288个字节的空间给main函数的栈桢,之后ebx,esi,edi入栈,下来在main函数开辟的栈区,初始化了一部分空间,我上面的例子初始化了36个字节(填充为0xcc),然后给a,b,c三个变量开辟了空间,这个以8个字节为一部分向上开辟,这部分完了之后,就要对Add函数进行操作,特别重要在这里插入图片描述
先把形参入栈,在把形参x入栈,下来是在执行call指令的同时,把call指令的下一条指令地址入栈,方便返回,然后把main函数的栈底地址入栈,为的是能够找到main的栈底,然后又把ebp指向esp指向的地方,esp-0cch,给Add函数栈桢204个字节,还是ebx,esi,edi入栈,之后初始化一部分空间,这儿初始化了12个字节,之后给z开辟空间,通过eax寄存器把x和y取出来,运用add指令相加之后放到了z里面,而return的操作是把z的值给eax寄存器,通过eax寄存器把它带出来了,之后edi,exi,ebx出栈,之后,esp回到ebp的地方,在pop ebp,ebp回到main函数的栈底,维护main函数,由于以前把call的下一条指令地址压栈了,ret语句执行,esp-4,返回到call的下一条指令执行(这个call的返回可能是程序寄存器来完成),esp+8跳过两个形参x,y,esp来到main函数的栈顶,至此,分析完毕,esp和ebp又维护main函数的栈桢了。

三、回答问题

1.局部变量是怎么创建的?
*局部变量的创建是先给函数开辟空间,指的是esp和ebp之间的空间,然后在这一块空间里,给局部变量开辟空间。
2.为什么局部变量的值是随机值?
*在给函数一部分空间之后,要对这部分空间进行初始化,初始化给内存中填的值就是随机值。
3.函数是怎么传参的?传参的顺序是怎样的?
函数传参是在函数栈桢空间未分配之前,就已经通过压栈操作,把形参压入栈中,是从右向左压栈,取出正好是从左向右。
4.形参和实参是什么关系?
实参就是在函数栈桢内创建的,形参是压入栈中的,两个不是同一个空间,是完全不同的两块空间。
5.函数调用是怎么做的?
函数调用是在函数形参压入栈中,当需要参数来计算时,是通过寄存器(eax)把压入中的形参拿出来,进行使用。
6.函数调用是结束后怎么返回的?
函数在调用之前就已经把call的下一条指令的地址压入栈中了,函数调用结束后,通过ret指令,返回到call的下一条指令。
7.return语句的本质是什么?
return语句是通过寄存器eax把值带出函数的!

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

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

相关文章

python24.1.14while循环

当条件结束时间未知时,while循环比for循环更合适 实践

带你拿捏SpringBoot自动装配的核心技术?模块装配(@EnableXXX注解+@Import)+ 条件装配(@ConditionalXXX)

文章目录 Profile激活指定配置文件主配置文件中指定激活的profile命令行激活设置虚拟机参数激活 profile控制不到的地方 Spring原生的条件装配注解ConditionalConditional接口讲解案例讲解 Spring Boot封装的条件装配注解ConditionalXXX自己实现ConditionalOnBeanSpringBoot 源…

自制数据库空洞率清理工具-C版-03-EasyClean-V1.2(支持南大通用数据库Gbase8a)

目录 一、环境信息 二、简述 三、升级点 四、支持功能 五、空洞率 六、工具流程图 1、流程描述 2、注意点 (1)方法一 (2)方法二 七、清理空洞率流程图 八、安装包下载地址 九、参数介绍 1、命令模板 2、命令样例 3…

【集合大练习】---------------简易学生管理系统

目标: 实现学生对象新增,删除,查看,对象信息修改 整体实现思路: 1.定义学生类-------------创建学生对象 2.管理界面代码编写-------------命令提示面板 3.添加学生的代码编写---------add功能实现 4.查看学生信…

4、C语言:指针与数组

数组与指针 指针与地址指针与函数参数指针与数组地址算数运算字符指针与函数指针数组以及指向指针的指针多维数组命令行参数指向函数的指针复杂声明 指针是一种保存变量地址的变量。C语言中,指针的使用非常广泛,原因之一是,指针常常是表达某个…

智能合约笔记

前言: 首先了解下为什么会出现智能合约,打个比方现在有两个人A和B打赌明天会不会下雨,每个人赌注100元,如果第二天下雨则A拿走200元,否则B拿走200元,这样就有一个问题,赌注要到第二天才能见效&…

Python 中的字符串分割函数 split() 详解

更多Python学习内容:ipengtao.com 在 Python 编程中,处理字符串是一项常见的任务。字符串分割是其中的一个常见操作,而 Python 提供了强大的 split() 函数,用于将字符串拆分成多个部分。本文将详细介绍 split() 函数的用法、参数和…

Linux 转换文字编码与换行符 nkf命令

参考资料 【 nkf 】コマンド――文字コードと改行コードを変換するnkfコマンドでファイルの文字コードと改行コードを統一する 目录 一. 前期准备二. 乱码现象与分析三. nkf命令3.1 nkf --guess 查看文件编码3.2 nkf -w8 UTF-8(BOM)编码显示3.3 nkf -wd --overwrite 覆盖源文件…

MySQL核心SQL

一.结构化查询语言 SQL是结构化查询语言(Structure Query Language),它是关系型数据库的通用语言。 SQL 主要可以划分为以下 3 个类别: DDL(Data Definition Languages)语句 数据定义语言,这…

C#无标题栏窗体拖动代码

文章目录 一、概念二、案例三、常见问题四、链接 一、概念 C#(C Sharp)是由微软公司开发的一种面向对象的编程语言。它是从C和C语言演化而来的,并结合了Java和其他编程语言的特性。C#是微软.NET平台的一部分,允许开发人员创建各种…

EMC VNXe / Unity存储系统如何找回密码

开始之前,先简单说说,EMC的VNXe存储之间的关系。 EMC的VNXe和Unity存储的操作系统OS是一样的,当然不是完全一样,但是架构是一样的,先推出的产品是VNXe,然后在这个基础上演进到了Unity,Unity XT…

港大谷歌提出GO-NeRF:在NeRF中生成协调且高质量的3D对象

尽管在3D生成方面取得了进展,但在作为NeRF表示的现有3D场景中直接创建3D对象仍然是未经探索的。这个过程不仅需要高质量的3D对象生成,还需要将生成的3D内容无缝地合成到现有的NeRF中。为此,作者提出了一种新方法,GO-NeRF&#xff…

电脑定时关机应用

这是一个Python应用。家里卧室装了新电视,HDMI连接笔记本追剧还是很愉快的。可是经常睡着,自然忘了关机。搜了一大圈,都是用命令行或者bat解决。商店里的应用也不好用,有些还收费。于是萌生了自己写一个定时关机应用的想法。利用N…

监控平台zabbix介绍与部署

1. 完整的项目 业务架构:客户端 -> 防火墙 -> 负载均衡(四层、七层)-> Web缓存/应用 -> 业务逻辑(动态应用)-> 数据缓存 -> 数据持久 运维架构:运维客户端 -> 堡垒机/跳板机&#x…

TLC Nand Flash 存储单元的读取原理

我们知道Nand Flash使用浮栅晶体管作为存储单元(memory cell)来存储数据,浮栅晶体管物理结构如图1所示: 图1 浮栅晶体管 对于普通的晶体管(去掉浮栅晶体管中的浮栅层,floating gate)&#xff0…

基于Docker的Nginx的安装与配置

基于Docker的Nginx的安装与配置 1 为Nginx创建一个容器1.1 学习docker run1.2 通过docker run为Nginx创建并启动一个容器 2 配置Nginx2.1 学习docker的bind mount技术2.2 在Nginx容器中找到想修改的文件所在的目录2.2.1 认识nginx.conf文件2.2.2 访问Nginx服务,默认…

【MATLAB】VMD_LSTM神经网络时序预测算法

有意向获取代码,请转文末观看代码获取方式~也可转原文链接获取~ 1 基本定义 变分模态分解(Variational Mode Decomposition,VMD)和LSTM(Long Short-Term Memory)神经网络结合的算法是一种用于处理时间序列…

超详细的嵌入式cJSON使用注意事项,持续补充中......

文章目录 一、堆内存不足1.1 问题描述1.2 解决办法 二、内存泄露2.1 忘记Delete2.2 忘记Free2.3 串口数据接收缺少部分字符导致的内存泄露(自己的问题)问题分析 2.4 内存泄露在Cortex-M3内核会发生什么? cJSON开源库地址: cJSON 一、堆内存不足 1.1 问…

ssm基于Web的课堂管理系统设计与实现论文

目 录 目 录 I 摘 要 III ABSTRACT IV 1 绪论 1 1.1 课题背景 1 1.2 研究现状 1 1.3 研究内容 2 2 系统开发环境 3 2.1 vue技术 3 2.2 JAVA技术 3 2.3 MYSQL数据库 3 2.4 B/S结构 4 2.5 SSM框架技术 4 3 系统分析 5 3.1 可行性分析 5 3.1.1 技术可行性 5 3.1.2 操作可行性 5 3…

【GitHub项目推荐--开源的坦克大战】【转载】

坦克大战当年红遍大江南北,很多和我一样的九零后应该都有着对这个游戏的记忆。现在显示器分辨率越来越高,使用矢量图来实现像素风格游戏,可以获得非常高的展现质量。 这个项目是作者肥超花了很长时间折腾的复刻版本,所有元素都使…