keil5编译后生成 Program Size: Code RO-data RW-data ZI-data是什么

 在keil5下全编译了这么多次代码,每次编译完了后都有这么一行提示,闲来没事还是搜索学习了一下。

Program Size: Code=49560 RO-data=7032 RW-data=308 ZI-data=1100180 (数据当然是不一样的哈) 

通过查阅keil5的帮助文档(ARM Development Tools),看到样的的一个数据,如图

 

Code (inc. data)   RO Data   RW Data    ZI Data      Debug
3712        1580        19        44      10200       7436   Object Totals
0              0        16         0          0          0   (incl. Generated)
0              0         3         0          0          0   (incl. Padding)
21376        648       805         4        300      10216   Library Totals 
0              0         6         0          0          0   (incl. Padding)
===============================================================================
Code (inc. data)   RO Data    RW Data    ZI Data      Debug
25088       2228       824         48      10500      17652   Grand Totals
25088       2228       824         48      10500      17652   ELF Image Totals
25088       2228       824         48          0          0   ROM Totals
===============================================================================
Total RO  Size (Code + RO Data)             25912 (  25.30kB)
Total RW  Size (RW Data + ZI Data)          10548 (  10.30kB)
Total ROM Size (Code + RO Data + RW Data)   25960 (  25.35kB)

 (1)Code (inc. data): 网上多大说的是程序代码所占的字节数。但是这种说法并不完全,在官方文档中这么
    一句话:Shows how many bytes are occupied by code. In this image, there are 3712 bytes of code. 
    This includes 1580 bytes of inline data (inc. data), for example, literal pools, and short strings.

    (意思就是说显示代码占用了多少字节。 在上面的这个表中,有3712个字节的代码。 这包括1580字节的内联
    数据,例如文字池短字符串)

    Code中不仅仅包含了代码的大小。其中还包括了inline data(内联数据),比如literal pools(文字池)
    和short strings(短字符串)

 (2)RO-data: 表示程序中的只读常量数据。比如const类型的数据 (除inline data之外的只读数据)。

 (3)RW-data: 表示可读写变量的大小,也就是说是程序中已经初始化的变量大小。

 (4)ZI-data: 表示程序中未初始化的变量大小。就是程序中已经定义但是初始化值为0或者
   是没有初始化赋值的变量(编译器会默认把没有赋值的变量自动赋值为0)。


  下面对几个数值的关系进行说明

  ROM size:  也就是下载到单片机FLASH中的数据为  Code +RO-data +RW-data 和的大小。
  为什么不把ZI-data 也下载进去呢? 其实是没有必要的,这是浪费空间,只要程序一上电运
  行就会把ZI-data 自动清0。

  RAM size: 程序运行时所需要的大小空间为 RW-data+ ZI-data

 

  2019.10.26补充:

最近在学习RT_Thread中,看到里面的文档对这部分分析得很细致,分享一下https://www.rt-thread.org/document/site/programming-manual/basic/basic/。

我也搬运一下,记录学习记录。

一般 MCU 包含的存储空间有:片内 Flash 与片内 RAM,RAM 相当于内存,Flash 相当于硬盘。编译器会将一个程序分类为好几个部分,分别存储在 MCU 不同的存储区。

Keil 工程在编译完之后,会有相应的程序所占用的空间提示信息,如下所示:

linking...
Program Size: Code=48008 RO-data=5660 RW-data=604 ZI-data=2124
After Build - User command \#1: fromelf --bin.\\build\\rtthread-stm32.axf--output rtthread.bin
".\\build\\rtthread-stm32.axf" - 0 Error(s), 0 Warning(s).
Build Time Elapsed: 00:00:07

上面提到的 Program Size 包含以下几个部分:

1)Code:代码段,存放程序的代码部分;

2)RO-data:只读数据段,存放程序中定义的常量;

3)RW-data:读写数据段,存放初始化为非 0 值的全局变量;

4)ZI-data:0 数据段,存放未初始化的全局变量及初始化为 0 的变量;

编译完工程会生成一个. map 的文件,该文件说明了各个函数占用的尺寸和地址,在文件的最后几行也说明了上面几个字段的关系:

Total RO Size (Code + RO Data) 53668 ( 52.41kB)
Total RW Size (RW Data + ZI Data) 2728 ( 2.66kB)
Total ROM Size (Code + RO Data + RW Data) 53780 ( 52.52kB)

1)RO Size 包含了 Code 及 RO-data,表示程序占用 Flash 空间的大小;

2)RW Size 包含了 RW-data 及 ZI-data,表示运行时占用的 RAM 的大小;

3)ROM Size 包含了 Code、RO Data 以及 RW Data,表示烧写程序所占用的 Flash 空间的大小;

程序运行之前,需要有文件实体被烧录到 STM32 的 Flash 中,一般是 bin 或者 hex 文件,该被烧录文件称为可执行映像文件。如图 3-3 中左图所示,是可执行映像文件烧录到 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 区域清零。

keil5编译后生成 Program Size: Code RO-data RW-data ZI-data是什么_第1张图片

其中动态内存堆为未使用的 RAM 空间,应用程序申请和释放的内存块都来自该空间。

如下面的例子:

rt_uint8_t* msg_ptr;
msg_ptr = (rt_uint8_t*) rt_malloc (128);
rt_memset(msg_ptr, 0, 128);

代码中的 msg_ptr 指针指向的 128 字节内存空间位于动态内存堆空间中。

而一些全局变量则是存放于 RW 段和 ZI 段中,RW 段存放的是具有初始值的全局变量(而常量形式的全局变量则放置在 RO 段中,是只读属性的),ZI 段存放的系统未初始化的全局变量,如下面的例子:

#include 

const static rt_uint32_t sensor_enable = 0x000000FE;
rt_uint32_t sensor_value;
rt_bool_t sensor_inited = RT_FALSE;

void sensor_init()
{
     /* ... */
}

sensor_value 存放在 ZI 段中,系统启动后会自动初始化成零(由用户程序或编译器提供的一些库函数初始化成零)。sensor_inited 变量则存放在 RW 段中,而 sensor_enable 存放在 RO 段中。

 

你可能感兴趣的:(keil5,嵌入式)