打印
[其他]

STM32的启动堆栈初始化

[复制链接]
664|2
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
grfqq325|  楼主 | 2024-3-31 17:45 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

有几个问题,众多博文中抄来抄去,内容一样,却没有解释清楚

  • 上电初始化堆栈,在进入_main后又说初始化堆栈,有什么不同
  • 堆栈的地址是怎么得出来的

关于这两个问题,先借用一下要标准的启动流程
一般而言,系统上电后第一个执行的是由汇编所编写的启动文件,其主要工作为一下五部分:


  (1)、初始化堆栈指针SP=_initial_sp


  (2)、初始化PC指针,令其=Reset_Handler


  (3)、初始化中断向量表


  (4)、配置系统时钟

  

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



使用特权

评论回复
沙发
grfqq325|  楼主 | 2024-3-31 17:45 | 只看该作者
STM32的中断向量表规定每一行必须是SP地址,第二行是复位中断入口地址,上电后,CPU首先就会读这两个值,分别存为SP和PC寄存器。上述流程第一行_initial_sp就是SP地址。
那么_initial_sp的值是怎么得到的呢?这是根据STM32的SRAM分配规则计算的,SRAM从规定的地址开始分别存付已初始全局和静态变量、未初化全局和静态变量、堆、栈,其中变量的长度是你写程序后就固定了,堆和栈的长度则是在启动代码中定义的,那么把它们加起来就会得于_initial_sp的值,编译后,_initial_sp就被替代为上述计算好的地址。

第二个问题,上电已经初始了SP,为什么后边又初始化堆栈?因为上电只是将_initial_sp值存入了SP寄存器,这只是一个栈顶指针,但堆的大小和栈的大小并没有初始化,所以在_main中要把在启动文件中定义好的值传给C库进行堆栈大小的初始化。无论是带系统的,还是裸机程序,都要管理堆栈的大小,这就是会产生堆栈溢出的原因。

另外,对于有MMU的系统,在进入保护模式后,地址切换到虚拟地址,还要对SP重新赋值,因为上电时的地址是实模式下真实的物理地址,而MMU是虚拟线性地址

使用特权

评论回复
板凳
woai32lala| | 2024-4-8 16:07 | 只看该作者
不错,学习了

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

38

主题

356

帖子

3

粉丝