Skip to content

启动文件

  • 初始化堆栈指针SP
assembly
Stack_Size      EQU     0x00000400	; 宏定义设置大小为1KB
			   AREA    STACK, NOINIT, READWRITE, ALIGN=3 ;分配一个数据段, 名字叫STACK, 不初始化, 可读可写, 8字节对齐
Stack_Mem       SPACE   Stack_Size ; 分配内存空间
__initial_sp ; 紧挨着SPACE语句, 表示栈的结束, 由低向高生长

image-20230626174327612

  • 初始化堆

用于动态内存的分配(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