概述
本文描述STM32F103处理器在上电到进入main函数阶段的启动汇编代码分析。以startup_stm32f103x6.s该启动汇编文件进行讲解
栈地址和长度定义
startup_stm32f103x6.s启动文件的开始定义了栈空间的长度Stack_Size = 0x400,即1K的内存空间当做程序栈空间。
ALIGN=3, 栈的长度对齐到8字节(1
堆内存定义
堆内存长度定义为Heap_Size = 0x200,即512字节长度,并且8字节对齐
中断向量表
当CPU正常执行步骤被打断时(中断或异常), 处理器中断当前正在处理的指令,然后直接跳转到固定的一个内存地址去处理异常,我们把保存这类中断和异常处理的程序地址,叫做中断向量,CPU会把这些异常处理的地址集中存放在一起,叫做中断向量表。中断向量表在CPU处理器架构手册中有详细描述。但是对于Cortex-M系列的CPU来说,架构手册只规定了0~15和中断向量的地址和功能,剩余的没有做硬性要求,有每家处理器厂家自行实现
STM32F103的默认中断向量表(中断向量表可以被重定位到其他内存地址)如下所示:
从该终端向量表中,我们发现,表中的0位置值__initial_sp内存地址。为什么要在起始位置放置处理器的栈地址呢。这个可以从Cortex-m3/4处理器架构手册中获取,当处理器被复位时,处理器在执行指令时,会从0地址自动加载处加载两个字的数据,用来填充MSP栈和PC寄存器,因此,此处的汇编代码的放置方式,刚好可以将__initial_sp的值加载到MSP寄存器,将Reset_Handler的值,加载到PC, 然后处理从PC所指的位置,开始执行,即从Reset_Hander处开始执行
Reset_Handler
当处理器开始执行指令时,从前面的描述符中,自动跳转到汇编的Reset_Handler的标签处开始执行:
Reset_Handler的执行比较简单,先跳转到SystemInit处开始执行,在STM32F103中的函数位置为:
SystemInit函数的主要功能:
1、复位RCC,暂时使用内部的HSI 8M的时钟作为系统时钟
2、设置中断向量表的重定位位置;
执行完成后,然后跳转到main函数接口
总结
1、启动代码初始化系统时钟源,STM32F103的启动暂时移内部HSI作为时钟源,后续可以在main函数中可以修改时钟源和时钟频率;
2、设置中断向量表的位置;
3、从汇编代码,跳转到C入口main处执行;