📄 os_cpu_a.asm
字号:
; os_cpu_a.asm
;
; Port of uC/OS-II (C) to the Intel 80x86 (32-bit flat protected mode)
; By Jean L. Gareau (jean.gareau@exposecorp.com)
;
; Copyright (C) 1997-1999, Jean L. Gareau. All rights reserved.
; This file or its content can not be used for commercial applications
; without the prior written permission of the author.
;
;(C) 2000 Anton Civit (civit@icaro.fie.us.es). Ported to Borland C V5.2 and On Time Systems
;RTTarget32 V2.0
;
; Description:
; This file contains the assembly language routines of the port
; (see os_cpu_c.c for the C routines).
; The implementation has been upgraded from the initial port (to uC/OS).
; Comments have been added to reflects the pseudo-code provided in
; Chapter 10 of the uC/OS-II book.
;
; Compared to the real mode implementation found in the uC/OS-II book,
; the most important differences are:
; a) 32-bit intructions are always used instead of 16-bit;
; b) There is no segment to worry about.
;
; Development Environment:
; This file has been developed with TASM32 V5.2B (not tested on other versions
; but it probably works
; Versions:
; 1.00 14-Dec-97 Initial release.
; 2.00 28-Feb-99 Upgrade from uC/OS to uC/OS-II
; 2.00B 29-Feb-2000 Port to CBuilder and RTTarget
; TITLE os_cpu_a.asm
.386P ; Priviledged instructions can be used.
model flat
; The following segments are expected by Borland's BCC32 compiler.
_TEXT segment dword public use32 'CODE'
_TEXT ends
_DATA segment dword public use32 'DATA'
_DATA ends
_BSS segment dword public use32 'BSS'
_BSS ends
DGROUP group _BSS,_DATA
_TEXT SEGMENT dword public use32 'CODE'
;=======================================================================
; uCOS-II Functions
;=======================================================================
;-----------------------------------------------------------------------
; OSTickISR
;-----------------------------------------------------------------------
PUBLIC _OSTickISR
EXTRN _OSIntEnter:NEAR
EXTRN _OSTimeTick:NEAR
EXTRN _OSIntExit:NEAR
_OSTickISR PROC NEAR
pushad
; Send an end-of-interrupt to the i8259.
mov al,20h
out 20h,al
; Standard uCOS processing.
call _OSIntEnter
call _OSTimeTick
call _OSIntExit
popad
iretd
_OSTickISR ENDP
;-----------------------------------------------------------------------
; OSStartHighRdy
;-----------------------------------------------------------------------
PUBLIC _OSStartHighRdy
EXTRN _OSTaskSwHook:NEAR
EXTRN _OSRunning:BYTE
EXTRN _OSTCBHighRdy:DWORD
_OSStartHighRdy PROC NEAR
; Call OSTaskSwHook();
call _OSTaskSwHook
; Increment OSRunning by 1 (the documentation says to set it to 1,
; but the ix86l example increments it).
inc [_OSRunning]
; Load the processor stack pointer with OSTCBHighRdy->OSTCBStkPtr
mov eax,[_OSTCBHighRdy] ; Point to TCB of highest priority task ready to run
mov [_OSTCBCur],eax
mov esp,[eax] ; ESP = OSTCBHighRdy->OSTCBStkPtr
; Pop all the processor registers from the stack
popad
; Execute a Return from interrupt intruction;
iretd
_OSStartHighRdy ENDP
;-----------------------------------------------------------------------
; OSCtxSw
;-----------------------------------------------------------------------
PUBLIC _OSCtxSw
EXTRN _OSTCBCur:DWORD
EXTRN _OSTaskSwHook:NEAR
EXTRN _OSTCBHighRdy:DWORD
_OSCtxSw PROC NEAR
; PUSH processor registers onto the current task's stack
pushad
; Save the stack pointer into OSTCBCur->OSTCBStkPtr
mov eax,[_OSTCBCur]
mov [eax],esp ; Stack pointer is ESP
; Call OSTaskSwHook();
call _OSTaskSwHook
; OSTCBCur = OSTCBHighRdy
mov eax,[_OSTCBHighRdy] ; EAX is OSTCBHighRdy
mov [_OSTCBCur],eax
; Load the processor stack pointer with OSTCBHighRdy->OSTCBStkPtr
mov esp,[eax] ; ESP = OSTCBHighRdy->OSTCBStkPtr
mov al,[_OSPrioHighRdy]
mov [_OSPrioCur],al ;Adjust OSPrioCur
; Pop all the processor registers from the stack
popad
; Execute a Return from interrupt intruction;
iretd
_OSCtxSw ENDP
;-----------------------------------------------------------------------
; OSIntCtxSw
;-----------------------------------------------------------------------
PUBLIC _OSIntCtxSw
EXTRN _OSTCBCur:DWORD
EXTRN _OSTaskSwHook:NEAR
EXTRN _OSPrioHighRdy:BYTE
EXTRN _OSPrioCur:BYTE
EXTRN _OSTCBHighRdy:DWORD
_OSIntCtxSw PROC NEAR
; Adjust the stack pointer to remove call to OsIntExit(), locals in
; OsIntExit() and the call to OSIntCtxSw();
add esp,16 ; Ignore calls to OSIntExit, PUSH EBP (BCC32 PUSHES EBP in OSIntExit), PUSHFD and OSIntCtxSw
; Save the stack pointer into OSTCBCur->OSTCBStkPtr
mov eax,[_OSTCBCur]
mov [eax],esp ; Stack pointer is ESP
; Call OSTaskSwHook();
call _OSTaskSwHook
; OSPrioCur = OSPrioHighRdy
mov al,[_OSPrioHighRdy]
mov [_OSPrioCur],al
; OSTCBCur = OSTCBHighRdy
mov eax,[_OSTCBHighRdy] ; EAX is OSTCBHighRdy
mov [_OSTCBCur],eax
; Load the processor stack pointer with OSTCBHighRdy->OSTCBStkPtr
mov esp,[eax] ; ESP = OSTCBHighRdy->OSTCBStkPtr
; Pop all the processor registers from the stack
popad
; Execute a Return from interrupt intruction;
iretd
_OSIntCtxSw ENDP
;-----------------------------------------------------------------------
; void DumpStackHandler();
;
; This is usefull handler that dumps the last three DWORDS pushed
; on the stack. This is convenient in a fault handler to determine the
; source of the fault. The function never returns.
;
; _DEBUG must be defined for this code to be effective.
;-----------------------------------------------------------------------
IFDEF _DEBUG
PUBLIC _DumpStackHandler
EXTERN _ShowRegister:NEAR
_DumpStackHandler PROC NEAR
mov eax,[esp] ; EAX: last pushed DWORD
push eax
call _ShowRegister ; Show it
add esp,4
mov eax,[esp+4] ; EAX: previous pushed DWORD
push eax
call _ShowRegister ; Show it
add esp,4
mov eax,[esp+8] ; EAX: 2nd previous pushed DWORD
push eax
call _ShowRegister
add esp,4
; Enter an infinite loop. It is likely that things went wrong and
; continuing could reset the PC, losing whatever is on the screen.
Here:
jmp Here
_DumpStackHandler ENDP
ENDIF
_TEXT ENDS
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -