不同的开发环境(IAR、KEIL、GCC编译器),startup.s的内容多少有些差别,但是功能基本如下:
文件功能:
;* This module performs:
;* - Set the initial SP
;* - Configure the clock system
;* - Set the initial PC == __iar_program_start,
;* - Set the vector table entries with the exceptions ISR address.
;* After Reset the Cortex-M3 processor is in Thread mode, priority is Privileged, and the Stack is set to Main.
The vector table is normally located at address 0.
在函数__iar_program_start() 内会调用 main() 函数
向量表
在 startup.s 内,定义了一个向量表,不同于GCC编译器由链接脚本决定向量表存储在ROM(flash)的哪个地址,IAR是 .icf 文件内决定存储地址,默认从地址0开始(对于STM32,就是 flash 的起始地址 0x08000000)存每个向量,向量指向的位置就是对应的中断服务函数
所以 0x20000D84 就是主堆栈指针的初始值,0x08059545-1就是复位向量,指向中断服务函数 Reset_Handler
startup.s 文件内容
以下是 IAR 版本的 startup.s
MODULE ?cstartup ;; Forward declaration of sections. SECTION CSTACK:DATA:NOROOT(3) SECTION .intvec:CODE:NOROOT(2) EXTERN __iar_program_start EXTERN SystemInit PUBLIC __vector_table DATA __vector_table DCD sfe(CSTACK) DCD Reset_Handler ; Reset Handler DCD NMI_Handler ; NMI Handler DCD HardFault_Handler ; Hard Fault Handler ...... THUMB PUBWEAK Reset_Handler SECTION .text:CODE:REORDER(2) Reset_Handler LDR R0, =SystemInit BLX R0 LDR R0, =__iar_program_start BX R0 PUBWEAK NMI_Handler SECTION .text:CODE:REORDER(1) NMI_Handler B NMI_Handler PUBWEAK HardFault_Handler SECTION .text:CODE:REORDER(1) HardFault_Handler B HardFault_Handler ......
除了 Reset_Handler 中断服务函数, 其他中断服务函数都是死循环,B 是跳转指令(即函数调用)。BLX 也是跳转指令。
DCD sfe(CSTACK)
DCD Reset_Handler ; Reset Handler
DCD NMI_Handler ; NMI Handler
DCD HardFault_Handler ; Hard Fault Handler
DCD:数据定义( Data Definition )伪指令
一般用于为特定的数据分配存储单元,同时可完成已分配存储单元的初始化。
语法格式:
标号 DCD(或 DCDU) 表达式
DCD(或 DCDU)伪指令用于分配一片连续的字存储单元并用指定的表达式初始化。其中表达式可以为程序标号或数字表达式。 DCD 也可用 “ &” 代替。
用 DCD 分配的字存储单元是字对齐的,而用 DCDU 分配的字存储单元并不严格字对齐。
结合前面的截图,上面几行分析如下:
为 CSTACK 分配存储地址 0x08000000,地址上的内容为 CSTACK 的值是 0x20000D84
为 Reset_Handler 分配存储地址 0x08000004,地址上的内容为中断服务函数指针(0x08059545),指向中断服务函数 Reset_Handler
为 NMI_Handler 分配存储地址 0x08000008,地址上的内容为中断服务函数指针(0x08059591),指向中断服务函数 NMI_Handler
函数 Reset_Handler 内没有对 SP 进行初始化,存疑。