📄 p_os.asm
字号:
;中文操作系统,演示中断系统,汉字显示,任务切换功能与分页模式。
;By 潘龙平/nuaa/08990115
;Date:6/18/2002
;显示模式为800*600 16色
;包含文件有:P_BASE_DEF.ASM,P_USER_1.ASM,INITLDT.ASM
; P_2.ASM,P_INT_SEV1.ASM
;其他用到的文件有 D:\HZK16,D:\FENBIN
;===============================================================
.MODEL HUGE
.386P
INCLUDE P_BASE.ASM
REAL_STACK SEGMENT STACK PARA 'STACK'
DB 200H DUP(0)
REAL_STACK_LEN EQU $
REAL_STACK ENDS
REAL_DATA SEGMENT
SAVE_GDT DW 4 DUP(0)
SAVE_IDT DW 4 DUP(0)
SAVE_SS DW 0
SAVE_SP DW 0
GDT_SIZE DW 0
GDT_ADDR DW 0,0
IDT_SIZE DW 0
IDT_ADDR DW 0,0
USER1_LDT_SIZE DW 0
USER1_LDT_ADDR DW 0,0
C_BUF_SIZE DW 0 ;读汉字库文件时用
G_BUF_SUM DD 0
C_BUFFER DB 1024 DUP(?)
HZKNAME DB 'D:\HZK16',0 ;汉字库文件
HZK_HANDLE DW 0 ;汉字库文件的句柄
HZK_OVER DB 0 ;读汉字库文件已结束
ERR_OPEN_HZK DB 'Can not open the file Chinese fonts file$',0
;打开汉字库文件出错信息
OK_MSG DB 0DH,0AH,'HAVE RETURNED TO DOS,HAVE A NICE DAY,BYE!$'
REAL_DATA_LEN EQU $
REAL_DATA ENDS
REAL_CODE SEGMENT WORD PUBLIC 'CODE'
ASSUME CS:REAL_CODE,DS:REAL_DATA,SS:REAL_STACK
START:
MOV AX,REAL_DATA
MOV DS,AX
CLI
MOV AX,REAL_STACK
MOV SS,AX
MOV AX,REAL_STACK_LEN
MOV SP,AX
MOV AX,OS_DATA
MOV DS,AX
MOV ES,AX
MOV CX,6400 ;加载图片到内存ES:SI
MOV SI,OFFSET OS_BMPBUF
MOV DX,OFFSET OS_BMPNAME
CALL LOAD_PIC
CMP AL,0
JZ LBL_LOAD_PIC_SUC
MOV AH,9
MOV DX,OFFSET LOAD_BMP_ERR
INT 21H
MOV AH,4CH ;退出程序
INT 21H
LBL_LOAD_PIC_SUC:
MOV AX,1130H ;将字符集移到OS_DATA开始处
MOV BH,6
INT 10H ;取得字符集的地址ES:BP
MOV CX,2048
MOV DI,0
MOVE_CHAR_SET:
MOV AL,ES:[BP]
MOV DS:[DI],AL
INC DI
INC BP
LOOP MOVE_CHAR_SET
MOV AX,REAL_DATA
MOV DS,AX
MOV ES,AX
CALL INIT_IDT ;初始化中断描述符表
CALL INIT_GDT ;初始化全局描述符表
CALL INIT_LDT ;初始化局部描述符表
MOV AX,4F02H ;进入600*800 16色模式
MOV BX,102H
INT 10H
;//////////////////////////////
;读汉字库文件到高端内存4M处
MOV AH,3DH
MOV DX,OFFSET HZKNAME
MOV AL,0
INT 21H
JNC LBL_OPEN_HZK_SUC
MOV AX,3
INT 10H
MOV AH,9 ;打开汉字库文件出错
MOV DX,OFFSET ERR_OPEN_HZK
INT 21H
MOV AH,4CH ;退出程序
INT 21H
LBL_OPEN_HZK_SUC:
MOV DS:HZK_HANDLE,AX
READ_HZK:
MOV DS:SAVE_SS,SS
MOV DS:SAVE_SP,SP
SGDT FWORD PTR SAVE_GDT
SGDT FWORD PTR SAVE_GDT
MOV BX,DS:HZK_HANDLE
MOV CX,1024
MOV DX,OFFSET C_BUFFER
MOV AH,3FH
INT 21H
JNC READ_HZK1
MOV AX,0
MOV DS:C_BUF_SIZE,AX
MOV DS:HZK_OVER,1 ;文件已读完
MOV AH,3EH
INT 21H ;关闭汉字库文件
JMP PROTECT_MODE
READ_HZK1:
MOV DS:C_BUF_SIZE,AX ;AX为读出的实际长度
CMP AX,1024
JNL PROTECT_MODE
MOV DS:HZK_OVER,1 ;文件已读完
MOV BX,DS:HZK_HANDLE
MOV AH,3EH
INT 21H ;关闭汉字库文件
PROTECT_MODE:
MOV AX,REAL_DATA
MOV DS,AX
MOV AX,REAL_STACK
MOV SAVE_SS,AX
MOV SAVE_SP,SP
SGDT FWORD PTR SAVE_GDT
SIDT FWORD PTR SAVE_IDT
CLI
LGDT FWORD PTR GDT_SIZE
LIDT FWORD PTR IDT_SIZE
OPEN_A20
MOV EAX,CR0
OR EAX,1
MOV CR0,EAX
JMP ENTER_PROTECT1
ENTER_PROTECT1:
DB 0EAH
DW OFFSET ENTER_PROTECT2
DW REAL_CODE_SEL
ENTER_PROTECT2:
MOV AX,REAL_DATA_SEL
MOV FS,AX
MOV AX,HZK_BUF_SEL
MOV GS,AX
CMP FS:C_BUF_SIZE,0
JE REAL_MODE
MOV ECX,0
MOV CX,FS:C_BUF_SIZE
MOV EAX,OFFSET C_BUFFER
MOV ESI,EAX
MOV EDI,FS:G_BUF_SUM
MOVE_BUF1:
MOV AL,FS:[ESI]
MOV GS:[EDI],AL
INC EDI
INC ESI
LOOP MOVE_BUF1
MOV FS:G_BUF_SUM,EDI
REAL_MODE:
CLI
MOV EAX,CR0
AND EAX,0FFFFFFFEH
MOV CR0,EAX
JMP ENTER_REAL1
ENTER_REAL1:
DB 0EAH
DW OFFSET ENTER_REAL2
DW REAL_CODE
ENTER_REAL2:
CLOSE_A20
MOV AX,REAL_DATA
MOV DS,AX
LGDT FWORD PTR SAVE_GDT
LIDT FWORD PTR SAVE_IDT
CLI
MOV SS,SAVE_SS
MOV SP,SAVE_SP
STI
CMP DS:HZK_OVER,1
JNE READ_HZK ;继续读汉字库文件
;读汉字库结束
;///////////////////////////////
TURN_TO_PROTECT ;转入保护模式,进入操作系统
LBL_TO_REAL:
RETURN_TO_REAL_1 ;从操作系统返回实模式
MOV AX,3
INT 10H
LEA DX,OK_MSG ;显示返回提示信息
MOV CX,0C00H
MOV AH,9
INT 21H
MOV AH,4CH ;结束程序,返回DOS
INT 21H
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
;****************INIT_IDT开始********************
INIT_IDT PROC FAR ;初始化 IDT
PUSH DS
MOV AX,IDT_SEG
MOV DS,AX
MOV DI,OFFSET IDT21
MOV AX,OFFSET SERVE_INT21
MOV DS:[DI].STRUCT_GATE.OFFSET_L,AX
POP DS
XOR DX,DX
MOV CX,16
MOV AX,IDT_SEG
MUL CX
ADC DX,0
MOV IDT_SIZE,IDT_LEN
MOV IDT_ADDR,AX
MOV IDT_ADDR+2,DX
RET
INIT_IDT ENDP
;++++++++++++++++INIT_IDT结束+++++++++++++++++++
;---------------------------------------------------------------
;****************INIT_GDT开始********************
INIT_GDT PROC FAR ;初始化 GDT
PUSH DS
MOV AX,GDT_SEG
MOV DS,AX
MOV SI,OFFSET GDT_INIT_BEGIN
MOV CX,GDT_INIT_COUNT
INIT_GDT_LBL1:
MOV AX,[SI].STRUCT_SEG.BASE_L
MOVZX EAX,AX
SHL EAX,4
SHLD EDX,EAX,16
MOV [SI].STRUCT_SEG.BASE_L,AX
MOV [SI].STRUCT_SEG.BASE_M,DL
MOV [SI].STRUCT_SEG.BASE_H,DH
ADD SI,SIZE STRUCT_SEG
LOOP INIT_GDT_LBL1
POP DS
XOR DX,DX
MOV CX,16
MOV AX,GDT_SEG
MUL CX
MOV GDT_SIZE,GDT_LEN
MOV GDT_ADDR,AX
MOV GDT_ADDR+2,DX
RET
INIT_GDT ENDP
;++++++++++++++++INIT_GDT结束+++++++++++++++++++
;加载图片到内存ES:SI
;DS:DX图片名称(包括路径)
;CX读的字节数
;如果成功则AX=0,否则AX=-1
LOAD_PIC PROC FAR
PUSH DS
PUSH CX
PUSH DX
MOV AH,3DH
MOV AL,0
INT 21H
JC LOAD_PIC_FAILED
PUSH ES
POP DS
MOV DX,SI
MOV BX,AX
MOV AH,3FH
INT 21H
JC LOAD_PIC_FAILED
MOV AH,3EH
INT 21H
JC LOAD_PIC_FAILED
MOV AX,0
JMP LOAD_PIC_EXIT
LOAD_PIC_FAILED:
MOV AX,0FFH
LOAD_PIC_EXIT:
POP DX
POP CX
POP DS
RET
LOAD_PIC ENDP
INCLUDE INITLDT.ASM ;;初始化局部描述符表的过程
REAL_CODE ENDS
;**************保护模式下的堆栈段开始*************
OS_STACK SEGMENT STACK PARA USE16
DB 4096 DUP(0)
OS_STACK_LEN EQU $
OS_STACK ENDS
;++++++++++++++保护模式下的堆栈段结束+++++++++++++++
;---------------------------------------------------------------
;**************保护模式下的数据段开始***************
OS_DATA SEGMENT PARA USE16
ASC_CHAR DB 2048 DUP(0) ;英文字符集
V_GDT_SIZE DW GDT_LEN ;分页时的GDT大小
V_GDT_ADDR DW 0,0 ;分页时的GDT地址
V_IDT_SIZE DW IDT_LEN ;分页时的IDT大小
V_IDT_ADDR DW 0,0 ;分页时的IDT地址
P_GDT_SIZE DW 0 ;分页前保存的GDT大小
P_GDT_ADDR DW 0,0 ;分页前保存的GDT地址
P_IDT_SIZE DW 0 ;分页前保存的IDT大小
P_IDT_ADDR DW 0,0 ;分页前保存的IDT地址
OS_CODE_ADDR DD 0
OS_STACK_ADDR DD 0
OS_DATA_ADDR DD 0
OS_BMPNAME DB 'D:\FENBIN',0 ;位图文件
OS_BMPBUF DB 6400 DUP(?) ;位图的缓冲区
LOAD_BMP_ERR DB 'Can not Open the BMP file!$'
;打开BMP文件出错信息
msg db '中',0
MSG1_1 DB '您好,欢迎使用中文操作系统',0
MSG1_2 DB '您正在保护方式下调用21H中断来清屏与显示字符串',0
MSG1_3 DB '请按 A 键进入系统的一个任务。',0
USER1_MSG_1 DB '您已经从操作系统切换到任务1。',0
USER1_MSG_2 DB '请按 S 键返回操作系统,并进入分页模式。',0
MSG2_1 DB '您已经进入了分页模式',0
MSG2_2 DB '您正在分页模式下调用中断处理程序',0
MSG2_3 DB '请按 D 键关闭分页模式,返回系统。',0
MSG3_1 DB '暑假快乐!',0
MSG3_2 DB '谢谢使用中文操作系统。',0
MSG3_3 DB '请按 F 键回到DOS操作系统。',0
MSG_PLP DB '作者:潘龙平/08990115',0
OS_DATA_LEN EQU $
OS_DATA ENDS
;++++++++++++++保护模式下的数据段结束+++++++++++++++++++++++++++
;---------------------------------------------------------------
;**************保护模式下的任务状态段开始***********************
OS_TSS SEGMENT PARA USE16
OS_TASK STRUCT_TSS<>
DB 0FFH
OS_TSS_LEN EQU $
OS_TSS ENDS
;++++++++++++++保护模式下的任务状态段结束+++++++++++++++++++++++
;---------------------------------------------------------------
;**************OS代码段开始*************************************
OS_CODE SEGMENT PARA USE16
ASSUME CS:OS_CODE,DS:OS_DATA,SS:OS_STACK
;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
OS_BEGIN: ;保护模式入口
INIT_PROCTECT ;初始化保护模式
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -