⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 os_cpu_a.asm

📁 ucos在x86上的移植代码。吐血推荐啊
💻 ASM
字号:
;********************************************************************************************************
;                                               uC/OS-II
;                                         The Real-Time Kernel
;
;                          (c) Copyright 1992-2002, Jean J. Labrosse, Weston, FL
;                                          All Rights Reserved
;
;
;                                       80x86/80x88 Specific code
;                                          LARGE MEMORY MODEL
;
;                                           Borland C/C++ V4.51
;                                       (IBM/PC Compatible Target)
;
; File         : OS_CPU_A.ASM
; By           : Jean J. Labrosse
;********************************************************************************************************

[SECTION .text]
[BITS 32]

;********************************************************************************************************
;                                    global and EXTERNAL REFERENCES
;********************************************************************************************************

            global  OSTickISR
            global  OSStartHighRdy
            global  OSCtxSw
            global  OSIntCtxSw

            extern  OSIntExit
            extern  OSTimeTick
            extern  OSTaskSwHook

            extern  OSIntNesting ;:BYTE
            extern  OSTickDOSCtr ;:BYTE
            extern  OSPrioHighRdy ;:BYTE
            extern  OSPrioCur ;:BYTE
            extern  OSRunning ;:BYTE
            extern  OSTCBCur ;:DWORD
            extern  OSTCBHighRdy ;:DWORD

;*********************************************************************************************************
;                                          START MULTITASKING
;                                       void OSStartHighRdy(void)
;
; The stack frame is assumed to look as follows:
;
; OSTCBHighRdy->OSTCBStkPtr --> DS                               (Low memory)
;                               ES
;                               EDI
;                               ESI
;                               EBP
;                               ESP
;                               EBX
;                               EDX
;                               ECX
;                               EAX
;                               OFFSET  of task code address
;                               SEGMENT of task code address
;                               Flags to load in PSW
;                               OFFSET  of task code address
;                               SEGMENT of task code address
;                               OFFSET  of 'pdata'
;                               SEGMENT of 'pdata'               (High memory)
;
; Note : OSStartHighRdy() MUST:
;           a) Call OSTaskSwHook() then,
;           b) Set OSRunning to TRUE,
;           c) Switch to the highest priority task.
;*********************************************************************************************************

OSStartHighRdy:
            CALL   OSTaskSwHook          				; Call user defined task switch hook
;
            MOV    AL, 1                          ; OSRunning = TRUE;
            MOV    BYTE [OSRunning], AL     			;   (Indicates that multitasking has started)

						MOV    EBX, [OSTCBHighRdy]
            MOV    ESP, [EBX]           					; 切换任务栈
;
            POP    DS                             ; Load task's context
            POP    ES                             ;
            POPAD
;
            IRETD                                 ; Run task

;*********************************************************************************************************
;                                PERFORM A CONTEXT SWITCH (From task level)
;                                           void OSCtxSw(void)
;
; Note(s): 1) Upon entry,
;             OSTCBCur     points to the OS_TCB of the task to suspend
;             OSTCBHighRdy points to the OS_TCB of the task to resume
;
;          2) The stack frame of the task to suspend looks as follows:
;
;                 SP -> OFFSET  of task to suspend    (Low memory)
;                       SEGMENT of task to suspend
;                       PSW     of task to suspend    (High memory)
;
;          3) The stack frame of the task to resume looks as follows:
;
;                 OSTCBHighRdy->OSTCBStkPtr --> DS                               (Low memory)
;                                               ES
;                                               EDI
;                                               ESI
;                                               EBP
;                                               ESP
;                                               EBX
;                                               EDX
;                                               ECX
;                                               EAX
;                                               ADDRESS of task code
;                                               Flags to load in EPSW             (High memory)
;*********************************************************************************************************

OSCtxSw: ;任务级任务切换
;
            PUSHAD                        ; Save current task's context
            PUSH   ES                     ;
            PUSH   DS                     ;

						MOV    EBX, [OSTCBCur]
            MOV    [EBX], ESP      				; OSTCBCur->OSTCBStkPtr = ESP

            CALL   OSTaskSwHook           ; Call user defined task switch hook

            MOV    EAX, [OSTCBHighRdy]  	; OSTCBCur <= OSTCBHighRdy
            MOV    [OSTCBCur], EAX      	;

            MOV    AL, [OSPrioHighRdy]   	; OSPrioCur <= OSPrioHighRdy
            MOV    [OSPrioCur], AL      	;

            MOV    EBX, [OSTCBHighRdy]  	; ESP = OSTCBHighRdy->OSTCBStkPtr
            MOV    ESP, [EBX]

            POP    DS                     ; Load new task's context
            POP    ES                     ;
            POPAD

            IRETD                         ; Return to new task
;

;*********************************************************************************************************
;                                PERFORM A CONTEXT SWITCH (From an ISR)
;                                        void OSIntCtxSw(void)
;
; Note(s): 1) Upon entry,
;             OSTCBCur     points to the OS_TCB of the task to suspend
;             OSTCBHighRdy points to the OS_TCB of the task to resume
;
;          2) The stack frame of the task to suspend looks as follows:
;
;             OSTCBCur->OSTCBStkPtr ------>  DS                              (Low memory)
;                                            ES
;                                            DI
;                                            SI
;                                            BP
;                                            SP
;                                            BX
;                                            DX
;                                            CX
;                                            AX
;                                            OFFSET  of task code address
;                                            SEGMENT of task code address
;                                            Flags to load in PSW            (High memory)
;
;
;          3) The stack frame of the task to resume looks as follows:
;
;             OSTCBHighRdy->OSTCBStkPtr --> DS                               (Low memory)
;                                           ES
;                                           DI
;                                           SI
;                                           BP
;                                           SP
;                                           BX
;                                           DX
;                                           CX
;                                           AX
;                                           OFFSET  of task code address
;                                           SEGMENT of task code address
;                                           Flags to load in PSW             (High memory)
;*********************************************************************************************************

OSIntCtxSw:
;
            CALL   OSTaskSwHook           ; Call user defined task switch hook
;
            MOV    EAX, [OSTCBHighRdy] 		; OSTCBCur = OSTCBHighRdy
            MOV    [OSTCBCur], EAX        ;
;
            MOV    AL, [OSPrioHighRdy]	  ; OSPrioCur = OSPrioHighRdy
            MOV    [OSPrioCur], AL
;
            MOV    EBX, [OSTCBHighRdy]     ; SS:SP = OSTCBHighRdy->OSTCBStkPtr
            MOV    ESP, [EBX]                ;
;
            POP    DS                      ; Load new task's context
            POP    ES                      ;
            POPAD                           ;
;
            IRETD                          ; Return to new task
;

;*********************************************************************************************************
;                                            HANDLE TICK ISR
;
; Description: This function is called 199.99 times per second or, 11 times faster than the normal DOS
;              tick rate of 18.20648 Hz.  Thus every 11th time, the normal DOS tick handler is called.
;              This is called chaining.  10 times out of 11, however, the interrupt controller on the PC
;              must be cleared to allow for the next interrupt.
;
; Arguments  : none
;
; Returns    : none
;
; Note(s)    : The following C-like pseudo-code describe the operation being performed in the code below.
;
;              Save all registers on the current task's stack;
;              OSIntNesting++;
;              if (OSIntNesting == 1) {
;                 OSTCBCur->OSTCBStkPtr = SS:SP
;              }
;              OSTickDOSCtr--;
;              if (OSTickDOSCtr == 0) {
;                  OSTickDOSCtr = 11;
;                  INT 81H;               Chain into DOS every 54.925 mS
;                                         (Interrupt will be cleared by DOS)
;              } else {
;                  Send EOI to PIC;       Clear tick interrupt by sending an End-Of-Interrupt to the 8259
;                                         PIC (Priority Interrupt Controller)
;              }
;              OSTimeTick();              Notify uC/OS-II that a tick has occured
;              OSIntExit();               Notify uC/OS-II about end of ISR
;              Restore all registers that were save on the current task's stack;
;              Return from Interrupt;
;*********************************************************************************************************
;
OSTickISR:
;
            PUSHAD                                ; Save interrupted task's context
            PUSH   ES
            PUSH   DS

            INC    BYTE [OSIntNesting]      ; Notify uC/OS-II of ISR

            CMP    BYTE [OSIntNesting], 1	 ; if (OSIntNesting == 1)
            JNE    SHORT _OSTickISR1

						MOV    EBX, [OSTCBCur]
            MOV    [EBX], ESP     ; OSTCBCur->OSTCBStkPtr = (SS):ESP

_OSTickISR1:
            MOV    AL, 20H             ; Move EOI code into AL.
            MOV    DX, 20H             ; Address of 8259 PIC in DX.
            OUT    DX, AL              ; Send EOI to PIC if not processing DOS timer.
;
_OSTickISR3:
            CALL   OSTimeTick         ; Process system tick
;
            CALL   OSIntExit          ; Notify uC/OS-II of end of ISR
;
            POP    DS                  ; Restore interrupted task's context
            POP    ES
            POPAD
;
            IRETD                      ; Return to interrupted task

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -