OSCtxSw
; SAVE CURRENT TASK'S CONTEXT:
STMFD SP!, {LR} ; Push return address,
;STMFD命令是满栈递减,即是指令STMDB(地址先减后压栈)将LR中内容压入SP减1后所指的位置上
STMFD SP!, {LR} ;同上
STMFD SP!, {R0-R12} ; Push registers,
MRS R0, CPSR ; Push current CPSR,
TST LR, #1 ; See if called from Thumb mode,
ORRNE R0, R0, #OS_CPU_ARM_CONTROL_THUMB ; If yes, set the T-bit.
STMFD SP!, {R0}
;到此压栈结束,栈中存储内容如下
;地址 内容
;1234 | |
;1230 | LR |
;1226 | LR |
;1222 | R12 |
;1218 | R11 |
;1214 | R10 |
;1210 | R9 |
;1206 | R8 |
;1202 | R7 |
;1198 | R6 |
;1194 | R5 |
;1190 | R4 |
;1186 | R3 |
;1182 | R2 |
;1178 | R1 |
;1174 | R0 |
;1170 | CPSR |
LDR R0, __OS_TCBCur ; OSTCBCur->OSTCBStkPtr = SP;
LDR R1, [R0]
STR SP, [R1]
LDR R0, __OS_TaskSwHook ; OSTaskSwHook();
MOV LR, PC
BX R0
LDR R0, __OS_PrioCur ; OSPrioCur = OSPrioHighRdy;
LDR R1, __OS_PrioHighRdy
LDRB R2, [R1]
STRB R2, [R0]
LDR R0, __OS_TCBCur ; OSTCBCur = OSTCBHighRdy;
LDR R1, __OS_TCBHighRdy
LDR R2, [R1]
STR R2, [R0]
LDR SP, [R2] ; SP = OSTCBHighRdy->OSTCBStkPtr;
; RESTORE NEW TASK'S CONTEXT:
LDMFD SP!, {R0} ; Pop new task's CPSR,
MSR SPSR_cxsf, R0
LDMFD SP!, {R0-R12, LR, PC}^ ; Pop new task's context.
;出栈指令LDMFD虽然叫满栈递减,但实际调用的指令是LDMIA,即先出栈后将地址加1
;出栈操作后的结果
;地址 | |
;1234 | |
;1230 | PC |
;1226 | LR |
;1222 | R12 |
;1218 | R11 |
;1214 | R10 |
;1210 | R9 |
;1206 | R8 |
;1202 | R7 |
;1198 | R6 |
;1194 | R5 |
;1190 | R4 |
;1186 | R3 |
;1182 | R2 |
;1178 | R1 |
;1174 | R0 |
;1170 | CPSR |
PS:有一个约定,编号低的寄存器在存贮数据或是加载数据时对应于存储器的低地址
MSR{<条件码>CPSR_f|SPSR_f,<#ommed_8r>
MSR{<条件码>CPSR_<field>|SPSR_<field>,Rm
其中:
<field>字段可以是以下之一或多种:
C:控制域屏蔽字段(PSR中的第0位到第7位);
X:扩展域屏蔽字段(PSR中的第8位到第15位);
S:状态域屏蔽字段(PSR中的第16位到第32位);
F:标志域屏蔽字段(PSR中的第24位到第31位)。