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 1b:000000000061FE08 heClo 2c: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 文件的大小

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

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

相关文章

MyBatis-Plus 总结

MyBatis-Plus简介 官网&#xff1a;https://baomidou.com/ GitHub&#xff1a;https://github.com/baomidou/mybatis-plus Gitee&#xff1a;https://gitee.com/baomidou/mybatis-plus 简介 MyBatis-Plus &#xff08;简称 MP&#xff09;是一个 MyBatis的增强工具&#x…

Unittest自动化测试框架vs Pytest自动化测试框架

引言 前面一篇文章Python单元测试框架介绍已经介绍了python单元测试框架&#xff0c;大家平时经常使用的是unittest&#xff0c;因为它比较基础&#xff0c;并且可以进行二次开发&#xff0c;如果你的开发水平很高&#xff0c;集成开发自动化测试平台也是可以的。而这篇文章主要…

3月18日英超两场足球比赛分析推荐

不知不觉文章分析的场次推荐已经4连红&#xff0c;昨日文章写的纽卡没有问题&#xff0c;扫盘中错的两场实属无奈&#xff0c;比勒费前半场领先2球优势被最后一分钟点球扳平。海牙带球入场结果后半场乏力被打穿&#xff01;球场上就是这么变化莫测&#xff0c;让人悲伤让人疯狂…

Unity人工智能之不断自我进化的五人足球赛

本文基于我前面发的两篇文章&#xff0c;需要对ML-Agents有一定的了解&#xff0c;详情请见&#xff1a;Unity强化学习之ML-Agents的使用、ML-Agents命令及配置大全。 我前面的相关文章有&#xff1a; ML-Agents案例之Crawler ML-Agents案例之推箱子游戏 ML-Agents案例之跳…

意甲第33轮尤文图斯VS博洛尼亚前瞻,尤文遇上“送分童子”

北京时间4月17日凌晨0&#xff1a;30&#xff0c;意甲第33轮将迎来一场焦点大战&#xff1a;尤文图斯主场迎战博洛尼亚。 本赛季的尤文&#xff0c;意甲、欧冠双线争雄&#xff0c;却经常让人捉摸不透。致力于打造快速、精准、全面的体育数据接口&#xff0c;提供赛事资讯、比赛…

Dataset之CIFAR-10:CIFAR-10数据集的简介、下载、使用方法之详细攻略

Dataset之CIFAR-10&#xff1a;CIFAR-10数据集的简介、下载、使用方法之详细攻略 目录 CIFAR-10的简介 1、与MNIST 数据集中目比&#xff0c; CIFAR-10 真高以下不同点 2、TensorFlow 官方示例的CIFAR-10 代码文件 3、CIFAR-10 数据集的数据文件名及用途 4、基于CIFAR-10数…

寒假第四天--排序--实况球员综合能力大比拼

实况球员综合能力大比拼 Time Limit: 1000MS Memory limit: 65535K 题目描述 大家都应该听说过实况足球吧&#xff0c;如果这个没听说过的话&#xff0c;大家应该听说过中国足球吧&#xff0c;无人不知无人不晓的神一样的队伍。 其实我们今天要讨论的话题主要是实况足球…

实况十 pes6

玩了两天删了实况九玩了两小时就删了在我看来实况的娱乐性一代不如一代可能是真实了&#xff0c;要真实我还不如自己踢阿不过ps上的实况确实完美&#xff0c;至于pc嘛实在不敢恭维 举几个例子&#xff1a;带球&#xff0c;实况8里的横拉为一大诟病&#xff0c;pes6确实改进不少…

软件测试考试中的环路复杂度、线性无关路径的理解

题目如下&#xff0c;回答问题1至3 int GetMaxDay (int year ,int month){int maxday0; //1if (month>1 && month <12) { //2,3if (month2) { //4if (year %4 0 ) { //5if (year %100 0) { //6if (year %400 0) {//7maxday29; //8else //9maxda…

【java】【项目实战】[外卖六]套餐管理业务开发

目录 一、新增套餐 1 需求分析 2 数据模型 3 代码实现 3.1 实体类SetmealDish 3.2 SetmealDto 3.3 SetmealDishMapper 3.4 SetmealDishService 3.5 SetmealDishServiceImpl 3.6 SetmealController 3.7 DishController 3.8 SetmealService 3.9 SetmealServiceImp…

学习JAVA打卡第四十四天

Scanner类 ⑴Scanner对象 scanner对象可以解析字符序列中的单词。 例如&#xff1a;对于string对象NBA 为了解析出NBA的字符序列中的单词&#xff0c;可以如下构造一个scanner对象。 将正则表达式作为分隔标记&#xff0c;即让scanner对象在解析操作时把与正则表达式匹配的字…

postman-使用Postman的模拟服务来模拟(mock)后端数据,完成前端模拟API调用

最近项目上比较忙&#xff0c;任务多时间紧&#xff0c;导致后端开发任务繁多&#xff0c;无法及时开发完毕&#xff0c;但是前端同学已经把对应功能开发完成&#xff0c;需要进行前后端联调来验证API及一些交互问题&#xff1b;这不能因为后端的进度来影响前端的工作完成情况&…

JAVA修练秘籍第五章《卧薪尝胆》

往期&#xff1a; JAVA 修炼秘籍第一章&#xff1a;《痛苦的折磨》 JAVA 修炼秘籍第二章&#xff1a;《逐渐魔化》 JAVA 修炼秘籍第三章&#xff1a;《绝地反击》 JAVA 修炼秘籍第四章&#xff1a;《闭关修炼》 文章目录 一、类和对象1.类的实例化2.属性3.方法 二、static关键字…

FreeMarker使用

说明&#xff1a;FreeMake可以通过设置一个模板&#xff0c;使用一些语法规则&#xff0c;可根据返回的VO数据填充到这个模板中&#xff0c;生成一个静态。这个技术&#xff0c;在项目中可以实现如预览页面的功能&#xff0c;将查询完成的VO数据按照这个模板填充&#xff0c;生…

网络模型分析

# 用户空间和内核空间 # 阻塞IO # 非阻塞IO # IO多路复用 IO多路复用-select 内核中遍历找到就绪的fd并保留&#xff0c;不匹配的就置为0&#xff0c; 以上的操作重复&#xff0c;知道所有的FD都完成 IO多路复用-poll IO多路复用-epoll IO多路复用-事件通知机制 很多进程都要用…

魔鬼之城

题目描述 在一个被分割为N*M个正方形房间的矩形魔鬼之城中&#xff0c;一个探险者必须遵循下列规则才能跳跃行动。他必须从(1, 1)进入&#xff0c;从(N, M)走出&#xff1b;在每一房间的墙壁上都写了一个魔法数字&#xff0c;是1&#xff5e;13之内的自然数&#xff1b;探险者可…

心灵毒药之CIA篇(二)

2019独角兽企业重金招聘Python工程师标准>>> 工欲善其事,必先利其器,而且最好是最锋利,最合适的器.因为器能成为你身体的延伸部分,同时还可以成为你信心的来源. 磨器的耐心,用器的巧心,藏器的无心. 转载于:https://my.oschina.net/piginwind/blog/713487

啊,万恶的this

一、全局下&#xff0c;this一般都指向window 全局下&#xff0c;ES5非严格模式&#xff0c;下面的this都是window。 console.log(this); function abc(){console.log(this); } abc();二、对象中的this 1、最常见的this情况&#xff1a; var a100;var obj{a:1,b:function()…

关押罪犯

题目&#xff1a; 描述S 城现有两座监狱&#xff0c;一共关押着 NNN 名罪犯&#xff0c;编号分别为 111 ~ NNN。他们之间的关系自然也极不和谐。 很多罪犯之间甚至积怨已久&#xff0c;如果客观条件具备则随时可能爆发冲突。 我们用 “怨气值”&#xff08;一个正整数值&#…