本文主要记录华大低功耗单片机 HC32L110 的 汇编启动过程,包括startup_hc32l110启动文件详细注释
有需要可点赞+收藏,并私信我获取全文。版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_39217004/article/details/137968603
0. 常用汇编指令
1.启动文件的作用
启动文件为 startup_hc32l110.s
,启动文件中完成了:
-
堆和栈的初始化
- 包括堆栈的大小,主栈指针 MSP 的初始值
-
向量表定义
- 定义各MSP的初值以及中断服务函数的入口地址
-
中断服务程序
-
设置系统时钟频率 (在复位中断服务程序
Reset_handler
中调用系统时钟频率初始化程序) -
中断寄存器初始化
-
进入C的
main
函数
2.堆栈定义
2.1栈
栈的作用是用于局部变量,函数调用,函数形参等的开销,栈的大小不能超过内部SRAM 的大小。当程序较大时,需要修改栈的大小,不然可能会出现的HardFault的错误。
EQU
是伪指令,相当于C 中的define
。ARER
伪指令表示下面将开始定义一个代码段或者数据段ARER
后面的关键字表示这个段的属性。段名为STACK
,可以任意命名;NOINIT
表示不初始化;READWRITE
表示可读可写,ALIGN=3
,表示按照 8 字节对齐。SPACE
用于分配大小等于Stack_Size
连续内存空间,单位为字节。__initial_sp
表示栈顶地址。栈是由高向低生长的
; Stack Configuration
; Stack Size (in Bytes) <0x0-0xFFFFFFFF:8>
Stack_Size EQU 0x00000100
AREA STACK, NOINIT, READWRITE, ALIGN=3
Stack_Mem SPACE Stack_Size
__initial_sp
; 定义栈大小为 0x100 256字节
; 定义一个数据段,8字节对齐,名称为 STACK ,数据段不初始化,仅仅保留内存单元,可读可写
; 分配一段大小为 Stack_Size 的连续内存空间,并初始化为0
; 表示栈顶指针地址
2.2堆
堆主要用来动态内存的分配,像 malloc()
函数申请的内存就在堆中。
; Heap Configuration
; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8>
Heap_Size EQU 0x00000400
AREA HEAP, NOINIT, READWRITE, ALIGN=3
__heap_base
Heap_Mem SPACE Heap_Size
__heap_limit
; 定义堆大小为 0x400 1024字节
; 定义一个数据段,8字节对齐,名称为 HEAP ,数据段不初始化,仅仅保留内存单元,可读可写
; __heap_base放置在SPACE之前表示堆的起始地址。
; 分配一段大小为 Heap_Size 的连续内存空间,并初始化为0
; __heap_limit放置在SPACE之后表示堆的结束地址。
PRESERVE8 ; 指示编译器8字节对齐
THUMB ; 指示编译器以后的指令为THUMB指令
3.向量表
向量表本质上是一个U32
的数组,每个元素代表一种异常,中断向量表 存放的实际上是中断服务程序的入口地址。当异常(也即是中断事件)发生时,CPU 的中断系统会将相应的入口地址赋值给 PC 程序计数器,之后就开始执行中断服务程序。 在地址 0 (即 FLASH 地址 0)处必须包含一张向量表,用于初始时的异常分配。
EXPORT
将标识符申明为可被外部引用DCD
表示分配 1 个 4 字节的空间
; Vector Table Mapped to Address 0 at Reset
;中断向量表定义
AREA RESET, DATA, READONLY ;定义只读数据段,名字是REST
;EXPORT:在程序中声明一个全局的标号__Vectors,
;该标号可在其他的文件中引用
EXPORT __Vectors ;表示向量表的起始地址
EXPORT __Vectors_End ;表示向量表的结束地址
EXPORT __Vectors_Size ;表示向量表的大小
; 中断向量表
__Vectors DCD __initial_sp ; Top of Stack
DCD Reset_Handler ; Reset
DCD NMI_Handler ; NMI
DCD HardFault_Handler ; Hard Fault
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD SVC_Handler ; SVCall
DCD 0 ; Reserved
DCD 0 ; Reserved
DCD PendSV_Handler ; PendSV
DCD SysTick_Handler ; SysTick
………………省略一部分