📄 dtos.asm
字号:
;对应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 + -