Keil 编译内存信息:Program size: Code, RO-data , RW-data, ZI-data 学习(转载)

转载出处:海月汐辰

一、用keil编译程序后会打印对应的内存分配信息,例如如Program Size: Code=97782 RO-data=9578 RW-data=2992 ZI-data=87696  ,如下图所示:


二、这里我们就解释一下Program size: Code, RO-data , RW-data, ZI-data具体代表什么?

      1、Code 是代码占用的空间。

      2、RO-data是 Read Only 只读常量的大小,如const型。

     3、RW-data是(Read Write) RW是可读可写变量,就是初始化时候就已经赋值了的,RW + ZI就是你的程序总共使用的RAM字节数。

     4、ZI-data是(Zero Initialize) 没有初始化的可读写变量的大小,就是程序中用到的变量并且被系统初始化为0的变量的字节数,keil编译器默认是把你没有初始化的变量都赋值一个0,这些变量在程序运行时是保存在RAM中的。

三、Total ROM Size (Code + RO Data + RW Data)这样所写的程序占用的ROM的字节总数,也就是说程序所下载到ROM flash 中的大小。为什么Rom中还要存RW,因为掉电后RAM中所有数据都丢失了,每次上电RAM中的数据是被重新赋值的,每次这些固定的值就是存储在Rom中的,为什么不包含ZI段呢,是因为ZI数据都是0,没必要包含,只要程序运行之前将ZI数据所在的区域一律清零即可。包含进去反而浪费存储空间。

四、MCU执行过程是先将RW从ROM中搬到RAM中,因为RW是变量,变量不能存在ROM中。然后将ZI所在的RAM区域全部清零,因为ZI区域并不在Image中,所以需要程序根据编译器给出的ZI地址及大小来将相应得RAM区域清零。ZI中也是变量,同理:变量不能存在ROM中。ROM中的指令完成了这两项工作后C程序才能正常访问变量。否则只能运行不含变量的代码。

五、用keil编译器实际测试学习。

1、目前我的这个工程编译后内存分配大小如下:


2、现在我在程序里面加入一个int   Program_Size[10]= {10};如下图所示,RW-data增加了40个字节,因为这个数组已经初始化了,代码放到RW-data。



3、如果是加入一个int   Program_Size[10];数组不进行已经初始化,如下图所示,ZI-data区增加40个字节。


3、如果是加入一个int   Program_Size[10]={0};数组进行已经初始化都是0,如下图所示,ZI-data区增加40个字节,说明初始化都是0和进行已经初始化,都是放ZI-data区。



<think>好的,用户想了解程序大小的组成,包括代码段、只读数据段、读写数据段和零初始化数据段的具体数值,特别是在嵌入式系统的内存布局中。首先,我需要回忆这些段的具体定义和作用。 代码段(Code Segment)通常存储可执行指令,也就是程序的机器代码。这部分是只读的,防止程序被意外修改。只读数据段(RO-Data)包含常量,比如字符串常量和全局常量,这些数据在程序运行期间不会改变。读写数据段(RW-Data)存储已初始化的全局变量和静态变量,这些变量在程序启动时被加载到内存,并且可以被修改。零初始化数据段(ZI-Data)则是未初始化的全局变量和静态变量,它们在程序启动时会被系统初始化为零,实际不占用程序镜像的空间,但运行时需要分配内存。 接下来,我需要考虑嵌入式系统的内存布局。通常,程序镜像包括CodeRO-DataRW-Data,而ZI-Data在运行时由启动代码初始化。内存分为Flash(存储CodeRO-Data)和RAM(存储RW-DataZI-Data)。例如,在Keil MDK中,编译后的输出会显示这些段的大小,帮助开发者优化内存使用。 用户可能想知道如何获取这些数值,可能需要提到编译工具链提供的功能,比如ARM的map文件或者GCC的size命令。此外,优化这些段的策略也很重要,比如使用const关键字减少RW-Data,或者合并字符串常量节省RO-Data空间。 还需要考虑用户可能的后续问题,比如如何减少各段的大小,或者具体的工具使用方法。要确保回答结构清晰,分点说明每个段,并给出示例数值和内存布局图,帮助用户直观理解。最后,生成的相关问题应覆盖内存优化、工具使用、具体案例和ZI-Data的处理方法,这样用户可以有进一步的学习方向。</think>在嵌入式系统中,程序内存布局通常由以下几个关键段组成,其大小组成可通过编译工具链(如ARM GCC、Keil MDK等)的输出报告获取: 1. **代码段(Code)** - 存储可执行机器指令 - 包含函数体、跳转指令等 - 示例数值:$$ \text{Code Size} = 32\text{KB} $$ 2. **只读数据段(RO-Data)** - 存储常量数据(如字符串常量、const全局变量) - 示例数值:$$ \text{RO-Data} = 8\text{KB} $$[^1] 3. **读写数据段(RW-Data)** - 存储已初始化的全局变量和静态变量 - 需要同时占用Flash(存储初始值)和RAM(运行时存储) - 示例数值:$$ \text{RW-Data} = 4\text{KB} $$ 4. **零初始化数据段(ZI-Data)** - 存储未初始化的全局变量和静态变量 - 仅占用RAM空间,在启动时由启动代码初始化为0 - 示例数值:$$ \text{ZI-Data} = 12\text{KB} $$ **内存布局示意图**: ``` +---------------------+ | Flash | +---------------------+ | Code | <- 执行时加载到指令缓存 | RO-Data | <- 只读数据区 | RW-Data初始值 | <- 启动时复制到RAM +---------------------+ | RAM | +---------------------+ | RW-Data运行时副本 | <- 可修改的全局变量 | ZI-Data | <- 启动时清零的变量 | 堆(Heap) | | 栈(Stack) | +---------------------+ ``` **优化策略**: - 使用`const`修饰符将数据放入RO-Data- 避免全局变量初始化冗余(如`int a = 0;`应简化为`int a;`) - 通过编译选项控制内存对齐方式(如`-falign-functions=4`)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值