<br />;软件中断的程序部分如下:<br />SoftwareInterrupt<br /> CMP R0, #12<br /> LDRLO PC, [PC, R0, LSL #2]<br /> MOVS PC, LR ;根据r0值来决定swi的功能<br /><br />SwiFunction<br /> DCD TASK_SW ;0<br /> DCD ENTER_CRITICAL ;1<br /> DCD EXIT_CRITICAL ;2<br /> DCD ISRBegin ;3<br /> DCD ChangeToSYSMode ;4<br /> DCD ChangeToUSRMode ;5<br /> DCD __OSStartHighRdy ;6<br /> DCD TaskIsARM ;7<br /> DCD TaskIsTHUMB ;8<br /> DCD OSISRNeedSwap ;9<br /> DCD GetOSFunctionAddr ;10<br /> DCD GetUsrFunctionAddr ;11<br /><br />TASK_SW ;任务中的任务切换由此进入<br /> MRS R3, SPSR ;保存任务的CPSR<br /> MOV R2, LR ;保存任务的PC<br /> <br /> MSR CPSR_c, #(NoInt | SYS32Mode) ;切换到系统模式<br /> STMFD SP!, {R2} ;保存PC到堆栈<br /> STMFD SP!, {R0-R12, LR} ;保存R0-R12,LR到堆栈<br /> <br /> ;因为R0~R3没有保存有用数据,所以可以这样做?<br /> <br /> B OSIntCtxSw_0 ;真正进行任务切换<br /><br /><br />以上只是截取了软件中断程序的开始一部分,我的问题是在软件中断的最开始为什么没有保存全部的寄存器r0-r12到堆栈哪?因为实际的工程中,若用c语言写程序,则无法保证c函数不会使用某一个在寄存器,例如r2或r3等等,若软件中断的最开始没有保存r2或r3,而软件中断中有使用了r2,r3,则就很有可能破坏掉c函数中的r2或r3的值.<br />所以我觉得这个程序只适用于简单的事先已经知道程序中不会用到r0-r3的情况,若复杂一些的系统直接使用此移植代码则会出问题.不知我的理解对不对?<br /> |
|