内存管理--bss data txt数据段与stm32的ZI-data RW-data RO-data Code数据段的关系

news2025/2/7 22:19:55

目录

前沿

1 数据在内存中的位置

1.1 堆栈在内存中的位置

1.2 全局变量和局部变量在内存中的位置

1.2.1 全局变量在内存中的位置

1.2.2 局部变量在内存中的位置

1.3 static变量在内存中的位置

1.4 malloc赋值的变量存放在内存中的位置

1.5 代码在内存中的位置

2 ZI-data RW-data RO-data和Code数据段

2.1 各个数据段的含义

2.2 bss data和txt数据段和ZI-data RW-data RO-data和Code数据段的关系

2.3 各个数据段在内存中的位置

2.3 应用程序加载和执行图


前沿

        我们经常听人提起bss数据段,txt数据段,data数据段,但是我们不知道是什么意思,有些读者和博主一样,经常使用keil这个软件,所以只知道ZI-data数据段,RW-data数据段,RO-data数据段,Code数据段,那么他们存在什么样的关系呢,本小节带大家粗略的了解一下他们的关系,如果有错,请大家指出。

1 数据在内存中的位置

        要搞懂本节,我们需要了解数据在内存中的存储方式,我们最长听见的词语就是堆栈了,下面我们就从堆栈进行进行讲解。

1.1 堆栈在内存中的位置

        我们常说的堆栈,其实单指堆区,但是严格来说,堆区和栈区是分开的,堆区是需要malloc开辟空间的,然而栈区是存放局部变量的数据区,是由系统自动分配(大小由用户定义)。

        我们使用最多的就是栈区,栈区的生长方式是向上生长,后面的小节为大家详细的讲解何为向上生长。

注意:堆区和栈区是存放在RAM空间的

1.2 全局变量和局部变量在内存中的位置

1.2.1 全局变量在内存中的位置

        全局变量又分为初始化为非零的全局变量、没有初始化或初始化为0的全局变量和const修饰的全局变量,他们在内存中的方式也是不同的。

  • 初始化为非零的全局变量

        初始化为非零的全局变量存储在ROM空间,当程序运行的时候,会自动的加载到RAM空间。

  • 没有初始化或初始化为0的全局变量

        此类变量因为没有赋值(默认全局变量初始值为0),所以不必存放在ROM空间,所以此类变量存放在RAM空间

  • const修饰的全局变量

        const修饰的全局变量为只读变量,也叫常量,它存放在ROM空间。

注意:char *p = "1234"定义的字符串常量也存在ROM空间

1.2.2 局部变量在内存中的位置

        局部变量的初始值不固定,编译器不同初始值也存在一定的差异,所以使用局部变量的时候,需要给它赋值,它存放在栈区,也就是RAM空间。

1.3 static变量在内存中的位置

        static修饰的变量分为全局变量和局部变量。

  • 全局变量表示只能在当前文件中使用,不能被《extern》关键词修饰到其它文件中使用。
  • 局部变量默认初始值为0,并且不会被函数的生命周期影响,也就是函数执行完成,此类变量的值不会被改变,它存放在ROM空间

1.4 malloc赋值的变量存放在内存中的位置

        mallco修饰的变量存放在堆区,也就是RAM空间

1.5 代码在内存中的位置

        代码,就是可执行的程序,它根据需求的不同存放的位置也有所不同,但是一般是存放在ROM空间的

2 ZI-data RW-data RO-data和Code数据段

        我们在使用keil第一次编译或者重新编译程序的时候,《Build Output》窗口会显示《Program Size: Code=8180 RO-data=880 RW-data=296 ZI-data=2176  》等信息,由于现在的单片机的ROM(FLASH)和RAM都比较大(相较于传统单片机),一般的程序不必考虑内存的问题,即使存在内存问题,编译器也会给你报错,所以这个就会导致很多现代的工程师很少关注这个问题,但是如果你对内存很敏感,比如你需要规定你的程序大小不能超过1Kbyte,或者不能使用超过250byte的RAM空间,查看这里的信息就显得十分的有用了。

2.1 各个数据段的含义

Code:代码域,指的是编译器生成的及其指令,这些内容被存储在ROM区。

RO-data(Read Only Data):只读数据域,指的是程序中用到的只读数据,这些数据被存储在ROM区,并且程序不能修改其内容。例如C语言中的关键词const定义的变量就是典型的RO-data。

RW-data(Read Write Data):可读可写数据域,指的是初始值为“非零”的可读写数据,程序运行之前这些数据被存储在ROM区,这些数据具有非零的初始值,程序运行的时候被加载到RAM区,并且常驻于RAM区。应用程序能够修改其内容。例如C语言中定义的赋值不为0的全局变量就是典型的RW-data。

注意:关键词static定义的变量虽然默认值为0,但是也存在RW-data中。

ZI-data(Zero Initialize Data):初始值为0的数据域,指的是初始化为0值的可读可写数据域。它与RW-data的区别是这些数据一直存在RAM区,并且是在程序运行的时候才被加载到RAM区,且被赋予初始值0,而后续运行过程与RW-data的性质一致。例如C语言中定义的未赋值的全局变量或者赋值为0的全局变量(没有赋值的全局变量初始值默认为0)。

ZI-data的堆空间和栈空间:在C语言中,函数内部定义的局部变量属于栈空间,进入函数的时候向栈空间申请内存给局部变量,退出时释放局部变量,归返内存空间。而使用malloc动态分配的变量属于堆空间。在程序中的堆和栈空间都属于ZI-data区域,这些空间都会被初始化为0,编译器给出的ZI-data占用的空间值中包含了堆栈的大小(若程序没有使用malloc动态申请内存,编译器会优化堆空间,不会把堆空间计算在内)。

注意:局部变量的初始值为0是因为在程序运行的时候局部变量被赋予0值,但是当程序运行的时候,堆栈不停的交换数据,所以当程序运行到某个局部变量的时候,此局部变量的值就为留在堆栈的随机值,因此上学的时候所说的局部变量的值是随机值由此而来。

2.2 bss data和txt数据段和ZI-data RW-data RO-data和Code数据段的关系

程序组件

所属类别

机器代码指令

Code(txt)

常量

RO-data(data)

初始非0的全局变量

RW-data(data)

Static定义的变量

RW-data(data)

初始为0的全部变量

ZI-data(bss)

局部变量

ZI-data栈空间(bss)

使用malloc动态分配的空间

ZI-data堆空间(bss)

2.3 各个数据段在内存中的位置

        RAM和ROM区域存储的数据如下:

  • Total RO Size (Code + RO Data)
  • Total RW Size (RW Data + ZI Data)
  • Total ROM Size (Code + RO Data + RW Data)
  • Total RAM Size (ZI Data + RW Data)

        下图表示RAM区存储的数据结构。栈区向上生长是压栈的时候SP指针减寄存器的大小,出栈的时候SP指针加上寄存器的大小,这就是所谓的向上生长。

        下图是压栈时SP指针值的变化。

        下图是出栈时SP指针值的变化。

        整个流程称为SP的压栈和出栈,可以看出它压栈的时候,是从高地址往低地址进行压栈的,这种方式称为向上生长。

2.3 应用程序加载和执行图

       当我们编译下载程序到ARM-M系列单片机中的时候,我们的程序存放在ROM空间的位置如左图所示,依次为DATA(R0)(此处为中断向量表),Code,Data(RO),Data(RW),程序复位的时候,PC默认指向0x08000004位置(0x08000000存放的是栈顶值),在复位的同时,程序会把存放在ROM空间的Data(RW)值加载到RAM空间(为了提高执行效率)。

        BSS(ZI)数据段也就是Data(ZI)数据段,它根据编译器不同存放的位置有所差异,常见是不存放在ROM空间的。

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

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

相关文章

udp广播的例子

以下是一个使用C语言描述广播发送和接收的简单示例&#xff1a; 发送端&#xff08;广播发送&#xff09;&#xff1a; #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <netinet/in.h> #inclu…

如何使用Docker将.Net6项目部署到Linux服务器(二)

目录 二 安装Redis 2.1 基本安装 2.1.1 下载Redis 2.1.2 解压并安装Redis 2.1.3 编译Redis 2.1.3 配置config文件 2.1.4 配置redis服务 2.1.5 关闭redis服务 2.2 Docker安装 2.2.1 拉取镜像 2.2.2 查看镜像 2.2.2 创建挂载目录 2.2.3 创建配置文件 2.2.4 创建容器…

几种串口扩展电路

一、IIC串口扩展电路 LCT200 是一款可以通过 I2C 接口通讯&#xff0c;拓展 2 路独立串口的通讯芯片&#xff0c;同时也支持通过 2 路串口读写 I2C 接口的数据。LCT200 的封装为 TSSOP-20。 主要功能&#xff1a;⚫ 通过对 I2C 接口读写实现拓展 2 路独立串口功能 ⚫ 通过读写…

Linux学习教程(第十八章 SELinux管理)

第十八章 SELinux管理 root 用户实在是一个超人&#xff0c;它在 Linux 系统当中就是无所不能的&#xff0c;而且读、写和执行权限对 root 用户完全没有作用。root 用户的存在极大地方便了 Linux 的管理&#xff0c;但是也造成了一定的安全隐患。 大家想象一下&#xff0c;如果…

LabVIEW与PID在温度测控系统中的应用

LabVIEW与PID在温度测控系统中的应用 本案例介绍LabVIEW在温度控制系统中的应用&#xff0c;特别是结合PID算法。项目使用abVIEW作为主要开发工具&#xff0c;配合NI PCI-7831R数据采集和控制设备&#xff0c;实现了高效的温度调节。 系统的核心在于LabVIEW的FPGA模块&#x…

编译opencv和opencv_contrib

1 下载源码 下载opencv源码https://github.com/opencv/opencv 下载opencv源码https://github.com/opencv/opencv_contrib 2 开始编译 构建需要下载ffmpeg的包&#xff0c;cmake构建时会自动下载&#xff0c;但是比较满&#xff0c;这里可以从下面链接直接下载 https://downloa…

怎么判断台灯是否护眼?分享适合考研使用的护眼台灯

虽然台灯是家家户户都会有的一盏照明设备&#xff0c;但是很多人并不是了解自家台灯是好是坏&#xff0c;能不能护眼等等。其实台灯是非常有讲究的&#xff0c;如果长期使用一些不合格、劣质的台灯&#xff0c;会让我们在不知不觉中造成视力损伤&#xff0c;从而导致近视。 也…

中后缀表达式

一、利用后缀表达式进行计算 1&#xff09;解题思路 如果当前字符串是操作数&#xff0c;就将该操作数入栈&#xff1b;如果当前字符串是操作符&#xff0c;就取栈顶的两个操作数进行运算&#xff08;注意&#xff1a;第一个出栈的数为计算时的右操作数&#xff1b;第二个出栈…

【深度学习-目标检测】03 - Faster R-CNN 论文学习与总结

论文地址&#xff1a;Faster R-CNN: Towards Real-Time ObjectDetection with Region Proposal Networks 论文学习 1. 摘要与引言 研究背景与挑战&#xff1a;当前最先进的目标检测网络依赖于 区域提议&#xff08;Region Proposals&#xff09;来假设目标的位置&#xff0c…

计算机服务器中了halo勒索病毒如何解密,halo勒索病毒解密数据恢复

计算机技术的不断发展&#xff0c;为企业的生产运营提供了极大便利&#xff0c;但也为网络安全埋下隐患&#xff0c;网络上的勒索病毒种类也在不断增加&#xff0c;给企业的数据安全带来了严重威胁。近日&#xff0c;云天数据恢复中心接到许多企业的求助&#xff0c;企业的计算…

HarmonyOS应用程序包-(上)

应用程序包-(上) 1.应用程序包概述 用户应用程序泛指运行在设备的操作系统之上&#xff0c;为用户提供特定服务的程序&#xff0c;简称“应用”。一个应用所对应的软件包文件&#xff0c;称为“应用程序包”。 HarmonyOS提供了应用程序包开发、安装、查询、更新、卸载的管理…

【Spring实战】06 ApplicationRunner

文章目录 1. 简介2. 使用1&#xff09;单个 ApplicationRunner2&#xff09;获取命令行参数3&#xff09;多个 ApplicationRunner 3. 优点4. 缺点总结 ApplicationRunner 是 Spring Boot 提供的一个接口&#xff0c;与 CommandLineRunner 类似&#xff0c;用于在 Spring Boot 应…

Linux文件编程

目录 1、Linux系统提供的文件编程API 1.1打开文件&#xff1a;open 1.2创建文件creat函数 1.3写入文件write函数 1.4读取文件read函数 1.5文件光标位置lseek函数 2、另外一组文件编程API 2.1文件打开函数fopen 2.2读文件函数fread 2.3写文件函数fwrite 2.4文件光标位…

jquery Tab切换,CSS3制作发光字

jquery Tab切换&#xff0c;CSS3制作发光字 代码如下 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><meta ht…

App应用如何在应用市场获得更多下载量?

App的转化率至关重要&#xff0c;App如何获得更多用户&#xff0c;提高应用的下载量&#xff1f; 据 Apple 称&#xff0c;每周有 6.5亿访问者访问应用商店&#xff0c;77%的应用下载来自 iOS 应用商店的自然搜索。随着 Apple 默认关闭了IDFA&#xff0c;自然搜索比以往任何时…

Exploring the Limits of Masked Visual Representation Learning at Scale论文笔记

论文名称&#xff1a;EVA: Exploring the Limits of Masked Visual Representation Learning at Scale 发表时间&#xff1a;CVPR2023 作者及组织&#xff1a;北京人工智能研究院&#xff1b;华中科技大学&#xff1b;浙江大学&#xff1b;北京理工大学 GitHub&#xff1a;http…

OpenCV之图像匹配与定位

利用图像特征的keypoints和descriptor来实现图像的匹配与定位。图像匹配算法主要有暴力匹配和FLANN匹配&#xff0c;而图像定位是通过图像匹配结果来反向查询它们在目标图片中的具体坐标位置。 以QQ登录界面为例&#xff0c;将整个QQ登录界面保存为QQ.png文件&#xff0c;QQ登…

百度Apollo五步入门自动驾驶:Dreamview与离线数据包分析(文末赠送apollo周边)

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏:《linux深造日志》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! ⛳️ 粉丝福利活动 ✅参与方式&#xff1a;通过连接报名观看课程&#xff0c;即可免费获取精美周边 ⛳️活动链接&#xf…

Kind创建k8s - JAVA操作控制

kind 简介kind 架构安装 Kind (必备工具)docker官网kubectl官网kind官网校验安装结果 关于kind 命令 安装一个集群查看当前 Kubernetes 集群中的节点信息。查看当前命名空间下中的Pod&#xff08;容器实例&#xff09;的信息。使用 kind create cluster 安装&#xff0c;关于安…

分布式下有哪些好用的监控组件?

在之前的内容中&#xff0c;分析了分布式系统下的线上服务监控的常用指标&#xff0c;那么在实际开发中&#xff0c;如何收集各个监控指标呢&#xff1f;线上出现告警之后&#xff0c;又如何快速处理呢&#xff1f;本文我们就来看下这两个问题。 常用监控组件 目前分布式系统…