www.pudn.com > czxtsycx1.zip > 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 ;初始化保护模式 MOV AX,OS_DATA_SEL ;保存IDT与GDT,以便分页后恢复 MOV DS,AX SIDT FWORD PTR DS:P_IDT_SIZE SGDT FWORD PTR DS:P_GDT_SIZE ;------------------------------------------------------------------- MOV AH,2 ;用浅蓝色清屏 MOV CL,9 INT 21H MOV AH,07H MOV BX,120 MOV DX,160 MOV SI,480 MOV DI,220 MOV CH,08H MOV CL,07H INT 21H MOV AH,07H MOV BX,125 MOV DX,165 MOV SI,480-10 MOV DI,220-10 MOV CH,07H MOV CL,08H INT 21H MOV AX,OS_DATA_SEL ;显示字符串 MOV DS,AX MOV ES,AX MOV AX,0100H MOV DI,OFFSET MSG ;msg1_1 MOV BX,12 MOV DX,35 MOV CL,07H INT 21H MOV AX,OS_DATA_SEL ;显示字符串 MOV ES,AX MOV AX,0100H MOV DI,OFFSET MSG1_2 MOV BX,16 MOV DX,27 MOV CL,07H INT 21H MOV AX,OS_DATA_SEL ;显示字符串 MOV ES,AX MOV AX,0100H MOV DI,OFFSET MSG1_3 MOV BX,35 MOV DX,2 MOV CL,07H INT 21H MOV AH,7 MOV BX,16*34+4 MOV DX,8*69 MOV SI,8*26 MOV DI,40 MOV CH,08H MOV CL,0FH INT 21H MOV AX,OS_DATA_SEL ;显示字符串 MOV ES,AX MOV AX,0100H MOV DI,OFFSET MSG_PLP MOV BX,35 MOV DX,72 MOV CL,07H INT 21H MOV AX,OS_DATA_SEL MOV ES,AX MOV SI,OFFSET OS_BMPBUF MOV AH,5 MOV BX,16*19 MOV DX,8*50 MOV BP,80 MOV CX,80 INT 21H ;------------------------------------------------------------------- LBL_WAIT_A: ;等待按A键 IN AL,60H CMP AL,1EH JNZ LBL_WAIT_A DB 0EAH ;切换到任务1 DW 0 DW USER1_TSS_SEL LBL_BACK_TO_OS: ;////////////////////////////////////////////////////////// ;为分页做准备 MOV AX,OS_TSS_ASDATA_SEL MOV DS,AX MOV EAX,GDT_PDT_ADDR MOV DS:STRUCT_TSS.TSS_CR3,EAX CALL V_SEL_SETUP ;初始化一些分页用的段描述符 CALL SEGS_MOV_2M ;将OS段移到2M处 CALL INIT_PDT ;初始化PDT MOV AX,OS_DATA_SEL MOV DS,AX MOV WORD PTR DS:V_IDT_ADDR,0 MOV WORD PTR DS:V_IDT_ADDR+2,20H LIDT FWORD PTR DS:V_IDT_SIZE MOV WORD PTR DS:V_GDT_ADDR,2000H MOV WORD PTR DS:V_GDT_ADDR+2,20H LGDT FWORD PTR DS:V_GDT_SIZE MOV EAX,GDT_PDT_ADDR MOV CR3,EAX ;设置页目录表的地址 MOV EAX,CR0 ;启动分页 OR EAX,80000000H MOV CR0,EAX JMP SHORT PAGE_BEGIN PAGE_BEGIN: DB 0EAH ;进入分页模式 DW OFFSET V_OS_CODE_BEGIN DW V_OS_CODE_SEL V_OS_CODE_BEGIN: MOV AX,V_OS_DATA_SEL MOV DS,AX MOV AX,V_OS_STACK_SEL MOV SS,AX MOV AX,V_OS_TSS_SEL LTR AX ;------------------------------------------------------------------- ;------------------------------------------------------------------- MOV AH,2 ;用浅蓝色清屏 MOV CL,9 INT 21H MOV AH,07H ;显示矩形框 MOV BX,130 MOV DX,200 MOV SI,400 MOV DI,200 MOV CH,08H MOV CL,07H INT 21H MOV AH,07H ;显示矩形框 MOV BX,135 MOV DX,205 MOV SI,400-10 MOV DI,200-10 MOV CH,07H MOV CL,08H INT 21H MOV AX,V_OS_DATA_SEL ;显示字符串 MOV DS,AX MOV ES,AX MOV AX,0100H MOV DI,OFFSET MSG2_1 MOV BX,12 MOV DX,40 MOV CL,07H INT 21H MOV AX,V_OS_DATA_SEL ;显示字符串 MOV ES,AX MOV AX,0100H MOV DI,OFFSET MSG2_2 MOV BX,16 MOV DX,35 MOV CL,07H INT 21H MOV AX,V_OS_DATA_SEL ;显示字符串 MOV ES,AX MOV AX,0100H MOV DI,OFFSET MSG2_3 MOV BX,35 MOV DX,2 MOV CL,07H INT 21H MOV AH,7 ;显示矩形框 MOV BX,16*34+4 MOV DX,8*69 MOV SI,8*26 MOV DI,40 MOV CH,08H MOV CL,0FH INT 21H MOV AX,V_OS_DATA_SEL ;显示字符串 MOV ES,AX MOV AX,0100H MOV DI,OFFSET MSG_PLP MOV BX,35 MOV DX,72 MOV CL,07H INT 21H LBL_WAIT_D: ;等待按D键 IN AL,60H CMP AL,20H JNZ LBL_WAIT_D ;------------------------------------------------------------------ MOV AH,2 ;用浅蓝色清屏 MOV CL,9 INT 21H MOV AH,07H ;显示矩形框 MOV BX,130 MOV DX,200 MOV SI,400 MOV DI,200 MOV CH,07H MOV CL,08H INT 21H MOV AH,07H ;显示矩形框 MOV BX,135 MOV DX,205 MOV SI,400-10 MOV DI,200-10 MOV CH,08H MOV CL,07H INT 21H MOV AX,V_OS_DATA_SEL ;显示字符串 MOV DS,AX MOV ES,AX MOV AX,0100H MOV DI,OFFSET MSG3_1 MOV BX,12 MOV DX,45 MOV CL,07H INT 21H MOV AX,V_OS_DATA_SEL ;显示字符串 MOV ES,AX MOV AX,0100H MOV DI,OFFSET MSG3_2 MOV BX,16 MOV DX,40 MOV CL,07H INT 21H MOV AX,V_OS_DATA_SEL ;显示字符串 MOV ES,AX MOV AX,0100H MOV DI,OFFSET MSG3_3 MOV BX,35 MOV DX,2 MOV CL,07H INT 21H MOV AH,7 ;显示矩形框 MOV BX,16*34+4 MOV DX,8*69 MOV SI,8*26 MOV DI,40 MOV CH,08H MOV CL,0FH INT 21H MOV AX,V_OS_DATA_SEL ;显示字符串 MOV ES,AX MOV AX,0100H MOV DI,OFFSET MSG_PLP MOV BX,35 MOV DX,72 MOV CL,07H INT 21H LBL_WAIT_F: ;等待按F键 IN AL,60H CMP AL,21H JNZ LBL_WAIT_F ;------------------------------------------------------------------ MOV AX,V_OS_DATA_SEL MOV DS,AX LIDT FWORD PTR DS:P_IDT_SIZE LGDT FWORD PTR DS:P_GDT_SIZE DB 0EAH DW OFFSET PAGE_END DW OS_CODE_SEL PAGE_END: MOV EAX,CR0 AND EAX,7FFFFFFFH MOV CR0,EAX ;关闭分页 JMP SHORT FROM_PAGE FROM_PAGE: ;分页结束 ;//////////////////////////////////////////////////////// TURN_TO_REAL ;返回到实模式 INCLUDE P_INT.ASM INCLUDE P_2.ASM OS_CODE_LEN EQU $ OS_CODE ENDS ;++++++++++++++OS代码段结束+++++++++++++++++++++++++++++++++++++ ;--------------------------------------------------------------- ;**************中断描述符表开始********************************* IDT_SEG SEGMENT PARA USE16 IDT0 STRUCT_GATE 21H DUP(<>) IDT21 STRUCT_GATE<0,OS_CODE_SEL,0,8EH,0> IDT_LEN EQU $ IDT_SEG ENDS ;++++++++++++++中断描述符表结束+++++++++++++++++++++++++++++++++ ;--------------------------------------------------------------- ;**************全局描述符表开始********************************* GDT_SEG SEGMENT GDT_NULL STRUCT_SEG<0,0,0,0,0,0> GDT_REAL_SEG STRUCT_SEG<0FFFFH,0,0,92H,0,0> REAL_SEL EQU GDT_REAL_SEG-GDT_NULL GDT_INIT_BEGIN LABEL BYTE GDT_REAL_CODE STRUCT_SEG<0FFFFH,REAL_CODE,0,9AH,0,0> REAL_CODE_SEL EQU GDT_REAL_CODE-GDT_NULL GDT_REAL_DATA STRUCT_SEGREAL_DATA_SEL EQU GDT_REAL_DATA-GDT_NULL GDT_OS_DATA STRUCT_SEG OS_DATA_SEL EQU GDT_OS_DATA-GDT_NULL GDT_OS_CODE STRUCT_SEG<0FFFFH,OS_CODE,0,9AH,0,0> OS_CODE_SEL EQU GDT_OS_CODE-GDT_NULL GDT_OS_STACK STRUCT_SEG OS_STACK_SEL EQU GDT_OS_STACK-GDT_NULL GDT_OS_TSS STRUCT_SEG OS_TSS_SEL EQU GDT_OS_TSS-GDT_NULL GDT_IDT STRUCT_SEG GDT_IDT_SEL EQU GDT_IDT-GDT_NULL GDT_ASDATA STRUCT_SEG GDT_ASDATA_SEL EQU GDT_ASDATA-GDT_NULL OS_TSS_ASDATA STRUCT_SEG OS_TSS_ASDATA_SEL EQU OS_TSS_ASDATA-GDT_NULL GDT_USER1_TSS STRUCT_SEG USER1_TSS_SEL EQU GDT_USER1_TSS-GDT_NULL GDT_USER1_LDT STRUCT_SEG USER1_LDT_SEL EQU GDT_USER1_LDT-GDT_NULL GDT_INIT_COUNT EQU ($-GDT_INIT_BEGIN)/(SIZE STRUCT_SEG) ;***************************************************** GDT_PDT STRUCT_SEG<0FFFFH,2000H,21H,92H,0,0> GDT_PDT_SEL EQU GDT_PDT-GDT_NULL GDT_PDT0 STRUCT_SEG<0FFFFH,3000H,21H,92H,0,0> GDT_PDT0_SEL EQU GDT_PDT0-GDT_NULL GDT_MOV_SEG STRUCT_SEG<0FFFFH,0,20H,92H,0FH,0> GDT_MOV_SEL EQU GDT_MOV_SEG-GDT_NULL ;**************************************************** V_OS_CODE STRUCT_SEG<0FFFFH,3000H,42H,9AH,0,0C0H> V_OS_CODE_SEL EQU V_OS_CODE-GDT_NULL V_OS_STACK STRUCT_SEG V_OS_STACK_SEL EQU V_OS_STACK-GDT_NULL V_OS_DATA STRUCT_SEG V_OS_DATA_SEL EQU V_OS_DATA-GDT_NULL V_OS_TSS STRUCT_SEG V_OS_TSS_SEL EQU V_OS_TSS-GDT_NULL V_GDT_VRAM STRUCT_SEG<0FFFFH,0,0,92H,0,0C0H> ;图形方式显示存储区段 V_GDT_VRAM_SEL EQU GDT_VRAM-GDT_NULL GDT_VRAM STRUCT_SEG<0FFFFH,0H,0AH,92H,0,0> GDT_VRAM_SEL EQU GDT_VRAM-GDT_NULL HZK_SEG STRUCT_SEG<0FFFFH,0,40H,92H,0FH,0> ;汉字库段 HZK_BUF_SEL EQU HZK_SEG-GDT_NULL GDT_LEN EQU $ GDT_SEG ENDS ;++++++++++++++全局描述符表结束++++++++++++++++++++++++++++++++ ;--------------------------------------------------------------- INCLUDE P_USER_1.ASM END START