启动文件:0x08000000第一个字是栈顶,第二个字是复位入口 📅 2026/7/13 2:10:42 短文标题启动文件0x08000000第一个字是栈顶第二个字是复位入口你有没有想过一个问题单片机通电后执行的第一个指令在哪为什么程序从main开始跑不是main甚至不是Reset_Handler。上电后硬件自动做两件事先取栈顶地址再取复位向量。没有栈C语言无法运行——所以硬件第一步是设栈第二步才取第一条指令。上电后硬件自动完成的两件事从地址0x08000000读取栈顶地址__initial_sp→ 写入MSP主栈指针从地址0x08000004读取复位向量Reset_Handler地址→ 跳转执行这两个地址固定由启动文件定义不可更改。中断向量表的结构存放在Flash起始栈顶地址错误会怎样指向ROMFlash→ 压栈操作覆盖代码区 → 立即HardFault超出RAM范围 → 压栈到未映射地址 → BusFault → HardFault未对齐奇数地址→ 总线错误启动文件写错单片机连启动都启动不了。Reset_Handler做了什么Reset_Handler:LDR R0, SystemInitBLX R0 ; ① 配置时钟LDR R0, __mainBX R0 ; ② C库入口初始化data/bss调用mainSystemInit配置Flash等待周期、设置PLL、切换系统时钟。__main不是main初始化已初始化的全局变量.data段→ 清零未初始化的全局变量.bss段→ 最后调用main。VTOR重定位Bootloader→APP通过SCB-VTOR寄存器可将向量表重定位到RAM或Flash其他地址SCB-VTOR 0x08004000; // APP从偏移0x4000开始Bootloader跳转APP前必须重设VTOR否则APP的中断向量仍指向Bootloader区。这个故事的启示main不是CPU执行的第一个函数。栈顶地址和复位向量在main之前就已经被硬件加载。启动文件写错main永远跑不起来。写在最后调试“上电没反应”最先检查中断向量表查看0x08000000第一个字是不是RAM地址第二个字是不是Reset_Handler地址这两个地址对了单片机才有可能“活”过来。本文灵感源于于振南《新概念ARM32单片机》教程第5.5节“ARM32启动流程与中断控制器配置”。觉得有用点赞、转发让更多人看懂启动文件和向量表的底层逻辑。