提问人:NinjaGreg 提问时间:11/3/2023 最后编辑:trincotNinjaGreg 更新时间:11/11/2023 访问量:27
STM32F0 - 关于内存的问题(堆栈、堆)
STM32F0 - question about memory (Stack, heap)
问:
我对 STM32 微控制器(cortex M0)的堆栈和堆存储器有点困惑。
首先,它们是RAM的一部分,但它们是数据表中描述的RAM大小的一部分吗?
其次,如果我通过告诉链接器来减少堆内存(我不使用任何 malloc),我是否可以增加 RAM 内存以存储更多的全局和静态局部变量(存储在 RAM 内存的数据部分)?
最后,我看到堆栈内存在某个地方用于局部变量,但我在其他地方看到它用于静态数据。真相是什么?
额外问题:STM32数据表的内存映射图中显示的保留空间是什么?
你能给它带来光明吗?
先谢谢你,
答:
RAM是一种记忆,它是一种物理的东西。
堆栈和堆不是 RAM 的一部分;它们是抽象结构,类似于变量、数组、对象等。它们通过工具链(IDE,但最终由链接器)定位到 RAM 中。
通常,堆栈通常由硬件直接支持(有一个或多个堆栈指针寄存器和指令自动使用它),并且某些功能是必需的,例如从调用的函数返回。编译器还可以并且确实使用堆栈来存储局部变量和自动变量(寄存器溢出,即不适合寄存器并需要临时存储在某个地方的计算所需的值)。
静态变量与全局变量一起存储在其他位置,而不是堆栈中。
ARM Cortex-M 处理器中的堆栈向下增长,因此堆栈指针通常初始化到堆栈的顶部;然后,链接器从堆栈底部定位静态/全局变量。编译器和链接器通常不会计算运行时将使用多少堆栈(有时它们会,但仅作为高级分析,并且需要注意),因为在某些情况下很难甚至不可能计算它(例如,当使用函数指针时)。假设您知道堆栈的增长有多大(考虑到程序的复杂性和局部变量的使用)。估计堆栈使用情况的一种常见但不完美的方法是用已知模式(通常是可识别的“幻数”,如0xDEADBEEF)填充RAM,尝试执行程序的所有可能的执行模式,然后观察该模式被堆栈“破坏”了多少。
在某些工具链中,您指定为堆栈大小的值只是一个“暂定”值,链接器使用它来警告您全局 + 静态变量的总和加上此数字将超过可用的总 RAM。
堆完全是一个软件结构。如果您不使用它,请将其设置为 0,然后忘记它。是的,如果它不为零,它只是被添加到上面的总和中,因此将其设置为 0 将“释放”内存(因为该链接器不会抱怨或拒绝生成输出)。
额外的答案是,地址空间的保留部分是“无接触”,这就是您需要知道的全部内容(没有别的,确实,它是未分配的空间,访问通常会导致硬故障)。
我对 STM32 的堆栈和堆内存有点困惑 微控制者(皮层 M0)。
堆栈和堆只是与 C 实现相关的抽象术语。当然,硬件堆栈指针存在于这个 uC 中,但我建议不要关注实现细节(从答案来看,你是一个非常初学者)。
您需要记住的是,在对 uc 进行编程时不要使用动态分配(族函数)。malloc
首先,它们是RAM的一部分,但它们是所描述的RAM大小的一部分 在数据表中?
数据表未描述 C 编译器的实现,因此您不会在此处找到此信息。
通常,程序使用的内存映射在链接器脚本中进行定义。典型的实现将对象放在:
- 自动存储持续时间对象 - 在堆栈上
const
静态存储持续时间对象 - 在区段中.rodata
- 初始化的静态存储持续时间对象 - 在分段中
.data
- 未初始化静态存储持续时间对象 - 在分段中
.bss
- 代码 - 在段中
.text
上一个:内存泄漏和内存问题
评论