MDK下单片机的编译过程和内存使用情况

启动文件:

 启动文件由汇编编写,是系统上电复位后第一个执行的程序。主要做了以下工作:

1、 初始化堆栈指针 SP=_initial_sp
2
、 初始化 PC 指针=Reset_Handler
3
、 初始化中断向量表
4、 配置系统时钟

5、 调用 C 库函数_main 初始化用户堆栈,从而最终调用 main 函数去到 C 的世界

MDK下的编译过程(其他编译器类似)

MDK下单片机的编译过程和内存使用情况_第1张图片

一般来说 Windows Linux 系统使用链接器直接生成可执行映像文件 elf后,内核根据该文件的信息加载后,就可以运行程序了,但在单片机平台上,需要把该文件的内容加载到芯片上,所以还需要对链接器生成的 elf 映像文件利用格式转换器fromelf 转换成“.bin”或“.hex”文件,交给下载器下载到芯片的 FLASH ROM 中。

程序的组成:

用户应用程序大致结构图如下所示:

MDK下单片机的编译过程和内存使用情况_第2张图片

程序在编译后,不同的数据占用不同的内存区域,程序在存储或运行的时候,不同的域会呈现不同的状态。

code:即代码域,它指的是编译器生成的机器指令,存储在ROM区;

RO-data(Read Only Data):只读数据域,表常量,存储在ROM区;

RW-data(Read Write data):可读可写域,表初始化值为“非0值”的变量,存储在ROM区,运行时复制到RAM区;

ZI-data(Zero Initialie data):初始化为0的可读可写域,表初始化为“0值”的变量,运行时生成于RAM区;

程序函数中使用的堆和栈的空间是来自ZI-data中分配的。

注意:C语言中,定义的静态变量(全局变量和局部静态变量,存储在静态存储区)初始化未赋初值时,其值为0;定义的自动变量(在栈上分配的内存)初始化未赋初值时,其值为随机值;

程序的存储和运行:

MDK下单片机的编译过程和内存使用情况_第3张图片

图中的左侧是应用程序的存储状态,右侧是运行状态,而上方是 RAM 存储器区域,下方是 ROM 存储器区域。 

静止态的程序被存储在非易失存储器中,如 STM32 的内部 FLASH,因而系统掉电后也能正常保存。但是当程序在运行状态的时候,程序常常需要修改一些暂存数据,由于运行速度的要求,这些数据往往存放在内存中(RAM),掉电后这些数据会丢失。 因此,程序在静止与运行的时候它在存储器中的表现是不一样的。 

在STM32中,程序在存储状态时, RO-dataRW-data都被保存在 ROM 区。当程序开始运行时,内核直接从 ROM 中读取代码,并且在执行主体代码前,会先执行一段加载代码,它把 RW数据从 ROM 复制到 RAM, 并且在 RAM 加入 ZI-dataZI数据都被初始化为0。加载完后 RAM 区准备完毕,正式开始执行主体程序。 

编译生成的 RW-data 的数据属于图中的 RW 节, ZI-data 的数据属于图中的 ZI 节。是否需要掉电保存,这就是把 RW-data ZI-data 区别开来的原因,因为在 RAM 创建数据的时候,默认值为 0,但如果有的数据要求初值非 0,那就需要使用 ROM 记录该初始值,运行时再复制到 RAM

当程序存储到 STM32 芯片的内部 FLASH (ROM ),它占用的空间是 CodeRO-data RW-data 的总和,所以如果这些内容比 STM32 芯片的 FLASH 空间大,程序就无法被正常保存了。当程序在执行的时候,需要占用内部 SRAM 空间(RAM ),占用的空间包括 RW-data ZI-data
MDK下单片机的编译过程和内存使用情况_第4张图片



        

你可能感兴趣的:(MDK下单片机的编译过程和内存使用情况)