原文链接:https://blog.csdn.net/D_azzle/article/details/83410141

截至到目前为止,本人接触单片机也有将近一年的时间。这一年以来也接触过了很具代表性的单片机,比如51、HT32、STM32等等。但是呢对于单片机的内存一直不了解,一直到现在,在一次单片机编程时我用到了malloc函数为指针分配内存空间。不知道为什么内存一直分配不成功。

所以这才去了解单片机的内存。下图是KELI编译成功后的输出信息。

在这里,我们先只关心Program Size这一行:

Code:代码指令占用的空间;

RO-data:Read Only Data的缩写。它的意义是只读常量占用的空间,比如const型常量、字符串常量等等;

RW-data:Read Write Data的缩写。它的意义是可读可写并且已初始化了的遍历所占用的空间,比如全局变量,静 态变量等等;

ZI-data:Zero Initialize Data的缩写。它的意义是以0初始化的变量,比如未初始化赋值的全局变量、静态变量等等;

而对单片机烧写程序时,FLASH被占用的空间大小为:Code + RO Data + RW Data,但是程序运行时使用到的RAM空间大小为:RW Data + ZI Data。

Why?

FALSH中被占用的空间 == 代码指令  + 只读数据值 + 已初始化变量的值。那么为什么程序运行时占用RAM空间大小 == RW Data + ZI Data呢?

我们都知道,在代码运行机制上单片机不同于PC,单片机的程序通常是在FALSH中直接取指执行,而PC是先把程序拷贝到RAM中再取指执行。因此单片机的RAM中不会存在Code拷贝(除非使用特殊方法强行使程序拷贝到了RAM中执行)。另外单片机RAM中也不会存在RO-data拷贝,因为RO-data是只读数据,为了节省RAM空间,这种数据在执行时直接从FLASH中取出使用,无需再复制到RAM。又由于RW Data和ZI Data是可读可写数据,为了供程序运行时正常读写,于是就会被放在单片机的RAM中(单片机的FLASH区不能被程序改写)

那么对于局部变量来说(RW Data和ZI data都是指的是全局变量或者静态变量),在C语言中全局变量和静态变量在RAM中都有一个特定的地址(存于静态区),而局部变量没有特定的地址。因此局部变量会被存放于堆栈中,当函数入栈时系统就会在栈顶开辟一段内存供局部变量使用,函数出栈时该内存就会被释放掉(静态局部变量除外)。

那么单片机程序在运行时RAM的使用量就等于RW Data + ZI Data了吗?还有没有其他因素会导致RAM占用变化?

玩过PC的都知道,一个程序在运行时它在内存中的占用情况是会随时改变的,这其中可能有压栈入栈和堆块的申请与释放等事件发生,那么在单片机里难道就没有这样的过程了吗?

其实单片机的RAM中也有堆栈区,因此程序运行时RAM的使用量就不会再等于RW Data + ZI Data了。(STM32的堆栈是存放于SRAM中的)而是等于 RW Data + ZI Data + Stack_Size + Heap_Size;

另外编译器并不会给变量一个内存,而是在内存中为变量指定一个地址,然后让其他变量不会重复指向该地址。在编译时编译器会把变量名用地址替换掉,这样也就达到了“编译器给变量分配了内存”的效果。那么,因为编译器为每个变量分配地址且不会让该地址被占用,由此可知RW Data 和 ZI Data这两块数据在被分配好内存之后一直会处于无法被回收的状态。因此如果没有新的程序烧录至单片机,RW Data + ZI Data区占用的空间是不会变的。

而对于堆栈区,堆栈区的大小是由启动文件确定的。函数入栈、出栈的过程变化的只是区内的数据而不是堆栈区的大小(入栈数量超过了栈区的大小限制则为爆栈)。因此没有新的程序烧录至单片机,堆栈区的大小也不会改变。

结论:ARM单片机中的FLASH占有量 == Code + RO Data + RW Data,程序运行时RAM的占有量 == RW Data + ZI Data + Stack_Size + Heap_Size

在KEIL下查看单片机编程内存使用情况的更多相关文章

  1. 操作系统复习——如何查看一个进程的详细信息,如何追踪一个进程的执行过程 ,如何在 Linux 系统下查看 CPU、内存、磁盘、IO、网卡情况?epoll和select区别?

    1. 如何查看一个进程的详细信息,如何追踪一个进程的执行过程 通过pstree命令(根据pid)进行查询进程内部当前运行了多少线程:# pstree -p 19135(进程号) 使用top命令查看(可 ...

  2. Linux查看CPU和内存使用情况 【转】

    Linux查看CPU和内存使用情况 在系统维护的过程中,随时可能有需要查看 CPU 使用率,并根据相应信息分析系统状况的需要.在 CentOS 中,可以通过 top 命令来查看 CPU 使用状况.运行 ...

  3. 测试页面,页面里边一次加载50张不同的图片,每张5M以上,查看浏览器的内存使用情况

    测试页面 1.需要你写个测试页面,页面里边一次加载50张不同的图片,每张5M,查看浏览器的内存使用情况 2.可以10张 递增的方式测试 3.图片需要缩放,比如所有图片缩放成600*800的比例 目的 ...

  4. Linux查看CPU和内存使用情况总结

    Linux查看CPU和内存使用情况:http://www.cnblogs.com/xd502djj/archive/2011/03/01/1968041.html 在做Linux系统优化的时候,物理内 ...

  5. 如何正确查看Linux机器内存使用情况

    如何正确查看Linux机器内存使用情况 背景 只要工作上涉及到Linux机器,基本上都会有这样一个需求,查看内存使用情况,但是怎么看才正确呢?之前使用的是top命令,一直存在一个误区. 为什么top命 ...

  6. 如何使用Linux命令行查看Linux服务器内存使用情况?

    一个服务器,最重要的资源之一就是内存,内存够不够用,是直接关系到系统性能的关键所在. 本文介绍如何查看Linux服务器内存使用情况, 1.free命令 free -m [root@localhost ...

  7. linux下对进程按照内存使用情况进行排序

    linux下对进程按照内存使用情况进行排序的命令为:ps aux --sort -rss 详细解说参见 http://alvinalexander.com/linux/unix-linux-proce ...

  8. 查看Linux服务器内存使用情况

    一个服务器,最重要的资源之一就是内存,内存够不够用,是直接关系到系统性能的关键所在. 本文介绍如何查看Linux服务器内存使用情况, 1.free命令 free -m [root@localhost ...

  9. ubuntu下查看服务器的CPU详细情况

    https://www.cnblogs.com/liuq/p/5623565.html 全面了解 Linux 服务器 - 1. 查看 Linux 服务器的 CPU 详细情况 ubuntu下查看服务器的 ...

随机推荐

  1. chromevue扩展 vue-devtools-master 谷歌vue的扩展程序

    1,在百度网盘中下载压缩包,网盘地址:https://pan.baidu.com/s/1BnwWHANHNyJzG3Krpy7S8A ,密码:xm6s 2,将压缩包解压到F盘,F:\chromeVue ...

  2. android开发 app闪退后fragment重叠bug解决方法,推荐使用第二种方法,完美解决问题

    解决方案为以下两种: 方法1:在fragmentActivity里oncreate方法判断savedInstanceState==null才生成新Fragment,否则不做处理. 方法2:在fragm ...

  3. sdf文件可以通过database net4工具升级版本

    用database .net4工具打开数据库后,右键数据库->数据库工具->upgrade to->to 4.0 or to 3.5; 可以用来判断数据库版本及是否要升级.

  4. Bitmap转ImageSource

    bitmap to bytes Bitmap b = new Bitmap( "test.bmp "); MemoryStream ms = new MemoryStream(); ...

  5. ios bug 分析

    ios中线上或者内部测试bug统计收集有两种方法: 1)使用第三方bug收集 1.bugHD 来源http://bughd.com/doc/ios-customize 2.bugtags 来源http ...

  6. Almost All Divisors(求因子个数及思维)

    ---恢复内容开始--- We guessed some integer number xx. You are given a list of almost all its divisors. Alm ...

  7. 组件给App全局传值vue-bus的使用

    npm安装 npm install vue-bus main.js引入 import VueBus from 'vue-bus' Vue.use(VueBus) 组件 getHouse(e){ thi ...

  8. wpf之DataGrid绑定DataTable,其中DataGridComboBoxColumn双向绑定枚举enum

    百度了快一天,没结果,除了几个原创的,都是复制粘贴的内容. 不想用别的笨办法,于是脑洞大开,想出了我的办法. 首先是前台代码,与网上的比较类似: xmlns:jz="clr-namespac ...

  9. (python)生产者消费者模型

    生产者消费者模型当中有两大类重要的角色,一个是生产者(负责造数据的任务),另一个是消费者(接收造出来的数据进行进一步的操作). 为什么要使用生产者消费者模型? 在并发编程中,如果生产者处理速度很快,而 ...

  10. vue父子传值与非父子传值

    大概梳理下传值的几种方式 一:父子组件传值 props方式 子组件对外暴露方法并向父组件传递由于触发方法导致的值的变化,父组件接收子组件传递来的值:子组件接收父组件传递来的值,并根据传递来的值在子组件 ...