📄 startup.s79
字号:
;-------------------------------------------------------------------------------
;文件中标号命名规则:
; ?xxx 仅能由汇编语言访问的外部标号。
; __xxx 可由C 语言访问或定义的外部标号。
; xxx 单个模块中的局部标号(注意,本文件包含多个模块)。
; main 用户程序起始点。
;
;-------------------------------------------------------------------------------
; 适用于整个文件的宏和定义
;-------------------------------------------------------------------------------
; 模式,对应于CPSR寄存器的0-5位
MODE_BITS DEFINE 0x1F ; 用于CPSR模式位的位屏蔽
USR_MODE DEFINE 0x10 ; 用户模式
FIQ_MODE DEFINE 0x11 ; 快中断请求模式
IRQ_MODE DEFINE 0x12 ; 中断请求模式
SVC_MODE DEFINE 0x13 ; 管理模式
ABT_MODE DEFINE 0x17 ; 中止模式
UND_MODE DEFINE 0x1B ; 为定义指令模式
SYS_MODE DEFINE 0x1F ; 系统模式
;
;-------------------------------------------------------------------------------
; ?RESET
; 复位向量。通常INTVEC段被连接到0地址,为程序调试方便,也可以将其放在其它地址。
;-------------------------------------------------------------------------------
MODULE ?RESET
COMMON INTVEC:CODE:NOROOT(2)
PUBLIC __program_start
EXTERN ?cstartup
EXTERN undef_handler, swi_handler, prefetch_handler
EXTERN data_handler, irq_handler, fiq_handler
CODE32 ; Always ARM mode after reset
org 0x00
__program_start
ldr pc,[pc,#24] ; 绝对跳转可以到达4 GByte
; ldr b,?cstartup ; 相对跳转允许重映射(remap),限于32 MByte
; 可以去掉以下指令前面的注释分号来允许异常向量,
; 也可以在C语言中采用预编译命令#pragma vector。
org 0x04
; ldr pc,[pc,#24] ; 跳转到undef_handler
org 0x08
; ldr pc,[pc,#24] ; 跳转到swi_handler
org 0x0c
; ldr pc,[pc,#24] ; 跳转到prefetch_handler
org 0x10
; ldr pc,[pc,#24] ; 跳转到data_handler
org 0x18
; ldr pc,[pc,#24] ; 跳转到irq_handler
org 0x1c
; ldr pc,[pc,#24] ; 跳转到fiq_handler
; 用于ldr pc指令的常数表入口定位于0x20,
; 异常向量可以用C语言的预编译命令#pragma vector指定,也可以在以下DC32指令后面填入向
; 量地址。向量地址为:ARM向量号+0x20。
org 0x20
dc32 ?cstartup
org 0x24
; dc32 undef_handler
org 0x28
; dc32 swi_handler
org 0x2c
; dc32 prefetch_handler
org 0x30
; dc32 data_handler
org 0x38
; dc32 irq_handler
org 0x3c
; dc32 fiq_handler
LTORG
; ENDMOD __program_start
ENDMOD
;
;---------------------------------------------------------------
; ?CSTARTUP
;---------------------------------------------------------------
MODULE ?CSTARTUP
RSEG IRQ_STACK:DATA(2)
RSEG ABT_STACK:DATA:NOROOT(2)
RSEG UND_STACK:DATA:NOROOT(2)
RSEG FIR_STACK:DATA:NOROOT(2)
RSEG SVC_STACK:DATA:NOROOT(2)
RSEG CSTACK:DATA(2)
RSEG ICODE:CODE:NOROOT(2)
PUBLIC ?cstartup
EXTERN ?main
; 从这里开始执行。
; 复位后为ARM管理模式,禁止中断
CODE32
?cstartup
; 需要时在这里加入建立堆栈指针之前的初始化指令
; 初始化堆栈指针。
; 以下方式可用于任何异常堆栈:FIQ, IRQ, SVC, ABT, UND, SYS。
; 用户模式使用与系统模式相同的堆栈。
; 堆栈段必须在连接器命令文件中定义,并已经在上面声明。
mrs r0,cpsr ; 原 PSR 值
bic r0,r0,#MODE_BITS ; 清0模式位
orr r0,r0,#IRQ_MODE ; 置1 IRQ 模式位
msr cpsr_c,r0 ; 改变模式
ldr sp,=SFE(IRQ_STACK) & 0xFFFFFFF8 ; IRQ_STACK结束
bic r0,r0,#MODE_BITS ; 清0模式位
orr r0,r0,#ABT_MODE ; 置1 Abort模式位
msr cpsr_c,r0 ; 改变模式
ldr sp,=SFE(ABT_STACK) & 0xFFFFFFF8 ; ABT_STACK结束
bic r0,r0,#MODE_BITS ; 清0模式位
orr r0,r0,#SVC_MODE ; 置1 Supervisor模式位
msr cpsr_c,r0 ; 改变模式
ldr sp,=SFE(SVC_STACK) & 0xFFFFFFF8 ; SVC_STACK结束
bic r0,r0,#MODE_BITS ; 清0模式位
orr r0,r0,#UND_MODE ; 置1 Undefined 模式位
msr cpsr_c,r0 ; 改变模式
ldr sp,=SFE(UND_STACK) & 0xFFFFFFF8 ; UND_STACK结束
bic r0,r0,#MODE_BITS ; 清0模式位
orr r0,r0,#FIQ_MODE ; 置1 FIQ 模式位
msr cpsr_c,r0 ; 改变模式
ldr sp,=SFE(FIR_STACK) & 0xFFFFFFF8 ; FIR_STACK结束
bic r0,r0,#MODE_BITS ; 清0模式位
orr r0,r0,#SYS_MODE ; 置1 System模式位
msr cpsr_c,r0 ; 改变模式
ldr sp,=SFE(CSTACK) & 0xFFFFFFF8 ; CSTACK结束
#ifdef __ARMVFP__
; 允许 VFP 协处理器。
mov r0, #0x40000000 ; 置1 VFP 的EN位
fmxr fpexc, r0 ; FPEXC,清除其它
; 将缓冲区清0以禁止下溢出。为完全满足IEEE 754标准,应删除该指令并安装合适的异常句柄。
mov r0, #0x01000000 ; 置1 VFP 的FZ位
fmxr fpscr, r0 ; FPSCR, 清除其它
#endif
; 在这里添加更多初始化指令。
ldr r0,=?main
bx r0
LTORG
ENDMOD
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -