函数栈桢的创建和销毁

2024-01-14 16:12
文章标签 函数 创建 销毁 栈桢

本文主要是介绍函数栈桢的创建和销毁,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

函数栈桢的创建和销毁

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

一、解决的问题

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.chinasem.cn/article/605746

相关文章

MySQL分表自动化创建的实现方案

《MySQL分表自动化创建的实现方案》在数据库应用场景中,随着数据量的不断增长,单表存储数据可能会面临性能瓶颈,例如查询、插入、更新等操作的效率会逐渐降低,分表是一种有效的优化策略,它将数据分散存储在... 目录一、项目目的二、实现过程(一)mysql 事件调度器结合存储过程方式1. 开启事件调度器2. 创

mysql外键创建不成功/失效如何处理

《mysql外键创建不成功/失效如何处理》文章介绍了在MySQL5.5.40版本中,创建带有外键约束的`stu`和`grade`表时遇到的问题,发现`grade`表的`id`字段没有随着`studen... 当前mysql版本:SELECT VERSION();结果为:5.5.40。在复习mysql外键约

Window Server创建2台服务器的故障转移群集的图文教程

《WindowServer创建2台服务器的故障转移群集的图文教程》本文主要介绍了在WindowsServer系统上创建一个包含两台成员服务器的故障转移群集,文中通过图文示例介绍的非常详细,对大家的... 目录一、 准备条件二、在ServerB安装故障转移群集三、在ServerC安装故障转移群集,操作与Ser

Window Server2016 AD域的创建的方法步骤

《WindowServer2016AD域的创建的方法步骤》本文主要介绍了WindowServer2016AD域的创建的方法步骤,文中通过图文介绍的非常详细,对大家的学习或者工作具有一定的参考学习价... 目录一、准备条件二、在ServerA服务器中常见AD域管理器:三、创建AD域,域地址为“test.ly”

Python在固定文件夹批量创建固定后缀的文件(方法详解)

《Python在固定文件夹批量创建固定后缀的文件(方法详解)》文章讲述了如何使用Python批量创建后缀为.md的文件夹,生成100个,代码中需要修改的路径、前缀和后缀名,并提供了注意事项和代码示例,... 目录1. python需求的任务2. Python代码的实现3. 代码修改的位置4. 运行结果5.

使用IntelliJ IDEA创建简单的Java Web项目完整步骤

《使用IntelliJIDEA创建简单的JavaWeb项目完整步骤》:本文主要介绍如何使用IntelliJIDEA创建一个简单的JavaWeb项目,实现登录、注册和查看用户列表功能,使用Se... 目录前置准备项目功能实现步骤1. 创建项目2. 配置 Tomcat3. 项目文件结构4. 创建数据库和表5.

使用SpringBoot创建一个RESTful API的详细步骤

《使用SpringBoot创建一个RESTfulAPI的详细步骤》使用Java的SpringBoot创建RESTfulAPI可以满足多种开发场景,它提供了快速开发、易于配置、可扩展、可维护的优点,尤... 目录一、创建 Spring Boot 项目二、创建控制器类(Controller Class)三、运行

Oracle的to_date()函数详解

《Oracle的to_date()函数详解》Oracle的to_date()函数用于日期格式转换,需要注意Oracle中不区分大小写的MM和mm格式代码,应使用mi代替分钟,此外,Oracle还支持毫... 目录oracle的to_date()函数一.在使用Oracle的to_date函数来做日期转换二.日

JAVA中整型数组、字符串数组、整型数和字符串 的创建与转换的方法

《JAVA中整型数组、字符串数组、整型数和字符串的创建与转换的方法》本文介绍了Java中字符串、字符数组和整型数组的创建方法,以及它们之间的转换方法,还详细讲解了字符串中的一些常用方法,如index... 目录一、字符串、字符数组和整型数组的创建1、字符串的创建方法1.1 通过引用字符数组来创建字符串1.2

手把手教你idea中创建一个javaweb(webapp)项目详细图文教程

《手把手教你idea中创建一个javaweb(webapp)项目详细图文教程》:本文主要介绍如何使用IntelliJIDEA创建一个Maven项目,并配置Tomcat服务器进行运行,过程包括创建... 1.启动idea2.创建项目模板点击项目-新建项目-选择maven,显示如下页面输入项目名称,选择