程序的存储态与运行态
☞认识程序的运行与存储:结合硬件存储器来分析程序在运行和静止时的存储状态。相关文章链接
应用程序有静止状态(存储态)和运行状态(运行态)。静止状态就是程序在运行之前存储在非易失性存储器中的状态,比如stm32的内部Flash中,因此,系统掉电后程序也能正常保存。当我们把程序下载(烧写)到STM32F429的Flash中,如果不运行程序,那么程序就处于静止状态,关机重启后程序依然存在,不会丢失。在程序开始运行的时候,也就是程序处于运行态的时候,程序经常会修改一些暂存数据,为了提高速度,这些数据一般会加载到内存(RAM)中,而内存中的数据在掉电后会丢失。因此,程序在静止和运行两种状态下,它们在存储器中的位置是不一样的。
程序在存储态时,RO节(RO section)和RW节(RW section)都保存在ROM区,比如STM32的Flash中。当程序开始运行时,内核直接从ROM中读取代码,并在执行主体代码前先执行一段加载代码,把RW section中的数据从ROM拷贝到RAM内存中,并在RAM中加入ZI section,ZI节的数据都被初始化为0,加载完RAM区之后,正式开始执行主体程序。
在《MDK编译过程及ARM编译工具链》一文中说到,编译后的信息划分了几个域(可参考本人文章)。编译信息中的RW-data和ZI-data分别对应这里的RW section和ZI section,二者的区别在于是否需要掉电保存。因为在RAM中创建数据时,默认初值都是0,比如ZI节,但是有的数据要求初值非0,也就是被初始化为非0值的数据,这些数据需要通过ROM来记录初值(因为初值是程序运行前就确定好的,也就是说这个非0初值应该具有掉电保存的性质,所以这就需要把具有非0初值的数据保存在ROM/Flash中,而初值为0的数据掉电后重新在RAM内存中加载并不会影响初值,所以不需要掉电保存,也就不需要保存到ROM/Flash中记录初值,而是在运行态时直接在RAM中创建即可,即ZI section),而存放在ROM中的数据会在程序运行时复制到RAM。STM32的RO区不会加载到RAM中,内核直接从Flash读取指令。这里需要区分开的是,计算机会把RO区加载到内存,因为计算机有MMU单元,支持虚拟内存,可以运行大于物理内存的程序。
当程序下载到STM32的Flash(RAM)中的时候,它占用的空间为 code + RO-data + RW-data ,若这个总和大于STM32的Flash存储空间,将会出现错误。程序执行时占用的SRAM空间为 RW-data + ZI-data。
程序状态 | 编译后的数据域 |
运行态RO区 | code + RO-data |
运行态RW区 | RW-data + ZI-data |
存储态ROM区 | code + RO-data + RW-data |