赞
踩
当我们用keil编译程序后,会出现该工程的一些信息,如下图,其中我们可以看到编译后的程序大小(Program Size):Code:=xxx Ro-data=xxx RW-data=xxx ZI-data=xxx。
- 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 区域清零。
相应的存储位置
扩展:
堆区:由程序员自己在该块中申请的内存,如new或者malloc,如果用完后不及时释放,会导致内存泄漏。
栈区:定义的局部变量和函数的形参,遵循先入后出的原则,编译器自动分配和释放。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。