OSCtxSw()是任务级切换函数,其实就是一个软中断,下面我就来分析一下在PC上移植的代码一行一行进行解析解析
_OSCtxSw PROC FAR
//调用子程序,PROC和ENDP是配对使用的,过程的最后一条指令一般是返回指令(RET)。
PUSHA
//将所有通用寄存器按顺序存储到堆栈:EAX、ECX、EDX、EBX、EBP、ESP、EBP、ESI 及 EDI进行入栈,
PUSH ES ;
PUSH DS
// ES和DS不是通用寄存器所以单独入栈
MOV AX, SEG_OSTCBCur
MOV DS, AX
//SEG_OSTCBCur是什么?是OSTCBCur所在的段地址,放入DS段寄存器中去
LES BX, DWORD PTR DS:_OSTCBCur
把DS:_OSTCBCur这个地址分开装,BX里面存放OSTCBCur地址,ES里面存放的是SEG_OSTCBCur
MOV ES:[BX+2], SS ;MOV ES:[BX+0], SP
将堆栈指针位置SP保存到任务A的任务控制块OS_TCB的OSTCBStkPtr成员中
CALL FAR PTR _OSTaskSwHook
//调用钩子函数OSTaskSwHook().应用程序人员可以在钩子函数中编写需要的代码
MOV AX, WORD PTR DS:_OSTCBHighRdy+2
MOV DX, WORD PTR DS:_OSTCBHighRdy
MOV WORD PTR DS:_OSTCBCur+2, AX
MOV WORD PTR DS:_OSTCBCur, DX
//这段话的意思是其实就是 OSTCBCur = OSTCBHighRdy
MOV AL, BYTE PTR DS:_OSPrioHighRdy
MOV BYTE PTR DS:_OSPrioCur, AL
// 这两句的意思就是OSPrioCur = OSPrioHighRdy
LES BX, DWORD PTR DS:_OSTCBHighRdy
MOV SS, ES:[BX+2] ;
MOV SP, ES:[BX]
//把新任务的堆栈指针取出来SS:SP = OSTCBHighRdy->OSTCBStkPtr
POP DS
POP ES
//把新任务堆栈里面的DS和ES寄存器出栈
POPA
//把新任务所有的通用寄存器出栈
IRET
/*执行IRET中断返回指令,依次从任务A的私栈中弹出:一是任务A上次断点地址的偏移地址到IP寄存器 二任务A上次断点地址的段移地址到CS寄存器
三程序状态字PSW(中断是开放)然后跳转到CS:IP位置处(上次断点位置)继续执行任务A的代码*/
_OSCtxSw ENDP
结束了,小伙伴们懂了么?