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

📄 dtos.asm

📁 我自己编写的一个保护模式下实现任务切换的系统软件
💻 ASM
📖 第 1 页 / 共 4 页
字号:
                mov     gs,ax                     ;把演示任务LDT选择子填入TSS
                mov     WORD PTR gs:DemoTaskSS.TRLDTR,DemoLDT_Sel
                mov     ax,DemoTSS_Sel
                ltr     ax                        ;装载TR
                mov     ax,DemoData_Sel
                mov     ds,ax                     ;装载其它数据段寄存器
                mov     ax,VideoBuf_Sel
                mov     es,ax
                mov     ax,XBuffer_Sel
                mov     fs,ax
                mov     ax,EchoData_Sel
                mov     gs,ax


              MOV       DX,28BH  ;写8255的控制字
              MOV       AL,80H    
              OUT       DX, AL         ;用A口输出
              MOV      BYTE PTR fs:NOW,01H
             JUMP16  DispTSS_Sel,0   ;开始电梯在1楼,数码

             MOV       DX,288H
              MOV       AL,00H
              OUT       DX,AL       ;流水灯全灭
                  
              in     al,imregp
              mov    savemask,al
              CLTS

;                mov     al,11111110b              ;置中断屏蔽字
;                out     IMREGP,al                 ;只开发时钟中断
;                sti                               ;开中断
;DemoConti:      cmp     BYTE PTR FS:Flag,0           ;判标志
;                jz      DemoConti                 ;直到不为0
;                mov      al,0ffh
;                out     IMREGP,al                 ;只开发时钟中断

                cli                               ;关中断

 choose:
                int     0ffh                      ;接收要模拟的异常类型号
                mov     al,BYTE PTR fs:KeyASCII   ;按接收的字符模拟异常号
                cmp     al,'Q'
                jnz     YY
                jmp     Over
              
  YY:           CMP       AL,'R'
              JNZ         LL
              MOV       BL,BYTE PTR fs:NUM2   ;若键入R 将num2的值赋给 num1
              MOV       BYTE PTR fs:NUM1,BL   ;并将num2置0
              MOV       AL,0
              MOV       BYTE PTR fs:NUM2,AL   
             JMP   LOP1
              
  LL:            SUB       AL,30H        
              MOV       BYTE PTR fs:NUM1,AL   ;将键入希望到达楼层数保存在 num1中
              CMP       BYTE PTR fs:NOW,AL        
              JZ        choose
           JUMP16  LedTSS_Sel,0   ;开始电梯在1楼,数码
          CLTS

waitrun:
                int     0ffh                      ;接收要模拟的异常类型号
                mov     al,BYTE PTR fs:KeyASCII   ;按接收的字符模拟异常号
          
              CMP       AL,'R'
              JNZ       waitrun        


  LOP1:            MOV       AL,BYTE PTR fs:NUM1     
              CMP       AL,BYTE PTR fs:NOW    ;希望到达层数与电梯所在层比较
              JA            UP0         ;若大则上升
              JB             DOWN0   ;若小则下降

 UP0:
               int     0fdh                      ;接收要模拟的异常类型号
                mov     al,BYTE PTR fs:KeyASCII   ;按接收的字符模拟异常号

               and  al,al
               JZ   UP1
               SUB AL,30H
               MOV BYTE PTR fs:NUM2,AL
              JUMP16  LedTSS_Sel,0   ;开始电梯在1楼,数码

             CMP       BYTE PTR fs:NUM1,AL     ;第一、二次希望到达层数比较
              JB         UP1          ;第一次小则电梯继续上升
              CMP       BYTE PTR fs:NOW,AL      ;电梯所在层与第二次希望到达层比较
              JA        UP1           ;所在层大则电梯继续上升
              MOV       BL,BYTE PTR fs:NUM1    ;第二次希望到达层在所在层和第一次希望到达
              MOV       BYTE PTR fs:NUM2,BL    ;层之间则交换num1和num2的值后继续上升
              MOV       BYTE PTR fs:NUM1,AL
           
    
 UP1:
           ;  CALL      TIME      ;两秒延时



                mov     al,11111110b              ;置中断屏蔽字
                out     IMREGP,al
                ; mov   byte ptr gs:messdata, '2'       ;只开发时钟中断
;                mov     byte ptr fs:flag,0
                sti                               ;开中断
DemoConti1:      cmp     BYTE PTR FS:Flag,0           ;判标志
                jz      DemoConti1                 ;直到不为0
                mov      al,0ffh
                out     IMREGP,al                 ;只开发时钟中断


                cli                               ;关中断

             INC       BYTE PTR fs:NOW        ;now自增
             JUMP16  DispTSS_Sel,0   ;开始电梯在1楼,数码
             CLTS
              MOV       AL,BYTE PTR fs:NUM1
              CMP       BYTE PTR fs:NOW,AL     ;判断是否达到希望到达层
              JB        UP0          ;还没有则继续上升
              MOV       AL,0        ;到达的话num1清0使对应流水灯熄灭
              MOV       BYTE PTR fs:NUM1,AL
               JUMP16  LedTSS_Sel,0   ;开始电梯在1楼,数码
              CLTS
              JMP       choose      ;返回程序起点

DOWN0:
               int     0fdh                      ;接收要模拟的异常类型号
                mov     al,BYTE PTR fs:KeyASCII   ;按接收的字符模拟异常号
               and  al,al
               JZ   DOWN1
               SUB AL,30H
               MOV NUM2,AL
              JUMP16  LedTSS_Sel,0   ;
                     CALL      TIME      ;两秒延时
                 
               CMP       BYTE PTR fs:NUM1,AL     ;第一、二次希望到达层数比较
              JA        DOWN1         ;第一次大则电梯继续下降
              CMP       BYTE PTR fs:NOW,AL      ;电梯所在层与第二次希望到达层比较
              JB        DOWN1       ;所在层小则电梯继续上升
              MOV       BL,BYTE PTR fs:NUM1    ;第二次希望到达层在所在层和第一次希望到达
              MOV       BYTE PTR fs:NUM2,BL     ;层之间则交换num1和num2的值后继续下降
              MOV       BYTE PTR fs:NUM1,AL

DOWN1:
                  CALL      TIME      ;两秒延时
                   DEC      BYTE PTR fs:NOW       ;now自减
                  JUMP16  DispTSS_Sel,0   ;开始电梯在1楼,数码管显示
                   CLTS
                   MOV       AL,BYTE PTR fs:NUM1
                   CMP       BYTE PTR fs:NOW,AL    ;判断是否达到希望到达层
                    JA        DOWN0      ;还没有则继续下降
                   MOV       AL,0
                    MOV       BYTE PTR fs:NUM1,AL   ;到达的话num1清0使对应流水灯熄灭
                   JUMP16  LedTSS_Sel,0   ;开始电梯在1楼,数码
                    JMP      choose       ;返回程序起点

TIME    PROC       NEAR        ;2秒延时子程序
              PUSH  CX
              PUSH  DI
              mov   cx,0FFFFH           
de1:        mov   di,9000        
de0:        dec   di                
               jnz   de0             
               loop  de1
              POP  DI 
              POP  CX
              RET
TIME  ENDP


Over:
                mov  al,savemask
                out  imregp,al  
                ;转临时代码段
                JUMP16  TempCode_Sel,<OFFSET ToDos>
DemoBegin       ENDP
;----------------------------------------------------------------------------
DemoCodeLen     =       $
DemoCodeSeg     ENDS
;----------------------------------------------------------------------------
TempCodeSeg     SEGMENT PARA USE16                ;临时任务的代码段
                ASSUME  CS:TempCodeSeg
;----------------------------------------------------------------------------
Virtual         PROC    FAR
                JUMP16  DemoCode_Sel,DemoBegin    ;转演示任务
ToDos:          mov     ax,Normal_Sel             ;恢复实方式段描述符高速缓存
                mov     ds,ax
                mov     es,ax
                mov     fs,ax
                mov     gs,ax
                mov     ss,ax
                mov     eax,cr0                   ;准备返回实模式
                and     al,11111110b
                mov     cr0,eax
                JUMP16  <SEG Real>,<OFFSET Real>
Virtual         ENDP
;----------------------------------------------------------------------------
TempCodeSeg     ENDS
;============================================================================
RDataSeg        SEGMENT PARA USE16                ;实方式数据段
VGDTR           PDesc   <GDTLen-1,>               ;GDT伪描述符
VIDTR           PDesc   <IDTLen-1,>               ;IDT伪描述符
NORVIDTR        PDesc   <3ffh,>                   ;用于保存原IDTR值
SPVar           DW      ?                         ;用于保存实方式下的SP
SSVar           DW      ?                         ;用于保存实方式下的SS
MESS            DB        0AH,0DH,'Press 1-8 to reach your desired the floor'
                DB        0AH,0DH,'Press Q to quit  '
                DB        0AH,0DH,'Press R to run '
                DB        0AH,0DH,'$'

RDataSeg        ENDS
;----------------------------------------------------------------------------
RCodeSeg        SEGMENT PARA USE16                ;实方式代码段
                ASSUME  CS:RCodeSeg,DS:RDataSeg
;---------------------------------------------------------------------------,
Start           PROC
                mov     ax,RDataSeg
                mov     ds,ax
                cld
                call    InitGDT                   ;初始化全局描述符表GDT
                call    InitIDT                   ;初始化中断描述符表IDT
                mov     ax,GKeyLDTSeg
                mov     fs,ax
                mov     cx,GKeyLDNum
                mov     si,OFFSET GLDT
                CALL    InitLDT

                mov     ax,KeyLDTSeg
                mov     fs,ax
                mov     cx,KeyLDNum
                mov     si,OFFSET KLDT
                CALL    InitLDT


              mov     ax,DispLDTSeg
                mov     fs,ax
                mov     cx,DispLDNum
                mov     si,OFFSET DiLDT
                CALL    InitLDT

              mov     ax,LedLDTSeg
                mov     fs,ax
                mov     cx,LedLDNum
                mov     si,OFFSET LeLDT
                CALL    InitLDT

                mov     ax,DemoLDTSeg
                mov     fs,ax
                mov     cx,DemoLDNum
                mov     si,OFFSET DLDT
                CALL    InitLDT
                mov     SSVar,ss                  ;保存堆栈指针
                mov     SPVar,sp
                lgdt    QWORD PTR VGDTR           ;装载GDTR
                sidt    QWORD PTR NORVIDTR        ;保存IDTR
                cli                               ;关中断
                lidt    QWORD PTR VIDTR           ;装载IDTR
                mov     eax,cr0
                or      al,1
                mov     cr0,eax
                JUMP16  <TempCode_Sel>,<OFFSET Virtual>
Real:           mov     ax,RDataSeg
                mov     ds,ax
                lss     sp,DWORD PTR SPVar        ;又回到实方式
                lidt    QWORD PTR NORVIDTR
                sti
                mov     ax,4c00h
                int     21h
Start           ENDP
;-------------------------------------,--------------------------------------
InitGDT         PROC
                push    ds
                mov     ax,GDTSeg
                mov     ds,ax
                mov     cx,GDNum
                mov     si,OFFSET EFFGDT
InitG:          mov     ax,[si].BaseL
                movzx   eax,ax
                shl     eax,4
                shld    edx,eax,16
                mov     WORD PTR [si].BaseL,ax
                mov     BYTE PTR [si].BaseM,dl
                mov     BYTE PTR [si].BaseH,dh
                add     si,SIZE Desc
                loop    InitG
                pop     ds
                mov     bx,16
                mov     ax,GDTSeg
                mul     bx
                mov     WORD PTR VGDTR.Base,ax
                mov     WORD PTR VGDTR.Base+2,dx
                ret
InitGDT         ENDP
;----------------------------------------------------------------------------
InitIDT         PROC
                mov     bx,16
                mov     ax,IDTSeg
                mul     bx
                mov     WORD PTR VIDTR.Base,ax
                mov     WORD PTR VIDTR.Base+2,dx
                ret
InitIDT         ENDP
;-,---------------------------------------------,----------------------------
;入口参数:FS:SI=第一个要初始化的描述符,CX=要初始化的描述符数
;----------------------------------,-----------------------------------------
InitLDT         PROC
ILDT:           mov     ax,WORD PTR FS:[si].BaseL
                movzx   eax,ax
                shl     eax,4
                shld    edx,eax,16
                mov     WORD PTR fs:[si].BaseL,ax
                mov     BYTE PTR fs:[si].BaseM,dl
                mov     BYTE PTR fs:[si].BaseH,dh
                add     si,SIZE Desc
                loop    ILDT
                ret
InitLDT         ENDP
;----------------------------------------------------------------------------
RCodeSeg        ENDS
                END     Start

⌨️ 快捷键说明

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