Appearance
启动文件
- 初始化堆栈指针SP
assembly
Stack_Size EQU 0x00000400 ; 宏定义设置大小为1KB
AREA STACK, NOINIT, READWRITE, ALIGN=3 ;分配一个数据段, 名字叫STACK, 不初始化, 可读可写, 8字节对齐
Stack_Mem SPACE Stack_Size ; 分配内存空间
__initial_sp ; 紧挨着SPACE语句, 表示栈的结束, 由低向高生长
- 初始化堆
用于动态内存的分配(malloc的使用)
assembly
Heap_Size EQU 0x00000200
AREA HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem SPACE Heap_Size
__heap_limit
__heap_base 表示对的起始地址,__heap_limit 表示堆的结束地址。堆是由低向高生长 的,跟栈的生长方向相反。
assembly
PRESERVE8 文件堆栈8字节对齐
THUMB 兼容这个指令集
- 初始化中断向量表
内核响应中断之后中断函数执行, 内核使用中断向量表
assembly
AREA RESET, DATA, READONLY
EXPORT __Vectors
EXPORT __Vectors_End
EXPORT __Vectors_Size
__Vectors DCD __initial_sp ; Top of Stack
DCD Reset_Handler ; Reset Handler
DCD NMI_Handler ; NMI Handler
......
DCD DMA2_Channel4_5_IRQHandler ; DMA2 Channel4 & Channel5
__Vectors_End
__Vectors_Size EQU __Vectors_End - __Vectors ; 计算出向量表的大小
EXPORT表示可以被其他文件调用, 有全局性, 分配以字为单位的内存, 初始化内存
使用DCD初始化一个字节的位置, 这里记录的是中断函数的名字, 中断函数在中断向量表中有顺序
- 初始化PC指针为复位程序, 初始化系统时钟, 和挂载的SARM(可选), 跳转到C库函数
assembly
AREA |.text|, CODE, READONLY
设置这里为代码段开始执行, 第一个函数为复位函数
assembly
; Reset handler
Reset_Handler PROC ; 程序开始
EXPORT Reset_Handler [WEAK];弱定义, 可以由其他文件实现
IMPORT __main ; 相当于extern, C库函数
IMPORT SystemInit ; 系统时钟配置函数
LDR R0, =SystemInit ;执行函数
BLX R0 ;跳转, 执行完返回
LDR R0, =__main
BX R0 ;跳转, 执行完不返回
ENDP ; 程序结束
- 中断服务函数
assembly
; Dummy Exception Handlers (infinite loops which can be modified)
NMI_Handler PROC
EXPORT NMI_Handler [WEAK] ; 有全局属性, 弱定义
B .
ENDP
- 堆栈初始化, 由C库函数实现
assembly
IF :DEF:__MICROLIB ;宏定义, 在IDE里面定义
EXPORT __initial_sp
EXPORT __heap_base
EXPORT __heap_limit
ELSE
IMPORT __use_two_region_memory ; 用户自己实现
EXPORT __user_initial_stackheap
__user_initial_stackheap
LDR R0, = Heap_Mem
LDR R1, =(Stack_Mem + Stack_Size)
LDR R2, = (Heap_Mem + Heap_Size)
LDR R3, = Stack_Mem
BX LR
ALIGN
ENDIF
END