;********************************************************************************************************
;                                               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 WITH FLOATING-POINT
;                                          Borland C/C++ V4.51
;
; File         : OS_CPU_A.ASM
; By           : Jean J. Labrosse
;********************************************************************************************************

        //集中了处理器所有相关的汇编代码

            PUBLIC _OSStartHighRdy
            PUBLIC _OSCtxSw
            PUBLIC _OSIntCtxSw
            PUBLIC _OSFPRestore
            PUBLIC _OSFPSave
            PUBLIC _OSTickISR

            EXTRN  _OSIntExit:FAR
            EXTRN  _OSTimeTick:FAR
            EXTRN  _OSTaskSwHook:FAR
            
            EXTRN  _OSIntNesting:BYTE
            EXTRN  _OSTickDOSCtr:BYTE
            EXTRN  _OSPrioHighRdy:BYTE
            EXTRN  _OSPrioCur:BYTE
            EXTRN  _OSRunning:BYTE
            EXTRN  _OSTCBCur:DWORD
            EXTRN  _OSTCBHighRdy:DWORD

.MODEL      LARGE
.CODE
.186
            PAGE                                    ; /*$PAGE*/
;*********************************************************************************************************
;                                          START MULTITASKING
;                                       void OSStartHighRdy(void)
;
; The stack frame is assumed to look 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             
;                               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  PROC FAR

            CALL   FAR PTR _OSTaskSwHook            ; Call user defined task switch hook
;
            MOV    AX, SEG _OSTCBHighRdy            ; Reload DS
            MOV    DS, AX                           ;
            MOV    AL, 1                            ; OSRunning = TRUE;
            MOV    BYTE PTR DS:_OSRunning, AL       ;   (Indicates that multitasking has started)
;
            LES    BX, DWORD PTR DS:_OSTCBHighRdy   ; SS:SP = OSTCBHighRdy->OSTCBStkPtr
            MOV    SS, ES:[BX+2]                    ;
            MOV    SP, ES:[BX+0]                    ;
;
            POP    DS                               ; Load task's context
            POP    ES                               ;
            POPA                                    ;
;
            IRET                                    ; Run task

_OSStartHighRdy  ENDP

            PAGE                                    ; /*$PAGE*/
;*********************************************************************************************************
;                                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
;                                               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)
;*********************************************************************************************************

_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

            PAGE                                    ; /*$PAGE*/
;*********************************************************************************************************
;                                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 PROC   FAR
;
            CALL   FAR PTR _OSTaskSwHook            ; Call user defined task switch hook
;
            MOV    AX, SEG _OSTCBCur                ; Reload DS in case it was altered
            MOV    DS, AX                           ;
;
            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
;
_OSIntCtxSw ENDP

            PAGE                                    ; /*$PAGE*/
;*********************************************************************************************************
;                                           RESTORE FPU REGISTERS
;                                       void OSFPRestore(void *pblk)
;
; Description : This function is called to restore the contents of the FPU registers during a context
;               switch.  It is assumed that a pointer to a storage area for the FPU registers is placed
;               in the task's TCB (i.e. .OSTCBExtPtr).
; Arguments   : pblk    is passed to this function when called.
; Note(s)     : 1) The stack frame upon entry looks as follows:
;
;                      SP + 0 -> OFFSET  of caller             (Low memory)
;                         + 2    SEGMENT of caller
;                         + 4    OFFSET  of pblk
;                         + 6    SEGMENT of pblk               (High memory)  
;*********************************************************************************************************

_OSFPRestore PROC   FAR
;
             PUSH   BP                              ; Save work registers
             MOV    BP,SP
             PUSH   ES                              
             PUSH   BX
;
             LES    BX, DWORD PTR [BP+6]            ; Point to 'pblk'
;
             FRSTOR ES:[BX]                         ; Restore FPU context
;
             POP    BX                              ; Restore work registers
             POP    ES
             POP    BP
;
             RET                                    ; Return to caller
;
_OSFPRestore ENDP

             PAGE                                   ; /*$PAGE*/
;*********************************************************************************************************
;                                           SAVE FPU REGISTERS
;                                        void OSFPSave(void *pblk)
;
; Description : This function is called to save the contents of the FPU registers during a context
;               switch.  It is assumed that a pointer to a storage area for the FPU registers is placed
;               in the task's TCB (i.e. .OSTCBExtPtr).
; Arguments   : pblk    is passed to this function when called.
; Note(s)     : 1) The stack frame upon entry looks as follows:
;
;                      SP + 0 -> OFFSET  of caller             (Low memory)
;                         + 2    SEGMENT of caller
;                         + 4    OFFSET  of pblk
;                         + 6    SEGMENT of pblk               (High memory)  
;*********************************************************************************************************

_OSFPSave    PROC   FAR
;
             PUSH   BP                              ; Save work registers
             MOV    BP,SP
             PUSH   ES                              
             PUSH   BX
;
             LES    BX, DWORD PTR [BP+6]            ; Point to 'pblk'
;
             FSAVE  ES:[BX]                         ; Save FPU context
;
             POP    BX                              ; Restore work registers
             POP    ES
             POP    BP
;
             RET                                    ; Return to caller
;
_OSFPSave    ENDP

             PAGE                                   ; /*$PAGE*/
;*********************************************************************************************************
;                                            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  PROC   FAR
;
            PUSHA                                   ; Save interrupted task's context
            PUSH   ES
            PUSH   DS
;
            MOV    AX, SEG(_OSIntNesting)           ; Reload DS
            MOV    DS, AX
            INC    BYTE PTR DS:_OSIntNesting        ; Notify uC/OS-II of ISR
;
            CMP    BYTE PTR DS:_OSIntNesting, 1        ; if (OSIntNesting == 1)
            JNE    SHORT _OSTickISR1             
            MOV    AX, SEG(_OSTCBCur)               ;     Reload DS
            MOV    DS, AX
            LES    BX, DWORD PTR DS:_OSTCBCur       ;     OSTCBCur->OSTCBStkPtr = SS:SP
            MOV    ES:[BX+2], SS                    ;
            MOV    ES:[BX+0], SP                    ;
;
_OSTickISR1:
            MOV    AX, SEG(_OSTickDOSCtr)           ; Reload DS
            MOV    DS, AX
            DEC    BYTE PTR DS:_OSTickDOSCtr
            CMP    BYTE PTR DS:_OSTickDOSCtr, 0
            JNE    SHORT _OSTickISR2                ; Every 11 ticks (~199.99 Hz), chain into DOS
;
            MOV    BYTE PTR DS:_OSTickDOSCtr, 11
            INT    081H                             ; Chain into DOS's tick ISR
            JMP    SHORT _OSTickISR3

_OSTickISR2:
            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   FAR PTR _OSTimeTick              ; Process system tick
;
            CALL   FAR PTR _OSIntExit               ; Notify uC/OS-II of end of ISR
;
            POP    DS                               ; Restore interrupted task's context
            POP    ES
            POPA
;
            IRET                                    ; Return to interrupted task
;
_OSTickISR  ENDP
;
            END

uC/OS-II汇编代码的更多相关文章

  1. uC/OS II原理分析及源码阅读(一)

    uC/OS II(Micro Control Operation System Two)是一个可以基于ROM运行的.可裁减的.抢占式.实时多任务内核,具有高度可移植性,特别适合于微处理器和控制器,是和 ...

  2. 【原创】uC/OS II 任务切换原理

    今天学习了uC/OS II的任务切换,知道要实现任务的切换,要将原先任务的寄存器压入任务堆栈,再将新任务中任务堆栈的寄存器内容弹出到CPU的寄存器,其中的CS.IP寄存器没有出栈和入栈指令,所以只能引 ...

  3. 【小梅哥SOPC学习笔记】NIOS II处理器运行UC/OS II

    SOPC开发流程之NIOS II 处理器运行 UC/OS II 这里以在芯航线FPGA学习套件的核心板上搭建 NIOS II 软核并运行 UCOS II操作系统为例介绍SOPC的开发流程. 第一步:建 ...

  4. uC/OS II 函数说明 之–OSTaskCreate()与OSTaskCreateExt()

    1. OSTaskCreate()    OSTaskCreate()建立一个新任务,能够在多任务环境启动之前,或者执行任务中建立任务.注意,ISR中禁止建立任务,一个任务必须为无限循环结构.    ...

  5. uc/os iii移植到STM32F4---IAR开发环境

    也许是先入为主的原因,时钟用不惯Keil环境,大多数的教程都是拿keil写的,尝试将官方的uc/os iii 移植到IAR环境. 1.首先尝试从官网上下载的官方移植的代码,编译通过,但是执行会报堆栈溢 ...

  6. 关于uC/OS的简单学习(转)

    1.微内核 与Linux的首要区别是,它是一个微内核,内核所实现的功能非常简单,主要包括: 一些通用函数,如TaskCreate(),OSMutexPend(),OSQPost()等. 中断处理函数, ...

  7. uC/OS 的任务调度解析 (转)

    uC/OS 的任务调度解析 1.任务调度器启动之后(初始化,主要是TCB的初始化),就可以创建任务,开始任务调度了,实际上第一个任务准确的说不是进行任务切换,而是进行启动当前最高优先级任务.uC/OS ...

  8. 分析一个C语言程序生成的汇编代码-《Linux内核分析》Week1作业

    署名信息 郭春阳 原创作品转载请注明出处 :<Linux内核分析>MOOC课程 http://mooc.study.163.com/course/USTC-1000029000 C源码 这 ...

  9. GCC 嵌入汇编代码

    The format of basic inline assembly is very much straight forward. Its basic form is 基本汇编嵌入格式如下: asm ...

随机推荐

  1. Android几种打开SQLite的方法

    第一种:用SQLiteOpenHelper辅助类 SQLiteOpenHelper类可以用来创建或打开数据库,两个关键的方法:onCreate(SQLiteDatabase db)和onUpgrade ...

  2. java web 100个知识点

    http://wenku.baidu.com/link?url=ns5SvKesJSLzpcTckBKsFopqgbC6O0XBuVBS1BZwtJbK1P-aYbNV3fVOU9lYTbGQwKYK ...

  3. Java网络编程——UDP实例

    UDPSendDemo import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamRea ...

  4. ASP.NET利用WINRar实现在线解压缩文件

    一.肯定是服务器必须装了winrar这个软件了. 二.创建Helper类,如下: using System; using System.Collections.Generic; using Syste ...

  5. Mybatis学习--Mapper.xml映射文件

    简介 Mapper.xml映射文件中定义了操作数据库的sql,每个sql是一个statement,映射文件是mybatis的核心. 映射文件中有很多属性,常用的就是parameterType(输入类型 ...

  6. ETL利器Kettle实战应用解析系列一【Kettle使用介绍】

    本系列文章主要索引如下: 一.ETL利器Kettle实战应用解析系列一[Kettle使用介绍] 二.ETL利器Kettle实战应用解析系列二 [应用场景和实战DEMO下载] 三.ETL利器Kettle ...

  7. Region Representaion and Description

    两类特征 外部特征(external characteristics), 如boundary 内部特征(internal characteristics), 如像素, color, texture. ...

  8. HTTP协议学习---(十)拓展-HTTPS协议

    HTTPS(Hypertext Transfer Protocol over Secure Socket Layer,基于SSL的HTTP协议)使用了HTTP协议,但HTTPS使用不同于HTTP协议的 ...

  9. 【CCCC天梯赛决赛】

    cccc的天梯赛决赛,水题一样的水,中档题以上的还是没做出来.补了一下题,觉得其实也不是很难,主要是练的少. L2-1:红色预警 并查集 我做的时候想不到并查集,想到了也不一定做的出来,都是其实不难. ...

  10. 【Codeforces-707D】Persistent Bookcase DFS + 线段树

    D. Persistent Bookcase Recently in school Alina has learned what are the persistent data structures: ...