|
请问:
(1)、创建任务时,任务堆栈初始化子程序(OSTaskStkInit)中,AX,CX,DX,BX,BP,SI,DI,ES,可以被初始化为
任意值,DS初始化为当前数据段段地址,SP指针也可以被初始化为任意值吗?
(2)、我不明白,当执行后以下几条语句后,SP到底等于多少?
PUSHA ; Save current task's context
PUSH ES ;
PUSH DS ;
;
MOV AX, SEG _OSTCBCur ; Reload DS in case it was altered
MOV DS, AX ;
;
LES BX, DWORD PTR DS:_OSTCBCur ; OSTCBCur->OSTCBStkPtr = SS:SP
MOV ES:[BX+2], SS ;
MOV ES:[BX+0], SP ;
如果执行PUSHA之前,SP=0,那么执行完DS后,SP=20吗?
此时执行 MOV ES:[BX+2], SS ;
MOV ES:[BX+0], SP ;
后,挂起任务的堆栈中记录的堆栈指针SS:SP=SS:20吗?
我的理解如下:
任务切换子程序OSCtxSw()中
(1)、通过执行PUSHA
将CPU的寄存器AX,CX,DX,BX,SP,BP,SI,DI压入当前任务的堆栈中
(2)、通过执行PUSH ES,PUSH DS
将CPU的寄存器ES,DS压入当前任务的堆栈中
(3)、通过执行如下语句,获取最高优先级任务的堆栈的段地址SS和偏移地址SP
LES BX, DWORD PTR DS:_OSTCBHighRdy ; SS:SP = OSTCBHighRdy->OSTCBStkPtr
MOV SS, ES:[BX+2] ;
MOV SP, ES:[BX] ;
如果假定SS=4055,
那么此时SP好象应该=20,因为前面执行了PUSHA、PUSH ES、PUSH DS。
(4)、通过执行POP DS、POP ES
将最高优先级任务堆栈中保存的DS、ES恢复到CPU中。此时SP=16
(5)、执行POPA ;
将DI、SI、BP、SP、DX、CX、AX依次从任务堆栈中恢复到CPU中。此时SP=0
附:
1、任务堆栈初始化子程序
OS_STK *OSTaskStkInit (void (*task)(void *pd), void *pdata, OS_STK *ptos, INT16U opt)
{
INT16U *stk;
opt = opt; /* 'opt' is not used, prevent warning */
stk = (INT16U *)ptos; /* Load stack pointer */
*stk-- = (INT16U)FP_SEG(pdata); /* Simulate call to function with argument */
*stk-- = (INT16U)FP_OFF(pdata);
*stk-- = (INT16U)FP_SEG(task);
*stk-- = (INT16U)FP_OFF(task);
*stk-- = (INT16U)0x0202; /* SW = Interrupts enabled */
*stk-- = (INT16U)FP_SEG(task); /* Put pointer to task on top of stack */
*stk-- = (INT16U)FP_OFF(task);
*stk-- = (INT16U)0xAAAA; /* AX = 0xAAAA */
*stk-- = (INT16U)0xCCCC; /* CX = 0xCCCC */
*stk-- = (INT16U)0xDDDD; /* DX = 0xDDDD */
*stk-- = (INT16U)0xBBBB; /* BX = 0xBBBB */
*stk-- = (INT16U)0x0000; /* SP = 0x0000 */
*stk-- = (INT16U)0x1111; /* BP = 0x1111 */
*stk-- = (INT16U)0x2222; /* SI = 0x2222 */
*stk-- = (INT16U)0x3333; /* DI = 0x3333 */
*stk-- = (INT16U)0x4444; /* ES = 0x4444 */
*stk = _DS; /* DS = Current value of DS */
return ((OS_STK *)stk);
}
2、任务切换子程序
_OSCtxSw PROC FAR
PUSHA ; Save current task's context
PUSH ES ;
PUSH DS ;
;
MOV AX, SEG _OSTCBCur ; Reload DS in case it was altered
MOV DS, AX ;
;
LES BX, DWORD PTR DS:_OSTCBCur ; OSTCBCur->OSTCBStkPtr = SS:SP
MOV ES:[BX+2], SS ;
MOV ES:[BX+0], SP ;
;
CALL FAR PTR _OSTaskSwHook ; Call user defined task switch hook
;
MOV AX, WORD PTR DS:_OSTCBHighRdy+2 ; OSTCBCur = OSTCBHighRdy
MOV DX, WORD PTR DS:_OSTCBHighRdy ;
MOV WORD PTR DS:_OSTCBCur+2, AX ;
MOV WORD PTR DS:_OSTCBCur, DX ;
;
MOV AL, BYTE PTR DS:_OSPrioHighRdy ; OSPrioCur = OSPrioHighRdy
MOV BYTE PTR DS:_OSPrioCur, AL ;
;
LES BX, DWORD PTR DS:_OSTCBHighRdy ; SS:SP = OSTCBHighRdy->OSTCBStkPtr
MOV SS, ES:[BX+2] ;
MOV SP, ES:[BX] ;
;
POP DS ; Load new task's context
POP ES ;
POPA ;
IRET ; Return to new task
_OSCtxSw ENDP
|
阿莫论坛20周年了!感谢大家的支持与爱护!!
一只鸟敢站在脆弱的枝条上歇脚,它依仗的不是枝条不会断,而是自己有翅膀,会飞。
|