C语言-内存分布(STM32内存分析)

C/C++内存分布

  • 一、内存组成
  • 二、静态区域
      • 文本段 (Text / 只读区域 RO)
      • 已初始化读写数据段(RW data -- Initialized Data Segment)
      • 未初始化数据段(BSS -- Block Started by Symbol)
  • 三、动态区域
      • 堆(heap)
      • 栈(stack)
  • 四、STM32 内存分析
      • Flash区域
      • RAM区域
      • map文件分析

一、内存组成

根据动静特性可以将内存分为动态区域静态区域代码段(Code)、只读数据段(RO data)、读写数据段(RW Data)、未初始化数据段(BSS)属于静态区域属于动态区域
在这里插入图片描述

二、静态区域

在这里插入图片描述

文本段 (Text / 只读区域 RO)

通常代码段和只读数据段合成为文本段(Text), 包含实际要执行的代码(机器指令)和 常量(常量区Ro data),例如字符串常量等。它通常是共享的,多个实例之间共享文本段。文本段是不可修改的。

已初始化读写数据段(RW data – Initialized Data Segment)

已初始化数据是在程序中声明,并且具有初值的变量,这些变量需要占用存储器的空间,在程序执行时它们需要位于可读写的内存区域内,并具有初值,以供程序运行时读写。

未初始化数据段(BSS – Block Started by Symbol)

未初始化的全局变量和静态变量,程序运行之前不需要占用存储器的空间,BSS段的变量只有名称和大小却没有值。
BSS段主要是为了节省可执行文件在磁盘上所占的空间,其仅仅记录变量所需的大小。储存未初始化的,或初始化为0的全局变量和静态变量。 BSS段属于静态内存分配,所以放在RAM里。
对未初始化的大型数组的节省效率比较明显。举例如下:

static int a[10000];  
int main()  
{  
}  

在上述程序中,若不存在 BSS 段,则可执行文件将开辟一个 10000 * sizeof(int) 大小的空间,并全部存储为0,int 为4字节的情况下,该变量将在磁盘上占用39KB的空间。但是此时若是存在BSS 段,则在可执行文件中,将只是记录现在的BSS段总大小为40000即可,而无需真正的占据39KB的空间.

代码优化对BSS段的影响:全局变量与静态变量没有初始化或初始化值为0时,都会放在.bss段。初始化为非0值,则放在.data段。考虑以下两个静态变量分别存储在哪个段中:

static int x1 = 1;  
static int x2 = 0;  

很明显可以看出,X1将被发在.data段中。令人意外的是 X2 将被放置在 .bss 段中,因为 x2 的值为0,被认为是未初始化的,因此将会被放在 .bss 段中以节省磁盘空间。

三、动态区域

对于程序运行过程中的内存使用,堆和栈一般是相向扩展的。堆的分配由程序来分配,但是栈是由编译器管理的。
在这里插入图片描述

堆(heap)

  • 堆内存只在程序运行时出现,一般由程序员分配和释放。在具有操作系统的情况下,如果程序没有释放,操作系统可能在程序(例如一个进程)结束后回收内存。注意它与数据结构中的堆是两回事,其操作方式类似于数据结构中的链表

  • 当进程调用malloc等函数分配内存时,新分配的内存就被动态添加到堆上(堆被扩张);

  • 当利用free等函数释放内存时,被释放的内存从堆中被剔除(堆被缩减)。

FreeRTOS的内存分配有五个方案: 如果申请的内存空间都在一个连续的空间内heap_4就够用了,但如果存在部分空间申请在内部RAM、部分在外部RAM,这时候就需要使用heap_5方案了,heap_5是在heap_4基础上实现的。

特点缺点
heap_1简单、不支持内存释放需要管理内存空间
heap_2支持内存释放,不支持碎片管理需要管理内存空间、碎片问题
heap_3malloc-free操作简单碎片问题
heap_4支持碎片管理需要管理内存空间
heap_5支持多个不连续内存空间,碎片管理需要管理内存空间

栈(stack)

栈内存只在程序运行时出现,在函数内部使用的局部变量函数的参数以及返回值将使用栈空间,栈空间由编译器自动分配和释放。其操作方式类似于数据结构中的栈

例一:静态存储区、栈区、堆区

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main(void)
{
	char *a = "hello 1";	//静态存储区
	char b[] = "hello 2";	//栈区
	char *c = (char *)malloc(sizeof(b));	//堆区
	memcpy(c, "hello 3", sizeof(b));

	//a[2] = 'C';	//操作静态区会报错,只读不可修改
	b[2] = 'C';		//操作栈-修改成功
	c[2] = 'C';		//操作堆-修改成功
	printf(" a:%p %s\n b:%p %s\n c:%p %s\n",a,a,b,b,c,c);
    return 0;
}

程序运行结果如下

 a:0000000000404000 hello 1
 b:000000000061FE08 heClo 2
 c:00000000007F1400 heClo 3

四、STM32 内存分析

在对于RAM紧缺的嵌入式系统中,是缺少MMU内存管理单元的。因此在一些嵌入式系统中,比如常用的STM32来讲,内存映射被划分为闪存段(也被称为Flash,用于存储代码和只读数据)和 RAM段,用于存储读写数据。

在《ARM Cotrex-M3权威指南》中有关 M3的存储器映射表:
在这里插入图片描述

STM32的Flash和RAM地址范围,从图中我们可以看出,RAM地址是从0x2000 0000开始的,Flash地址是从0x8000 0000开始的。

Flash区域

在这里插入图片描述
如上图所示,Flash又可以分为这么几个部分。

  • 分别是文本段(Text) ,其中文本段中又包含可执行代码(Executable Code)和常量(Literal Value),在文本段之后就是只读
  • 数据区域(Read Only Data),当然并不是所有架构的单片机都满足这样一个排布规律,这里只针对于ARM Cortex M3系列的
  • 只读数据段后面接着的就是数据复制段(Copy of Data Section),第一次遇见这个概念的朋友看到数据复制可能会有疑惑,其实这个段充当的作用是存放程序中初始化为非0值得全局变量的初始值之所以要将初始值存放到这里 是因为全局变量是存放在RAM上的,RAM上的值掉电便丢失,每次上电之后这些变量是要重新赋值的,而重新赋值的值就存放在这里 那为什么不存放初始化为0的全局变量的初始值呢,原因也很简单,既然是初始化为0,那么在上电之后统一对存放初始化为0的全局变量的那块区域清0就好。

RAM区域

在这里插入图片描述
如上图所示,RAM中包含了如下几个部分,

  • 栈(Stack):存放局部变量和函数调用时返回的地址
  • 堆(heap):由malloc申请,free释放
  • bss:存放未初始化或者是初始化为0的全局变量
  • data:存放初始化为非0的全局变量

map文件分析

CodeRO DataRW DataZI Data
ExecutableCodeRead OnlyData data
  • 程序占用 Flash = Code + RO data + RW data

  • 程序运行时候占用 RAM = RW data + ZI data

  • Code + RO data + RW data 的大小也是生成的 bin 文件的大小

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

后端面试话术集锦第三篇:spring cloud 面试话术

这是后端面试集锦第三篇博文——spring cloud面试话术❗❗❗ 1. 什么是Springcloud Spring Cloud是一系列框架的集合,它利用Spring Boot的开发便利性简化了分布式系统的开发,比如服务发现、服务网关、服务路由、链路追踪等。 他的设计目的是为了简化Spring应用的搭建和开发…

C++算法 —— 分治(2)归并

文章目录 1、排序数组2、数组中的逆序对3、计算右侧小于当前元素的个数4、翻转对 1、排序数组 排序数组 排序数组也可以用归并排序来做。 vector<int> tmp;//写成全局是因为如果在每一次小的排序中都创建一次&#xff0c;更消耗时间和空间&#xff0c;设置成全局的就更高…

强大的思维导图库SimpleMindMap

本文软件是网友 Frank Yang 推荐的&#xff1b; 什么是 SimpleMindMap &#xff1f; Simple Mind Map 是一个简单、强大的 Web 思维导图库&#xff0c;不依赖任何特定框架&#xff0c;可以帮助你快速开发思维导图产品。同时 Simple Mind Map 也是一个思维导图软件。无论你是开发…

13.动态渲染侧边栏

为什么要动态渲染&#xff1f; 比如我们现在需要以下侧边栏的数据&#xff1a; 如果一个个的去写标签会很麻烦&#xff0c;发现导航栏中的数据分为两类&#xff0c;一类是一级导航&#xff0c;另一位是二级导航&#xff08;有子页&#xff09;&#xff0c;因此直接写两个函数判…

MVC模式分层练习

新建库 新建表 插入点数据 先不用MVC模式写功能,来看下缺点是什么 新建一个空项目 选项项目使用的JDK 自己的IDEA总是要重启下 新建模块 因maven还没教 添加框架支持 添加后项目多了这些 添加些必要依赖 这里注意下,如果导入jar包不对可以重新导入下或者是jar包本身出了问…

中东 Shopify 如何使用 Bytebase 构建一站式数据库开发工作流

公司简介 Salla 是一家 2016 年成立&#xff0c;位于沙特麦加的自建站电商平台。 作为中东 Shopify&#xff0c;其最大的特点是支持阿拉伯语建站&#xff0c;并且提供更多适应中东地区特点的本地化服务。截止目前&#xff0c;已有 47,000 家店铺入驻 Salla&#xff0c;商品销售…

已解决‘jupyter‘ 不是内部或外部命令,也不是可运行的程序或批处理文件报错

本文摘要&#xff1a;本文已解决‘jupyter‘ 不是内部或外部命令&#xff0c;也不是可运行的程序或批处理文件的相关报错问题&#xff0c;并系统性地总结提出了几种可用解决方案。同时结合人工智能GPT排除可能得隐患及错误。 &#x1f60e; 作者介绍&#xff1a;我是程序员洲洲…

C++--动态规划其他问题

1.一和零 力扣&#xff08;LeetCode&#xff09;官网 - 全球极客挚爱的技术成长平台 给你一个二进制字符串数组 strs 和两个整数 m 和 n 。 请你找出并返回 strs 的最大子集的长度&#xff0c;该子集中 最多 有 m 个 0 和 n 个 1 。 如果 x 的所有元素也是 y 的元素&#xff0…

ubuntu学习(六)----文件编程实现cp指令

1 思路 Linux要想复制一份文件通常指令为&#xff1a; cp src.c des.c 其中src.c为源文件&#xff0c;des.c为目标文件。 要想通过文件编程实现cp效果&#xff0c;思路如下 1 首先打开源文件 src.c 2 读src到buf 3 创建des.c 4 将buf写入到des.c 5 close两个文件 2 实现 vi …

容器技术Linux Namespaces和Cgroups

对操作系统了解多少&#xff0c;仅仅敲个命令吗 操作系统虚拟化&#xff08;容器技术&#xff09;的发展历程 1979 年&#xff0c;UNIX 的第 7 个版本引入了 Chroot 特性。Chroot 现在被认为是第一个操作系统虚拟化&#xff08;Operating system level virtualization&#x…

如何在 Vue TypeScript 项目使用 emits 事件

Vue是构建出色的Web应用程序的最灵活、灵活和强大的JavaScript框架之一。Vue中最重要的概念和关键特性之一是能够促进应用程序组件之间的通信。让我们深入探讨一下Vue中的“emits”概念&#xff0c;并了解它们如何以流畅和无缝的方式实现父子组件之间的通信。 Vue中的emits是什…

工控上位机程序为什么只能用C语言?

工控上位机程序并不只能用C#开发&#xff0c;实际上在工业自动化领域中&#xff0c;常见的上位机开发语言包括但不限于以下几种&#xff1a;C#: C#是一种常用的编程语言&#xff0c;在工控领域中被广泛使用。它具有良好的面向对象特性和丰富的类库支持&#xff0c;可以实现高性…

艾昆纬携手亚马逊云科技赋能生物医药企业,加速武田数字化转型

IQVIA艾昆纬是全球以及中国医疗健康服务领域的领导者&#xff0c;利用其数据及分析&#xff0c;前沿数字化技术和医疗领域的专业知识&#xff0c;智能连接医疗生态的各个环节。过去几年&#xff0c;IQVIA艾昆纬所服务的生物医药行业客户武田中国也迎来了数字化转型的高潮。 武田…

习题练习 C语言(暑期第三弹)

自我小提升&#xff01; 前言一、存储地址二、逗号表达式三、除自身以外数组的乘积四、字节与二进制五、符号计算六、不用加减乘除做加法七、unsigned判断八、移位计算九、sizeof宏十、移位计算十一、移位计算十二、优先级判断十三、单词倒排总结 前言 重要的事说三遍&#xf…

工厂方法模式的概述和使用

目录 一、工厂方法模式概述1. 定义2. 使用动机 二、工厂方法模式结构1. 模式结构2. 时序图 三、工厂方法模式的使用实例四、工厂方法模式的优缺点五、工厂方法模式在Java中应用 原文链接 一、工厂方法模式概述 1. 定义 工厂方法模式(Factory Method Pattern)又称为工厂模式&…

python3+requests:接口自动化测试(二)

前言&#xff1a;上篇文章python3requestsunittest&#xff1a;接口自动化测试&#xff08;一&#xff09;&#xff1a;已经介绍了基于unittest框架的实现接口自动化&#xff0c;但是也存在一些问题&#xff0c;比如最明显的测试数据和业务没有区分开&#xff0c;接口用例不便于…

禅道项目管理系统 - 操作使用 (2023版)

1. 部门-用户-权限 新增部门 新增用户 设置权限 2. 项目集创建 项目集 - 添加项目集 3. 产品线创建 产品 - 产品线 4. 产品创建 产品 - 产品列表 - 添加产品 5. 产品计划创建 产品 - xx产品 - 计划 - 创建计划 我这里创建3个计划 (一期, 二期, 三期) 6. 研发需求 - 创建模块…

设计模式-中介者模式

文章目录 一、前言二、中介者模式1、定义2、未使用/使用中介者模式对比2.1、未使用中介者模式&#xff1a;2.2、使用中介者模式&#xff1a; 3、角色分析3.1、中介者&#xff08;Mediator&#xff09;&#xff1a;3.2、同事&#xff08;Colleague&#xff09;&#xff1a;3.3、…

Springboot2.0 上传图片 jar包导出启动(第二章)

目录 一&#xff0c;目录文件结构讲解二&#xff0c;文件上传实战三&#xff0c;jar包方式运行web项目的文件上传和访问处理&#xff08;核心知识&#xff09;最后 一&#xff0c;目录文件结构讲解 简介&#xff1a;讲解SpringBoot目录文件结构和官方推荐的目录规范 1、目录讲解…

SAP_ABAP_接口技术_RFC远程函数实践总结

SAP ABAP顾问能力模型梳理_企业数字化建设者的博客-CSDN博客SAP Abap顾问能力模型&#xff0c;ALV/REPORT|SMARTFROM|SCREEN|OLE|BAPI|BDC|PI|IDOC|RFC|API|WEBSERVICE|Enhancement|UserExits|Badi|Debughttps://blog.csdn.net/java_zhong1990/article/details/132469977 SAP接…