关于Keil编译后的大小分析及存储位置

文章目录

前言

一、Code  Ro-data  RW-data  ZI-data是什么?

二、存储位置


前言

        当我们用keil编译程序后,会出现该工程的一些信息,如下图,其中我们可以看到编译后的程序大小(Program Size):Code:=xxx  Ro-data=xxx  RW-data=xxx  ZI-data=xxx。

一、Code  Ro-data  RW-data  ZI-data是什么?

  • Code代码区,存储我们自己写的所有代码;
  • Ro-data(Read Only):只读程序段,存储只能读的常量,如const型;
  • RW-data(Read Write):读写数据段,存储非零的全局变量;
  • ZI-data(Zero Initialze):0数据段,可以理解为没有初始化的全局变量;

        这时我们打开工程目录下的Listings文件夹,其中里面有一个.map的文件,可以用记事本的方式打开,拉到最下面有这么一个表:

二、存储位置

我们知道单片机中有片内flash和片内RAM,RAM相当于运行内存,而flash相当于电脑硬盘。 

   RO Size 包括Code和Ro Data ,表示程序占用Flash的大小。

   RW Size 包括 RW Data 和ZI Data ,表示运行时占用RAM的大小。

   ROM Size包括 Code、RO Data 和 RW Data,是我们烧录到Flash里的空间大小。

总结: 

   Flash 存储 Code + RO-Data

   SRAM存储 RW Data + ZI Data

        之所以 Rom没有包含ZI Data 是因为程序在运行之前ZI段的数据都会被清零,所以没必要去包含该块内存。

        程序运行之前,需要有文件实体被烧录到 STM32 的 Flash 中,一般是 bin 或者 hex 文件,该被烧录文件称为可执行映像文件。如下图左边部分所示,是可执行映像文件烧录到 STM32 后的内存分布,它包含 RO 段和 RW 段两个部分:其中 RO 段中保存了 Code、RO-data 的数据,RW 段保存了 RW-data 的数据,由于 ZI-data 都是 0,所以未包含在映像文件中。

        STM32 在上电启动之后默认从 Flash 启动,启动之后会将 RW 段中的 RW-data(初始化的全局变量)搬运到 RAM 中,但不会搬运 RO 段,即 CPU 的执行代码从 Flash 中读取,另外根据编译器给出的 ZI 地址和大小分配出 ZI 段,并将这块 RAM 区域清零。

        ——摘自RT_Thread文档

   相应的存储位置

扩展:

        堆区:由程序员自己在该块中申请的内存,如new或者malloc,如果用完后不及时释放,会导致内存泄漏。

        栈区:定义的局部变量和函数的形参,遵循先入后出的原则,编译器自动分配和释放。

猜你喜欢

转载自blog.csdn.net/qq_53734051/article/details/126405477