栈(深入理解栈是什么)

这里写目录标题

        • 概念
        • 栈的初始化
        • 栈的溢出
        • 函数的栈帧
        • 函数的返回

概念

英文:stack,也叫做堆栈。
特点:先进后出。
栈的两个基本操作,也就是入栈和出栈。都是通过SP指针来维护。C语言中的函数的局部变量,传递的实参,返回的结果、编译器生成的临时变量都是保存在栈中。

栈的初始化

系统一上电,开始运行的都是汇编代码,在跳到第一个C语言函数运行之前,都要先初始化栈空间-----将栈指针指向内存中的一段空间,就完成了栈的初始化。
ARM处理器是使用SP寄存器和FP寄存器管理堆栈。
在LINUX环境下,栈的起始地址就是进程用户空间的最高地址,栈指针从高地址指向低地址增长。

栈的溢出

Linux中默认的每一个用户的进程时分配8MB的空间大小。

#include <stdio.h>
int main(void)
{char  a [ 8 *1024 *1024 ];int  i ;……
};

这种情况下,数组a保存在栈中,占用了8MB的栈空间,那这样别的局部变量i就没有存储空间了,就会造成了栈溢出。

为了避免栈溢出:

  1. 尽量不要使用的大的数组;
  2. 函数的嵌套层数不宜过深。
函数的栈帧

函数的栈帧除了保存局部变量与实参,还用来保存函数的上下文。每每调用过一次函数便会创建一个栈帧。
当函数运行完毕,栈帧将会销毁。

简单来说,就是使用EBP和ESP(被调用函数指针,总是指向函数栈顶)指针:
在这里插入图片描述

#include<stdio.h>int add(int a, int b)
{int c = 0;c = a + b;return c;
}int main()
{int a = 1;int b = 1;int sum;sum = add(a, b);return 0;
}

在这里插入图片描述

  1. 使用护当前ebp:
    由于我们马上要创建新的栈帧空间,因此ebp和esp都得将变动,为了能够让我们调用完add函数后还能让ebp回到当前位置我们需要对ebp的值进行保护,即将此时ebp的值压入栈(至于为什么不需要保护esp,看到后面你就能明白)
    在这里插入图片描述
  2. 创建所需调用函数的栈帧空间
    令ebp指向当前esp的位置并根据add函数的参数个数,创建一个大小合适的空间。
    在这里插入图片描述
    3. 创建空间
    在这里插入图片描述
    4. 保存局部变量
    将add函数中创建的变量"int c = 0"放入刚刚开辟的栈帧空间中
    在这里插入图片描述
  3. 参数运算
    根据形参与局部变量,进行对应的运算,这里执行"c = a +b", 得到 c = 2,放入刚才c对应的位置。
    在这里插入图片描述
    到这里,函数执行过程就结束了。
函数的返回

1.存储返回值
现在我们已经达成了目的"add(a,b)“,要将之前创建的add的函数栈销毁,以使得我们能够回到main函数中正常执行,而在销毁add的函数栈帧前我们的main函数可还没有拿到运算结果,因此我们需要先将需要返回的值存储起来,存储的位置就是前面提到的eax寄存器,这里"return c”,我们将c的值放到eax寄存器中。
在这里插入图片描述

  1. 销毁空间
    拿到了运算结果后,我们就没有任何任何顾虑了,可以直接销毁函数的栈桢空间了。
    在这里插入图片描述

  2. ebp回上一栈帧栈底
    此时ebp拿到之间存储的上一栈帧栈底的值,回到相应的位置,于此同时,存储的ebp没有用了,也将被销毁。
    在这里插入图片描述

  3. 销毁形参
    形参也不再有用,因此也随即销毁。
    在这里插入图片描述

  4. main函数拿到返回值

参考好文:
https://blog.csdn.net/Zero__two_/article/details/120781099

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

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

相关文章

态势感知是什么?在网络安全中有什么作用

态势感知是一种基于环境的、动态的、全面的洞察安全风险的能力。它以安全大数据为基础&#xff0c;从全局的角度&#xff0c;提高对安全威胁的发现识别、理解分析和处理反应能力。目的在于在大规模网络环境下&#xff0c;对能够引起网络态势变化的安全要素进行获取、理解、显示…

Docker安装与使用

Docker 1.初识Docker Docker如何解决大型项目依赖关系复杂&#xff0c;不同组件依赖的兼容性问题&#xff1f; Docker允许开发中将应用、依赖、函数库、配置一起打包&#xff0c;形成可移植镜像Docker应用运行在容器中&#xff0c;使用沙箱机制&#xff0c;相互隔离 Docker…

友思特分享 | 量产发布:首款在实时视频流中实现AI感知叠加的工业相机

友思特 IDS NXT malibu 的推出 标志着新一代智能工业相机的诞生 实现在设备端实时视频流与AI感知的叠加&#xff01; 实现AI流媒体 智能工业相机 malibu 采用了 Ambarella 最初用于运动相机的特殊芯片&#xff0c;可以高速&#xff08;>25fps&#xff09;实现全高清压缩视…

树莓派上电发送IP地址到邮箱

创建python脚本文件 auto_send_email.py #!/usr/bin/python3import subprocess import smtplib from email.mime.text import MIMEText import datetime import time import osdef check_ping():hostname "www.baidu.com"response os.system("ping -c 1 &quo…

zabbix、netdata和glances,做最简单的系统资源监控

软件需要显示服务器的资源信息&#xff08;CPU、内存、网络、硬盘等&#xff09;&#xff0c;但是软件是在Docker容器中运行。 目前方案 通过ssh在主机上远程运行ps、free等指令&#xff0c;获取相应的信息。这种方案需要代码配置主机的IP&#xff0c;以及用户名和密码&#…

【MATLAB】基于CEEMD分解的信号去噪算法(基础版)

代码的使用说明 【MATLAB】基于CEEMD分解的信号去噪算法&#xff08;基础版&#xff09; 代码流程图 代码效果图 获取代码请关注MATLAB科研小白的个人公众号&#xff08;即文章下方二维码&#xff09;&#xff0c;并回复CEEMD去噪 本公众号致力于解决找代码难&#xff0c;写代…

Flink核心概念

并行度 当要处理的数据量非常大时&#xff0c;我们可以把一个算子操作&#xff0c;“复制”多份到多个节点&#xff0c;数据来了之后就可以到其中任意一个执行。这样一来&#xff0c;一个算子任务就被拆分成了多个并行的“子任务”&#xff08;subtasks&#xff09;&#xff0…

node14升级node16之后,webpack3项目无法启动处理

node从14升级到16之后&#xff0c;项目就无法启动了&#xff0c;研究了webpack3升级5&#xff0c;研究好几个小时都无法启动&#xff0c;最后发现&#xff0c;微微升级几个版本就可以了。webpack还是3 版本改了好多个的&#xff0c;但是不确定具体是哪几个起作用的&#xff0c;…

110. 平衡二叉树(Java)

给定一个二叉树&#xff0c;判断它是否是高度平衡的二叉树。 本题中&#xff0c;一棵高度平衡二叉树定义为&#xff1a; 一个二叉树每个节点 的左右两个子树的高度差的绝对值不超过 1 。 示例 1&#xff1a; 输入&#xff1a;root [3,9,20,null,null,15,7] 输出&#xff1a;t…

AcWing 95. 费解的开关(递推)

题目链接 活动 - AcWing 本活动组织刷《算法竞赛进阶指南》&#xff0c;系统学习各种编程算法。主要面向有一定编程基础的同学。https://www.acwing.com/problem/content/97/ 题解 只要第一行开关的状态确定&#xff0c;则所有开关的状态都可以被推出来。第一行开关总共有种操…

Nginx的server层外层的常见配置语句的解读

有下面的Nginx配置: worker_processes auto; worker_rlimit_nofile 51200;events {use epoll;worker_connections 51200;multi_accept on; }http {include mime.types;default_type application/octet-stream;server_names_hash_bucket_size 512;client_max_body_size 50m;cli…

QT作业3

完善对话框&#xff0c;点击登录对话框&#xff0c;如果账号和密码匹配&#xff0c;则弹出信息对话框&#xff0c;给出提示”登录成功“&#xff0c;提供一个Ok按钮&#xff0c;用户点击Ok后&#xff0c;关闭登录界面&#xff0c;跳转到其他界面 如果账号和密码不匹配&#xf…