📄 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.
;
; Description:
; This file contains the assembly language routines of the port
; (see os_cpu_c.c for the C routines). A full description of the port
; can be found in Port86pm.doc. Although most of this routines could be
; embedded in os_cpu_c.c under Visual C++ 6.0, some compilers do not
; support this feature. Thus, all the assembly code is in this file.
;
; 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 Microsoft Assembler 6.11 using the
; following command:
;
; ml /c /Fl /coff [/D_DEBUG] os_cpu_a.asm
;
; The macro _DEBUG can be enabled to dump the stack of unexpected interrupts.
; In that case, os_cpu_c.c must also be compiled with _DEBUG defined as well.
;
; Versions:
; 1.00 14-Dec-97 Initial release.
; 2.00 28-Feb-99 Upgrade from uC/OS to uC/OS-II
; 2.01 10-Nov-99 Adjusted the current priority in OSCtxSw() and OSIntCtxSw().
; TITLE os_cpu_a.asm
.386P ; Priviledged instructions can be used.
; The following segments are expected by Microsoft's CL compiler.
_TEXT SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT ENDS
_DATA SEGMENT DWORD USE32 PUBLIC 'DATA'
_DATA ENDS
CONST SEGMENT DWORD USE32 PUBLIC 'CONST'
CONST ENDS
_BSS SEGMENT DWORD USE32 PUBLIC 'BSS'
_BSS ENDS
_TLS SEGMENT DWORD USE32 PUBLIC 'TLS'
_TLS ENDS
; Put all segment directives into one single group (flat memory model).
GFLAT GROUP _TEXT, _DATA, CONST, _BSS
ASSUME CS: GFLAT, DS: GFLAT, ES: GFLAT, SS: GFLAT
_TEXT SEGMENT
;=======================================================================
; 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 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 _OSPrioHighRdy:BYTE
EXTRN _OSPrioCur:BYTE
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
; OSPrioCur = OSPrioHighRdy
mov al,[_OSPrioHighRdy] ; AL is OSPrioHighRdy
mov [_OSPrioCur],al
; OSTCBCur = OSTCBHighRdy
mov eax,[_OSTCBHighRdy] ; EAX is OSTCBHighRdy
mov [_OSTCBCur],eax
; Load the processor stack pointer with OSTCBHighRdy->OSTCBStkPtr
; Note that EAX is still OSTCBHighRdy.
mov esp,[eax] ; ESP = OSTCBHighRdy->OSTCBStkPtr
; 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();
;IFDEF _SAVE_INT_STATUS
add esp,12 ; Ignore calls to OSIntExit, PUSHFD and OSIntCtxSw
;ELSE
; add esp,8 ; Ignore calls to OSIntExit and OSIntCtxSw
;ENDIF
; 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] ; AL is OSPrioHighRdy
mov [_OSPrioCur],al
; OSTCBCur = OSTCBHighRdy
mov eax,[_OSTCBHighRdy] ; EAX is OSTCBHighRdy
mov [_OSTCBCur],eax
; Load the processor stack pointer with OSTCBHighRdy->OSTCBStkPtr
; Note that EAX is still OSTCBHighRdy.
mov esp,[eax] ; ESP = OSTCBHighRdy->OSTCBStkPtr
; Pop all the processor registers from the stack
popad
; Execute a Return from interrupt intruction;
iretd
_OSIntCtxSw ENDP
;=======================================================================
; x86 Helper Functions.
;=======================================================================
;-----------------------------------------------------------------------
; void DefIntHandler();
;
; Default interrupt handler. It simply performs an interrupt return.
; It is required to initialize all interrupt entries in the IDT.
;-----------------------------------------------------------------------
PUBLIC _DefIntHandler
_DefIntHandler PROC NEAR
iretd ; Simply return from interrupt.
_DefIntHandler 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
;-----------------------------------------------------------------------
; UBYTE inportb(UWORD PortNo);
;
; Reads a byte from the specified port. The byte is returned in AL,
; since Microsoft CL uses EAX for returned values.
;-----------------------------------------------------------------------
PUBLIC _inportb
_inportb PROC NEAR
push ebp
mov ebp,esp
push edx
mov edx,[ebp+8] ; EDX: Port No
in al,dx ; Input the value.
pop edx
pop ebp
ret ; AL contains the value to return.
_inportb ENDP
;-----------------------------------------------------------------------
; void outportb(UWORD PortNo, UBYTE Value);
;
; Write a value to a specified port.
;-----------------------------------------------------------------------
PUBLIC _inportb
_outportb PROC NEAR
push ebp
mov ebp,esp
push eax
push edx
mov dx,[ebp+8] ; Get the port.
mov al,[ebp+12] ; Get the value.
out dx,al ; Output the value to the port.
pop edx
pop eax
pop ebp
ret
_outportb ENDP
_TEXT ENDS
END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -