嵌入式软件面试之程序在存储器中的分布

Hi, 大家好,今天阿目分享的是一个嵌入式软件面试的常见问题,内存分布或者说程序在内存中的布局,我们写的程序是按照怎么的准则放在内存中的?

一般有操作系统的嵌入式设备,都会有一个Bootloader, 它负责在上电后初始化外设和系统配置,并把操作系统的代码从硬盘搬运到内存上,然后跳到操作系统的入口函数开始执行。因此,这种设计架构就会把程序放在内存,那么是遵循怎样的原则呢?相信大家一定看到过这样的内存分布图:

其中常见的各个段的解析:

  1. 栈区(stack):

    用来存储函数调用时的临时信息的结构,存放为运行时函数分配的局部变量、函数参数、返回数据、返回地址等。

  2. 堆区(heap):

    一般由程序员分配、和释放,用来存储程序运行时分配的变量。

  3. 全局区(静态区static):

    存放全局变量、静态数据。程序结束后由系统释放。全局区分为已初始化全局区(data)和未初始化全局区(bss)。

  4. 代码区(.text):

    存放函数体(类成员函数、静态函数和全局函数)的二进制代码。

  5. 内核区

    用于有操作系统的设计,用于存放操作系统代码,并会受到访问保护

需要注意的是上图中的分区,并不是固定的,也就是说每个软件设计者都可以灵活的安排这些区域的地址范围。这些都是在编译的链接脚本中可以指定地址范围的。

下面阿目还是以STM32的keil工程为例,为大家介绍,STM32工程配置的内存分布,该工程是基于STM32F103芯片,且不带操作系统。所以分区中就不需要考虑操作系统的部分了,那么具体有哪些分区呢?我们可以通过编译的map文件查看:

上图就是map文件中的关于编译后的程序的地址分配信息,可以看到从1331行开始列出了地址信息,它属于哪个段呢?可以看关键字"Type"一列写的"Data"且属性列写的RO(read only的意思),所以0x0800_0000地址处放的就是一个只读变量,属于.data段;1332行"Type"一列写的"Code",就是代码段(.text)的内容,它的地址是0x0800_00ec,其他行以此类推。

这里需要注意的是,STM32单片机运行时,代码段(.text)并不是在内存中的(启动模式设置为从Flash启动的情况),不像上面说的有些带有操作系统的设计方式,直接把所有代码放在内存中(因为一般这种设备内存会比较大),但是单片机芯片一般内存都比较小且执行效率要求没有那么高,所以为了节省成本会把程序放在Flash中,在执行过程中从Flash中取指令执行,所以这里的地址是从0x0800_0000开始的。

如果Flash的大小是10KB,那么这里代码段的地址空间可以理解为0x0800_0000~0x0800_2800, 一般不会把Flash空间全部当作用户的代码存放空间,因为芯片厂商一般会保存自家芯片的一些参数到Flash中,所以会占用一些空间。

上面就是需要放在RAM中的.data段了,上期也有讲到,.data段在没有启动时是放在Flash中保存的,在启动后,将他们搬运到ram中,所以这里map文件列出了两个地址一个是 Exec Addr(执行地址), 一个是Load Addr(加载地址), 执行地址就是RAM的地址,加载地址就是这个变量存放在Flash中的地址。

1426行的一个数据它在RAM中的地址就是0x2000_0000,RW表示可读可写;1437行写出了STACK(栈空间)的地址,0x2000_0058,大小是0x400,也就是1KB,即stack空间的地址范围为:0x2000_0058 ~0x2000_0457。

这里的.data段的空间其实并没有明确规定,它只是在编译时由编译器安排的,程序中有几个全局变量或者静态变量就安排几个地址,并没有指定这个空间的结束地址。

ending~~

相关推荐
danaaaa7 分钟前
算法力扣刷题记录 二十八【225. 用队列实现栈】
数据结构·c++·算法·leetcode·职场和发展
未来可期,静待花开~13 分钟前
C++基础(八):类和对象 (下)
开发语言·jvm·c++
几个几个n36 分钟前
51单片机-第一节-LED和独立按键
单片机·嵌入式硬件·51单片机
Caramel_biscuit39 分钟前
C++专业面试真题(1)学习
c++·学习·面试
卫卫周大胖;41 分钟前
【C++】多态(详解)
开发语言·c++
Java资深爱好者5 小时前
如何在std::map中查找元素
开发语言·c++
极客小张6 小时前
ESP32 步进电机精准控制:打造高精度 DIY 写字机器人,实现流畅书写体验
单片机·嵌入式硬件·mcu·物联网·机器人·硬件工程
杰哥在此7 小时前
Java面试题:讨论持续集成/持续部署的重要性,并描述如何在项目中实施CI/CD流程
java·开发语言·python·面试·编程
安步当歌8 小时前
【FFmpeg】av_write_trailer函数
c语言·c++·ffmpeg·视频编解码·video-codec
青青草原上的梦想家9 小时前
Cocos Creator 游戏性能优化指南
游戏·面试·性能优化·typescript