📄 start.s
字号:
/*
* Symbolic register names for 32 bit ABI
*/
#define zero $0 /* wired zero */
#define AT $1 /* assembler temp - uppercase because of ".set at" */
#define v0 $2 /* return value */
#define v1 $3
#define a0 $4 /* argument registers */
#define a1 $5
#define a2 $6
#define a3 $7
#define t0 $8 /* caller saved */
#define t1 $9
#define t2 $10
#define t3 $11
#define t4 $12
#define t5 $13
#define t6 $14
#define t7 $15
#define s0 $16 /* callee saved */
#define s1 $17
#define s2 $18
#define s3 $19
#define s4 $20
#define s5 $21
#define s6 $22
#define s7 $23
#define t8 $24 /* caller saved */
#define t9 $25
#define jp $25 /* PIC jump register */
#define k0 $26 /* kernel scratch */
#define k1 $27
#define gp $28 /* global pointer */
#define sp $29 /* stack pointer */
#define fp $30 /* frame pointer */
#define s8 $30 /* same like fp! */
#define ra $31 /* return address */
.set noreorder
########################################################################################
#
# 上电的引导函数
#
########################################################################################
.globl _start
.text
_start:
bal 1f
nop
.word _GLOBAL_OFFSET_TABLE_ - 1f + 4
1:
move gp, ra
lw $9, 0(ra)
nop
add gp, $9
#sp -->16k
la $25, code_end
nop
add $25, 16384-4-32
move sp, $25
#free_mem_start
add $25, 36
la $24, free_mem_start
nop
sw $25, 0($24)
#转到C代码的入口
la $25, main #$25 始终等于函数的起始地址
nop
jalr $25
#从C代码返回后,终止运行.
.word 0
.word -1 #halt instruct终止指令
########################################################################################
#
# OS_STK *OSTaskStkInit (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT16U opt)
# 建立任务时,保存任务的运行地址和传入参数到堆栈中,
#
# 在 OSStartHighRdy 时,被调度运行.
#
########################################################################################
.globl OSTaskStkInit
.text
OSTaskStkInit:
sw a0 , -4(a2) #运行地址
sw $2 , -8(a2)
sw $3 , -12(a2)
sw a1 , -16(a2) #运行参数
sw $5 , -20(a2)
sw $6 , -24(a2)
sw $7 , -28(a2)
sw $8 , -32(a2)
sw $9 , -36(a2)
sw $10, -40(a2)
sw $11, -44(a2)
sw $12, -48(a2)
sw $13, -52(a2)
sw $14, -56(a2)
sw $15, -60(a2)
sw $16, -64(a2)
sw $17, -68(a2)
sw $18, -72(a2)
sw $19, -76(a2)
sw $21, -80(a2)
sw $22, -84(a2)
sw $23, -88(a2)
sw $24, -92(a2)
sw a0, -96(a2) #函数地址值,C函数开头计算GP时用
sw $26, -100(a2)
sw $27, -104(a2)
sw $28, -108(a2)
# sw $29, -112(a2) #此处的堆栈是 main 处的,在上电时设置的. 与任务的堆栈是不一样的
#所以不需要保存,在第一次调度时,会切换到任务堆栈的.
sw $30, -116(a2)
sw $31, -120(a2)
jr ra
add v0, a2, -120
########################################################################################
#
# void _OSStartHighRdy(OSTCBCur)
# 第一次被调度,
# OSTCBCur:任务的控制区, 第一个地址是堆栈值,从中恢复寄存器,并跳转到任务开始地址.
#
# 被 OSStartHighRdy 调用, 因为汇编函数不知怎样计算GP值,所以不能引用全局变量.
#
########################################################################################
.globl _OSStartHighRdy
.text
_OSStartHighRdy:
# a0 --> OSTCBCur
lw sp , 0(a0) #sp = OSTCBCur->OSTCBStkPtr
#切换到任务的堆栈
nop
lw $2 , 112(sp)
lw $3 , 108(sp)
lw $4 , 104(sp)
lw $5 , 100(sp)
lw $6 , 96(sp)
lw $7 , 92(sp)
lw $8 , 88(sp)
lw $9 , 84(sp)
lw $10, 80(sp)
lw $11, 76(sp)
lw $12, 72(sp)
lw $13, 68(sp)
lw $14, 64(sp)
lw $15, 60(sp)
lw $16, 56(sp)
lw $17, 52(sp)
lw $18, 48(sp)
lw $19, 44(sp)
lw $21, 40(sp)
lw $22, 36(sp)
lw $23, 32(sp)
lw $24, 28(sp)
lw $25, 24(sp)
lw $26, 20(sp)
lw $27, 16(sp)
lw $28, 12(sp)
# lw $29, 8(sp)
lw $30, 4(sp)
lw $31, 0(sp)
lw t9, 116(sp)
nop
jr t9 #第一次进入C函数, 还没有计算出GP的值, $25必须等于函数入口地址,用来计算GP的值
addi sp, sp, 120
########################################################################################
#
# void OSCtxSw()
# 存储当前任务的寄存器,返回地址是当前的 ra.
# 参数:
# OSTCBCur:任务的控制区, 第一个地址是堆栈值
#
# 被 OSCtxSw 调用
#
########################################################################################
.globl OSCtxSw
.text
OSCtxSw:
############################
# save current task to stack
############################
sw ra , -4(sp) #这个 ra 是任务重新调度时的运行地址(返回到OSCtxSw调用的地方)
sw $2 , -8(sp)
sw $3 , -12(sp)
sw $4 , -16(sp)
sw $5 , -20(sp)
sw $6 , -24(sp)
sw $7 , -28(sp)
sw $8 , -32(sp)
sw $9 , -36(sp)
sw $10, -40(sp)
sw $11, -44(sp)
sw $12, -48(sp)
sw $13, -52(sp)
sw $14, -56(sp)
sw $15, -60(sp)
sw $16, -64(sp)
sw $17, -68(sp)
sw $18, -72(sp)
sw $19, -76(sp)
sw $21, -80(sp)
sw $22, -84(sp)
sw $23, -88(sp)
sw $24, -92(sp)
sw $25, -96(sp)
sw $26, -100(sp)
sw $27, -104(sp)
sw $28, -108(sp)
# sw $29, -112(sp)
sw $30, -116(sp)
sw $31, -120(sp)
add sp, sp, -120
############################
#get gp
############################
bal 3f
nop
.word _GLOBAL_OFFSET_TABLE_
3:
lw gp, 0(ra)
nop
#save sp to task TCB
la t0, OSTCBCur #t0 -> address of OSTCBCur
nop
lw t1, 0(t0) #t1 -> OSTCBCur
nop
sw sp, 0(t1)
############################
#
############################
# OSTaskSwHook();
# la t9, OSTaskSwHook
# jalr t9
# OSTCBCur = OSTCBHighRdy;
la t1, OSTCBHighRdy
nop
lw t2, 0(t1)
nop
sw t2, 0(t0) #t0 -> address of OSTCBCur
#sp
lw sp, 0(t2) #t2 -> OSTCBCur
# OSPrioCur = OSPrioHighRdy; 8bit char
la t0, OSPrioHighRdy
nop
lb t1, 0(t0)
la t2, OSPrioCur
nop
sb t1, 0(t2)
############################
# restore new task to running
############################
lw $2 , 112(sp)
lw $3 , 108(sp)
lw $4 , 104(sp)
lw $5 , 100(sp)
lw $6 , 96(sp)
lw $7 , 92(sp)
lw $8 , 88(sp)
lw $9 , 84(sp)
lw $10, 80(sp)
lw $11, 76(sp)
lw $12, 72(sp)
lw $13, 68(sp)
lw $14, 64(sp)
lw $15, 60(sp)
lw $16, 56(sp)
lw $17, 52(sp)
lw $18, 48(sp)
lw $19, 44(sp)
lw $21, 40(sp)
lw $22, 36(sp)
lw $23, 32(sp)
lw $24, 28(sp)
lw $25, 24(sp)
lw $26, 20(sp)
lw $27, 16(sp)
lw $28, 12(sp)
# lw $29, 8(sp)
lw $30, 4(sp)
lw $31, 0(sp)
lw k1, 116(sp)
nop
jr k1 #此处不能用$25,要保留中断前的一切寄存器
addi sp, sp, 120
########################################################################################
#
# void isr_service()
#
# 中断入口函数
#
#
########################################################################################
.globl isr_service
.text
isr_service:
##################
# save all regs
##################
sw $2 , -8(sp)
sw $3 , -12(sp)
sw $4 , -16(sp)
sw $5 , -20(sp)
sw $6 , -24(sp)
sw $7 , -28(sp)
sw $8 , -32(sp)
sw $9 , -36(sp)
sw $10, -40(sp)
sw $11, -44(sp)
sw $12, -48(sp)
sw $13, -52(sp)
sw $14, -56(sp)
sw $15, -60(sp)
sw $16, -64(sp)
sw $17, -68(sp)
sw $18, -72(sp)
sw $19, -76(sp)
sw $21, -80(sp)
sw $22, -84(sp)
sw $23, -88(sp)
sw $24, -92(sp)
sw $25, -96(sp)
sw $26, -100(sp)
sw $27, -104(sp)
sw $28, -108(sp)
# sw $29, -112(sp)
sw $30, -116(sp)
sw $31, -120(sp)
#返回地址(被中断的任务地址) cp0_epc
mfc0 ra, $14 #CP0_EPC $14
sw ra , -4(sp) #运行地址
add sp, sp, -120
##############################
#get gp
##############################
bal 3f
nop
.word _GLOBAL_OFFSET_TABLE_
3:
lw gp, 0(ra)
nop
##############################
# call isr_service_wrap
##############################
la t9, isr_service_wrap
nop
jalr t9
nop
############################
# restore new task to running
############################
lw $2 , 112(sp)
lw $3 , 108(sp)
lw $4 , 104(sp)
lw $5 , 100(sp)
lw $6 , 96(sp)
lw $7 , 92(sp)
lw $8 , 88(sp)
lw $9 , 84(sp)
lw $10, 80(sp)
lw $11, 76(sp)
lw $12, 72(sp)
lw $13, 68(sp)
lw $14, 64(sp)
lw $15, 60(sp)
lw $16, 56(sp)
lw $17, 52(sp)
lw $18, 48(sp)
lw $19, 44(sp)
lw $21, 40(sp)
lw $22, 36(sp)
lw $23, 32(sp)
lw $24, 28(sp)
lw $25, 24(sp)
lw $26, 20(sp)
lw $27, 16(sp)
lw $28, 12(sp)
# lw $29, 8(sp)
lw $30, 4(sp)
lw $31, 0(sp)
############################
#中断处理完成, 返回到被中断的地方
############################
lw k1, 116(sp) #此处不能用$25,要保留中断前的一切寄存器
nop
jr k1
add sp, sp, 120
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -