目录
概述
本文主要讲述编译的代码文件的程序结构,以及在程序运行的过程中,各个代码段或者数据区在程序中加载的过程。还总结程序分段的内在含义。
1 RT-Thread Studio创建STM32H7工程
1.1 下载RT-Thread Studio
step - 1: 安装RT-Thread Studio
打开如下链接,下载RT-Thread Studio
https://www.rt-thread.org/document/site/#/development-tools/rtthread-studio/um/studio-user-begin
下载页面如下:
step - 2: 创建工程
安装完成后,使用RT-Thread Studio创建STM32H7工程
step - 3: 创建完成工程后,打开工程
1.2 编译STM32H7工程
使用RT-Thread Studio编译STM32H7工程,编译成功后可以看见如下信息:
编译log如下:
arm-none-eabi-size --format=berkeley "rtthread.elf"
text data bss dec hex filename
68960 1808 4552 75320 12638 rtthread.elf
使用如下列表,简单介绍以上数据的意义:
内容 | 名称 | 数据 |
---|---|---|
代码区 | text | 68960 |
静态数据/全局初始化数据区 | data | 1808 |
未初始化数据区 | bss | 4552 |
十进制数据总和 | dec | 75320 |
十六进制数据总和 | hex | 12638 |
文件名称 | filename | rtthread.elf |
2 编译文件结构
2.1 代码区( text segment)
该区域主要存放CPU执行的机器指令,通过代码区是可以共享的(即另外的执行程序可以调用它),使其可共享的目的是对于频繁执行的程序,只需要在内存中有一份代码即可。代码区通常是只读的,使其只读的原因是防止意外的修改它的指令。另外,代码去还规划了局部变量的相关信息。
代码区的指令包括操作码和操作对象(或对象地址引用)。如果是立即数,就直接包含在代码中。如果是局部数据,将运行在栈区分配空间,然后在引用该数据的地址。如果是BSS区和数据区,在代码中同样将应用该数据的地址。
2.2 静态数据/全局初始化数据区
该区包含了在程序中明确被初始化的全局变量,已经初始化的静态变量和数据常量,如下两种情况将存放在数据区:
1) 定义一个全局变量:
int maxcont = 99;
这个变量将放在初始化数据区
2)任意位置的静态变量,也将存储到初始化数据区,例如:
static int val = 100;
2.3 未初始化数据区
该区域也被称为BSS区,存入的是全局为初始化的变量和为初始化的静态变量,BSS区的数据在程序开始执行之前被内核初始化为0或者空指针( NULL)。
3 MCU中代码运行时的数据结构
在运行非linux操作系统的通用型STM32芯片中,只有一个进程,就是上电后运行的总体程序代码。它包含:申请的内存空间,代码(代码段、数据段、BSS)、堆、栈。
1)代码区
加载是可执行文件的代码段,其加载到内存中的位置由加载器完成。加载代码由MCU内部的bootloader完成,这部分bootloader在芯片生产后已经固化在其内部了。
2)全局初始化数据区/静态数据区
MCU加载可执行文件的数据段时,这部分数据可位于代码段之后,也可以单独分开。程序在运行之初就为该数据段申请了空间,在程序退出时才释放。因此,存储于数据段(全局初始化、静态数据初始化)的数据生存周期为整个程序的运行过程。
3)未初始化数据区(BSS)
加载可以执行型文件的BSS段,其位置可以分开,也可以紧靠近数据段,程序运行之初,就为该部分申请了空间。程序退出时才释放。因此,存储于该部分的数据(全局未初始化、金泰未初始化数据)的生存周期为整个程序的运行过程。
4)栈区(stack)
由编译器自动分配释放,存放函数的参数值、返回值、局部变量等。在程序运行的过程中实时的加载和释放。因此,局部变量的生存周期为申请到释放该段栈空间的过程。
5)堆区(heap)
用于动态内存分配,堆在内存中位于BSS区和栈区之间。一般由程序员分配和释放。对于有内存管理的OS来说,OS会定期回收没有被释放且没有被使用的内存。
4 程序分段的意义
1)代码段和数据段分开,运行时便于分开加载。在哈佛结构体系的MCU将取得更好的流水线处理效率
2)代码是依次执行的,由处理器的PC指针依次读入,而且代码也可以被多个程序共享。数据在整个程序运行的过程中也将多次被使用,且数据是可变的,如果两者混在一起,造成内存的极大浪费。
3)临时数据及需要再次使用的代码在运行时放入栈中,生命周期短,便于提高资源的利用率
4)堆区可以有程序员分配和释放,以便用户自由分配,提高程序的灵活性