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

📄 dtos.asm

📁 我自己编写的一个保护模式下实现任务切换的系统软件
💻 ASM
📖 第 1 页 / 共 4 页
字号:
                ;对应0feh号中断处理程序的陷阱门描述符
                Gate    <EchoBegin,EchoCode_Sel,,AT386TGate,>
                ;0ffh号任务门描述符(对应读键盘中断处理任务)
                Gate    <,GKeyTSS_Sel,,ATTaskGate,>
;----------------------------------------------------------------------------
IDTLen          =       $-IDT
;----------------------------------------------------------------------------
IDTSeg          ENDS                              ;中断描述符表段定义结束
;----------------------------------------------------------------------------
;读键盘任务局部描述符表段

;8号中断处理程序的数据段
;----------------------------------------------------------------------------
TIDataSeg       SEGMENT PARA USE16
Count           DB      0                         ;中断发生的计数器
TIDataLen       =       $
TIDataSeg       ENDS
;----------------------------------------------------------------------------
;8号中断处理程序的代码段
;----------------------------------------------------------------------------
TICodeSeg       SEGMENT PARA USE16
                ASSUME  CS:TICodeSeg,DS:TIDataSeg
;----------------------------------------------------------------------------
TIBegin         PROC    FAR
                push    eax                       ;保护现场
                push    ds
                push    fs
                push    gs
tis:
                
                mov     ax,TIData_Sel             ;置中断处理程序数据段
                mov     ds,ax
                mov     ax,EchoData_Sel           ;置显示过程数据段
                mov     fs,ax
                mov     ax,XBuffer_Sel           ;置演示程序数据段
                mov     gs,ax
            ;    mov     byte ptr fs:messdata,'2'
                cmp     Count,0
                jnz     TI2                       ;计数非0表示未到1秒
                mov     Count,18                  ;每秒约18次
                int     0feh                      ;调用0FEH号中断处理程序显示
                cmp     BYTE PTR fs:MessData,'0'
                jnz     TI1
               mov     BYTE PTR gs:Flag,1        ;显示符号'0'时置标记
TI1:            dec     BYTE PTR fs:MessData          ;调整显示符号
TI2:            dec     Count                     ;调整计数
                pop     gs                        ;恢复现场
                pop     fs
                pop     ds
                mov     al,EOICOM                ;通知中断控制器中断处理结束
                out     ICREGP,al
                inc     byte ptr fs:MessData 
                inc     byte ptr fs:MessData
                pop     eax
                iretd                             ;中断返回
                jmp tis
TIBegin         ENDP
;----------------------------------------------------------------------------
TICodeLen       =       $
TICodeSeg       ENDS
;----------------------------------------------------------------------------

;0FEH号中断处理程序数据段
;----------------------------------------------------------------------------
EchoDataSeg     SEGMENT PARA USE16
MessData          DB      '2',4eh
EchoDataLen     =       $
EchoDataSeg     ENDS
;----------------------------------------------------------------------------
;0FEH号中断处理程序(显示程序)的代码段
;---------------------------------------------------------------,------------
EchoCodeSeg     SEGMENT PARA USE16
                ASSUME  CS:EchoCodeSeg,DS:EchoDataSeg
;----------------------------------------------------------------------------
EchoBegin       PROC    FAR
                push    ax                        ;保护现场
                push    ds
                push    es
                mov     ax,EchoData_Sel           ;置显示过程数据段
                mov     ds,ax
                mov     ax,Videobuf_Sel              ;置视频缓冲区数据段
                mov     es,ax
                mov     ax,WORD PTR MessData
                mov     WORD PTR es:[0],ax
                pop     es
                pop     ds
                pop     ax
                iretd
EchoBegin       ENDP
;----------------------------------------------------------------------------
EchoCodeLen     =       $
EchoCodeSeg     ENDS
;----------------------------------------------------------------------------

;----------------------------------------------------------------------------
GKeyLDTSeg      SEGMENT PARA USE16
;----------------------------------------------------------------------------
GLDT            LABEL   BYTE
                ;代码段描述符及选择子
GKeyCode        Desc    <0ffffh,GKeyCodeSeg,,ATCE,,>
GKeyCode_Sel    =       GKeyCode-GLDT+TIL
                ;堆栈段描述符及选择子
GKeyStack       Desc    <GKeyStackLen-1,GKeyStackSeg,,ATDWA,,>
GKeyStack_Sel   =       GKeyStack-GLDT+TIL
;----------------------------------------------------------------------------
GKeyLDNum       =       ($-GLDT)/(SIZE Desc)      ;需初始化基地址的描述符个数
GKeyLDTLen      =       $                         ;局部描述符表段长度
;----------------------------------------------------------------------------
GKeyLDTSeg      ENDS
;----------------------------------------------------------------------------
;读键盘任务TSS段
;----------------------------------------------------------------------------
GKeyTSSSeg      SEGMENT PARA USE16
                DD      0                         ;链接字
                DD      ?                         ;0级堆栈指针
                DW      ?,?
                DD      ?                         ;1级堆栈指针
                DW      ?,?
                DD      ?                         ;2级堆栈指针
                DW      ?,?
                DD      0                         ;CR3
                DW      GKeyBegin,0               ;EIP
                DD      0                         ;EFLAGS
                DD      0                         ;EAX
                DD      0                         ;ECX
                DD      0                         ;EDX
                DD      0                         ;EBX
                DW      GKeyStackLen,0            ;ESP
                DD      0                         ;EBP
                DD      0                         ;ESI
                DD      0                         ;EDI
                DW      Normal_Sel,0              ;ES
                DW      GKeyCode_Sel,0            ;CS
                DW      GKeyStack_Sel,0           ;SS
                DW      Normal_Sel,0              ;DS
                DW      Normal_Sel,0              ;FS
                DW      Normal_Sel,0              ;GS
                DW      GKeyLDT_Sel,0             ;LDTR
                DW      0                         ;调试陷阱标志
                DW      $+2                       ;指向I/O许可位图的偏移
                DB      0ffh                      ;I/O许可位图结束字节
GKeyTSSLen      =       $
GKeyTSSSeg      ENDS
;----------------------------------------------------------------------------
;读键盘任务堆栈段
;----------------------------------------------------------------------------
GKeyStackSeg    SEGMENT PARA USE16
GKeyStackLen    =       1024
                DB      GKeyStackLen DUP(0)
GKeyStackSeg    ENDS
;----------------------------------------------------------------------------
;读键盘任务代码段
;----------------------------------------------------------------------------
GKeyCodeSeg     SEGMENT PARA USE16
                ASSUME  CS:GKeyCodeSeg,DS:RDataSeg,ES:BufferSeg
;----------------------------------------------------------------------------
GKeyBegin       PROC    FAR
                push    ds
                push    es
                push    fs
                push    gs
                mov     ax,Normal_Sel
                mov     ss,ax                     ;准备转实方式
                mov     eax,cr0
                and     al,11111110b
                mov     cr0,eax                   ;转实方式
                JUMP16  <SEG GetKey>,<OFFSET GetKey>
GetKey:         mov     ax,RDataSeg               ;实方式
                mov     ds,ax
                mov     ebp,esp                   ;恢复实方式部分现场
                lss     sp,DWORD PTR SPVar
                lidt    QWORD PTR NORVIDTR
                sti
                mov     dx,OFFSET Mess
                mov     ah,9
                int     21h                       ;显示提示信息
GetKey1:
                mov      al,11111101b
                out     IMREGP,al                 ;只开发时钟中断
               
               mov     ah,0
               int     16h                       ;读键盘

                cmp     al,'1'
                jz      GetKey2
                cmp     al,'2'               
                jz      GetKey2
                cmp     al,'3'
                jz      GetKey2
                cmp     al,'4'
                jz      GetKey2
                cmp     al,'5'               
                jz      GetKey2
                cmp     al,'6'
                jz      GetKey2
                cmp     al,'7'               
                jz      GetKey2
                cmp     al,'8'
                jz      GetKey2

                and     al,11011111b              ;小写转大写
                cmp     al,'Q'
               ; jb      GetKey1
                cmp     al,'R'
              ;  ja      GetKey1                 
GetKey2:        mov     dl,al
                mov     ah,2
                int     21h                       ;显示所按字符


                mov     ax,BufferSeg
                mov     es,ax
                mov     BYTE PTR es:KeyASCII,dl   ;保存到缓冲数据段
                cli                               ;准备返回保护方式
                lidt    QWORD PTR VIDTR
                mov     eax,cr0
                or      al,1
                mov     cr0,eax
                JUMP16  <GKeyCode_Sel>,<OFFSET GetKeyV>
GetKeyV:        mov     ax,GKeyStack_Sel          ;又进入保护方式
                mov     ss,ax
                mov     esp,ebp

                pop     gs
                pop     fs
                pop     es
                pop     ds

                mov     al,EOICOM                ;通知中断控制器中断处理结束
                out     ICREGP,al

                iretd
                jmp     GKeyBegin
GKeyBegin       ENDP
;----------------------------------------------------------------------------
GKeyCodeLen     =       $
GKeyCodeSeg     ENDS
;----------------------------------------------------------------------------


;----------------------------------------------------------------------------
KeyLDTSeg      SEGMENT PARA USE16
;----------------------------------------------------------------------------
KLDT            LABEL   BYTE
                ;代码段描述符及选择子
KeyCode        Desc    <0ffffh,KeyCodeSeg,,ATCE,,>
KeyCode_Sel    =       KeyCode-KLDT+TIL
                ;堆栈段描述符及选择子
KeyStack       Desc    <KeyStackLen-1,KeyStackSeg,,ATDWA,,>
KeyStack_Sel   =       KeyStack-KLDT+TIL
;----------------------------------------------------------------------------
KeyLDNum       =       ($-KLDT)/(SIZE Desc)      ;需初始化基地址的描述符个数
KeyLDTLen      =       $                         ;局部描述符表段长度
;----------------------------------------------------------------------------
KeyLDTSeg      ENDS
;----------------------------------------------------------------------------
;读键盘任务TSS段
;----------------------------------------------------------------------------
KeyTSSSeg      SEGMENT PARA USE16
                DD      0                         ;链接字
                DD      ?                         ;0级堆栈指针
                DW      ?,?
                DD      ?                         ;1级堆栈指针
                DW      ?,?
                DD      ?                         ;2级堆栈指针
                DW      ?,?
                DD      0                         ;CR3
                DW      KeyBegin,0               ;EIP
                DD      0                         ;EFLAGS
                DD      0                         ;EAX
                DD      0                         ;ECX
                DD      0                         ;EDX
                DD      0                         ;EBX
                DW      KeyStackLen,0            ;ESP
                DD      0                         ;EBP
                DD      0                         ;ESI
                DD      0                         ;EDI
                DW      Normal_Sel,0              ;ES
                DW      KeyCode_Sel,0            ;CS
                DW      KeyStack_Sel,0           ;SS
                DW      Normal_Sel,0              ;DS
                DW      Normal_Sel,0              ;FS
                DW      Normal_Sel,0              ;GS
                DW      KeyLDT_Sel,0             ;LDTR
                DW      0                         ;调试陷阱标志
                DW      $+2                       ;指向I/O许可位图的偏移
                DB      0ffh                      ;I/O许可位图结束字节
KeyTSSLen      =       $
KeyTSSSeg      ENDS
;----------------------------------------------------------------------------
;读键盘任务堆栈段
;----------------------------------------------------------------------------
KeyStackSeg    SEGMENT PARA USE16
KeyStackLen    =       1024
                DB      KeyStackLen DUP(0)
KeyStackSeg    ENDS
;----------------------------------------------------------------------------
;读键盘任务代码段
;----------------------------------------------------------------------------
KeyCodeSeg     SEGMENT PARA USE16
                ASSUME  CS:KeyCodeSeg,DS:RdataSeg,ES:BufferSeg
;----------------------------------------------------------------------------
KeyBegin       PROC    FAR
                push    ds
                push    es
                push    fs
                push    gs
                mov     ax,Normal_Sel
                mov     ss,ax                     ;准备转实方式
                mov     eax,cr0
                and     al,11111110b
                mov     cr0,eax                   ;转实方式
                JUMP16  <SEG Key>,<OFFSET Key>
Key:            mov     ax,RDataSeg               ;实方式
                mov     ds,ax
                mov     ebp,esp                   ;恢复实方式部分现场
                lss     sp,DWORD PTR SPVar
                lidt    QWORD PTR NORVIDTR
                sti

⌨️ 快捷键说明

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