『7x24小时有问必答』
周末·轻松一刻

写在前面
Keil、IAR编译(Build)窗口打印出来的信息
Program Size: Code=2596 RO-data=268 RW-data=44 ZI-data=1028  

72 765 bytes of readonly   code memory  
  3 508 bytes of readonly   data memory  
20 202 bytes of readwrite data memory  

5 676 bytes of CODE   memory  
     926 bytes of CONST memory  
  1 148 bytes of DATA   memory

相信大家都看到过上面的信息,应该都知道它们大概的意思,但关于存储这一块的细节知识又有多少朋友去深入理解过呢?

要知道代码、常量、全局、局部变量存储在哪儿,就需要了解FLASH和RAM的一些特性,在工程中要具体分析其大小及对应存储地址,可以从map文件中分析。

简要说明其意思
为了照顾大部分人,简要说一下上面打印信息的意思。微主这里提醒一下大家网上也有一大堆相关资料,但网上好些资料说的有歧义,可能会误导大家,如:RW-data为已初始化的全局变量。加了static修饰的变量叫静态变量,和全局变量还是存在差别,但已初始化的静态变量也会归为RW-data中。

1.Keil编译窗口信息

Program Size:  Code=2596  RO-data=268  RW-data=44  ZI-data=1028
Code:指代码的大小;
Ro-data:指除了内联数据(inline data)之外的常量数据;
RW-data:指可读写(RW)、已初始化的变量数据;
ZI-data:指未初始化(ZI)的变量数据;

Code、Ro-data:位于FLASH中;
RW-data、ZI-data:位于RAM中;
提醒:RW-data已初始化的数据会存储在Flash中,上电会从FLASH搬移至RAM中。

关系如下:
RO   Size  = Code + RO Data
RW   Size  = RW Data + ZI Data
ROM Size = Code + RO Data + RW Data

2.IAR编译窗口信息

IAR存在两种情况,但意思都差不多,只是显示不一样:
编译工程(点击Make),会出现如下信息:

72 765 bytes of  readonly   code  memory  
  3 508 bytes of  readonly   data  memory  
20 202 bytes of  readwrite data  memory  

编译单个文件(点击Compile,会出现下面信息(若没有DATA就没有那一行):
5 676 bytes of  CODE    memory  
     926 bytes of  CONST  memory  
  1 148 bytes of  DATA    memory

readonly   code:代码大小(类似于CODE);
readonly   data:常量数据(类似于CONST
readwrite data:可读写变量数据(类似于DATA);

说明:
IAR中的Data相当于Keil中RW Data + ZI Data

内存(RAM)分配
本节扩展一下RAM的一些知识,有助于大家对程序运行时RAM的情况。
内存分为5类:

1、栈区(stack): 由编译器自动分配和释放 ,存放函数的参数值,局部变量的值等。

2、堆区(heap) : 一般由程序员(使用malloc)分配和(使用free)释放, 若程序员不释放,则一直被占用。一般来说,单片机类的程序一般没有使用堆。

3、全局区(静态区)(static):全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。

4、文字常量区(const) :常量字符串就是放在这里的。  

5、程序代码区 (code): 存放函数体的二进制代码。

经典例子
int a = 0; 全局初始化区

char *p1; 全局未初始化区

main(void)
{

   int b;// 栈

   char s[] = "abc"; //栈

   char *p2; //栈

   char *p3 = "123456"; 123456\0";//在常量区,p3在栈上。

   static int c =0; //全局(静态)初始化区

   p1 = (char *)malloc(10);
   p2 = (char *)malloc(20);
   //分配得来得10和20字节的区域就在堆区。

   strcpy(p1, "123456"); //123456\0放在常量区,编译器可能会将它与p3所指向的"123456"优化成一个地方。
}

最后
微信搜索“EmbeddDeveloper” 或者扫描下面二维码、关注,查看更多精彩内容。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

上一主题上一主题         下一主题下一主题
QQ手机版小黑屋粤ICP备17165530号

关于我们·投诉举报· 用户帮助· 联系我们 · 本站服务 · 版权声明· 隐私政策 · 投搞指南

法律保护:PLC技术网,plcjs.com,plcjs.net等字样
Copyright 2010-2030. All rights reserved. 


微信公众号二维码 抖音二维码 百家号二维码 今日头条二维码哔哩哔哩二维码