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

📄 disp.asm

📁 一个小型操作系统
💻 ASM
字号:
;FILENAME:              DISP.ASM
.MODEL  HUGE
.386P
;常量定义
FALSE                   EQU     0
TRUE                    EQU     1
TAB_KEY                 EQU     09H
CR_KEY                  EQU     0DH
LF_KEY                  EQU     0AH
FLAG_OF_FILE_END	EQU	0FFH
INCLUDE                 386SCD.ASM
INCLUDE                 MACRO.MAC
INCLUDE                 IDT.ASM
;--------------------------------------------------------------------------------------------------------------
;堆栈段
REAL_STACK_SEG          SEGMENT STACK   PARA    USE16	'STACK'
;堆栈大小
REAL_STACK_LEN          =       100H
			DB      REAL_STACK_LEN  DUP(0)
REAL_STACK_SEG          ENDS
;---------------------------------------------------------------------------------------------------------------
;数据段
REAL_DATA_SEG           SEGMENT PARA    USE16	'DATA'
FILE_NAME               DB 'DISP.ASM',0
			DB	30H	DUP(0)
;文件句柄
FILE_HANDLE             DW 0
;文件结束标志
FILE_OVER               DW FALSE
;提示信息
OPEN_FILE_ERR_MSG       DB 0DH,0AH,'OPEN FILE ERROR !$'
READ_FILE_ERR_MSG       DB 0DH,0AH,'READ FILE ERROR !$'
REAL_BEGIN_MSG          DB 0DH,0AH,'REAL MODE BEGIN !$'
PROMPT_1                DB 'PRESS ANY KEY TO CONTINUE !$'
PROMPT_2		DB 'PRESS ANY KEY TO QUIT THIS PROGRAM !$'
AUTHER_MESSAGE          LABEL   BYTE
LINE_1                  DB '* --------------------------------------- *$'
LINE_2                  DB '|                                         |$'
LINE_3                  DB '|               DESIGNED BY:              |$'
LINE_4                  DB '|                                         |$'
LINE_5                  DB '|            08000118  DAI  HUA           |$'
LINE_6                  DB '|            08000129   XU  XIN           |$'
LINE_7                  DB '|            08000130 ZHAO  TINGHAI       |$'
LINE_8                  DB '|                                         |$'
LINE_9                  DB '|            THANK YOU FOR TESTING        |$'
LINE_A                  DB '|                                         |$' 
LINE_B                  DB '* --------------------------------------- *$'
;保存实模式下GDTR,IDTR,SS,SP的内容
REAL_GDT                DW 4 DUP(0)
REAL_IDT                DW 4 DUP(0)
REAL_SS                 DW ?
REAL_SP                 DW ?
;实模式下的文件缓冲区
REAL_DATA_BUF           DB 1024 DUP(?)
;每次读到的文件大小
DATA_BUF_SIZE           DW 0
;文件总大小
DATA_BUF_SUM            DD 0
;EDI的备份
SAVE_EDI                DD 0
;保护模式下的GDTR和IDTR
VGDTR                   PDESC   <GDT_LEN-1,>
VIDTR                   PDESC   <IDT_LEN-1,>
REAL_DATA_SEG           ENDS
;----------------------------------------------------------------------------------------------------------------------
;全局描述符表段
GDT_SEG                 SEGMENT PARA    USE16
GDT                     LABEL   BYTE
NULL_DESC               DESCRIPTOR      <>
NORMAL                  DESCRIPTOR      <0FFFFH,,,ATDW,,>
NORMAL_SEL              =       NORMAL-GDT
GDT_INIT_BEGIN          LABEL   BYTE
REAL_STACK_DESC         DESCRIPTOR      <REAL_STACK_LEN-1,REAL_STACK_SEG,,ATDWA,,>
REAL_STACK_SEL          =       REAL_STACK_DESC-GDT
REAL_DATA_DESC          DESCRIPTOR      <0FFFFH,REAL_DATA_SEG,,ATDWA,,>
REAL_DATA_SEL           =       REAL_DATA_DESC-GDT
REAL_CODE_DESC          DESCRIPTOR      <0FFFFH,REAL_CODE_SEG,,ATCER,,>
REAL_CODE_SEL           =       REAL_CODE_DESC-GDT
IDT_STACK_DESC          DESCRIPTOR      <IDT_STACK_LEN-1,IDT_STACK_SEG,,ATDW,,>
IDT_STACK_SEL           =       IDT_STACK_DESC-GDT
IDT_DATA_DESC           DESCRIPTOR      <0FFFFH,IDT_DATA_SEG,,ATDW,,>
IDT_DATA_SEL            =       IDT_DATA_DESC-GDT
IDT_CODE_DESC           DESCRIPTOR      <0FFFFH,IDT_CODE_SEG,,ATCER,,>
IDT_CODE_SEL            =       IDT_CODE_DESC-GDT
GDNUM                   =       ($-GDT_INIT_BEGIN)/(SIZE DESCRIPTOR)
;
VRAM_DESC               DESCRIPTOR      <0FFFFH,08000H,0BH,ATDW,,>
VRAM_SEL                =       VRAM_DESC-GDT
DATA_BUF_DESC           DESCRIPTOR      <0FFFFH,,20H,ATDW,0FH,>
DATA_BUF_SEL            =       DATA_BUF_DESC-GDT
GDT_LEN                 =       $-GDT
GDT_SEG                 ENDS
;---------------------------------------------------------------------------------------------------------------------------
;中断描述符表段
IDT_SEG                 SEGMENT PARA    USE16
IDT                     LABEL   BYTE
IDT_0H                  GATE    <>
IDT_1H                  DW      128     DUP(0)  ;20H * 4 = 80H  (80H = 128D)
;自定义的DOS INT21H中断描述符
IDT_DOS_21H             GATE    <(OFFSET INT21H),IDT_CODE_SEL,,AT386IGATE,>
IDT_LEN                 =       $-IDT
IDT_SEG                 ENDS
;--------------------------------------------------------------------------------------------------------------------------
;代码段
REAL_CODE_SEG           SEGMENT PARA    USE16
        ASSUME  CS:REAL_CODE_SEG,DS:REAL_DATA_SEG,SS:REAL_STACK_SEG
;程序入口点
MODE_T_START:
			MOV	AX,REAL_DATA_SEG
			MOV	ES,AX
                        MOV     SI,80H
                        MOV     CL,DS:[SI]
                        CMP     CL,0
;显示文件
                        JZ      DISP_DEFAULT_FILE
DEL_SPACE:              INC     SI
                        MOV     AL,DS:[SI]
			CMP	AL,20H
                        JZ      DEL_SPACE ;LET SI POINT TO THE FIRST CHARACTER
                                          ;WHITCH IS NOT A SPACE
                        MOV     DI,0H
			CLD
;得到文件名
GET_FILE_NAME:
                        MOV     AL,DS:[SI]
                        CMP     AL,0DH
                        JE      FORM_ASCIIZS
                        MOVSB
                        JMP     GET_FILE_NAME
FORM_ASCIIZS:           INC     DI
                        MOV     ES:[DI],0
DISP_DEFAULT_FILE:
			CLI
			MOV     AX,REAL_STACK_SEG
			MOV     SS,AX
                        MOV     AX,REAL_DATA_SEG
                        MOV     DS,AX
                        MOV     REAL_SS,SS
			MOV     SP,REAL_STACK_LEN
			MOV     REAL_SP,SP
			STI
			MOV     AX,REAL_DATA_SEG
			MOV     DS,AX
;打开第20根地址线
			CALL    OPEN_A20
;保存实模式下的GDTR和IDTR
			SGDT    FWORD PTR REAL_GDT
			SIDT    FWORD PTR REAL_IDT
;初始化GDT和IDT
			CALL    INIT_GDT
			CALL    INIT_IDT
;调用文件读取宏(文件->实模式下缓冲区->保护模式下缓冲区)
			READFILE        FILE_NAME
;将扩展内存中的数据写到显示内存
MOVE_DATA_TO_VRAM:
			MOV     AX,REAL_DATA_SEL
			MOV     FS,AX
			MOV     AX,DATA_BUF_SEL
			MOV     GS,AX
			MOV     AX,VRAM_SEL
			MOV     ES,AX
			MOV     ECX,DATA_BUF_SUM
;置文件结束符
			MOV	GS:[ECX],FLAG_OF_FILE_END
			MOV     EDI,0
;调用清屏宏
			CLEAR_SCREEN
REPEAT_MOVE:            MOV     AH,07H
			MOV     AL,GS:[EDI]
;读到文件结束标志
IF_FILE_END:
			CMP	AL,FLAG_OF_FILE_END
			JE	FILE_DISP_END	;文件显示结束
;读到TAB键
IF_TAB_KEY:             CMP     AL,09H
                        JNE     IF_CR_KEY
                        MOV     CX,8
;TAB键处理部分(加空格)
FILL_TO_8_BLANK:        MOV     AX,0720H
                        MOV     ES:[EBX],AX
                        MOV     EAX,EBX
                        INC     EBX
                        INC     EBX
                        XOR     EDX,EDX
                        PUSH    EBX
                        MOV     EBX,16
                        DIV     EBX
                        POP     EBX
                        CMP     EDX,14
                        JNZ     FILL_TO_8_BLANK
                        INC     EDI
                        JMP     REPEAT_MOVE
;读到回车键
IF_CR_KEY:              CMP     AL,CR_KEY
			JNZ     GO_ON_DISPLAYING
			INC     EDI
			INC     EDI
;回车键处理部分(加空格至行尾)
FILL_BLANK_TO_LINE_END: MOV     AX,0720H
			MOV     ES:[EBX],AX
			MOV     EAX,EBX
			INC     EBX
			INC     EBX
			XOR     EDX,EDX
			PUSH    EBX
			MOV     EBX, 160
			DIV     EBX
			POP     EBX
			CMP     EDX,158
                        JNZ     FILL_BLANK_TO_LINE_END
;判断是否写满一屏                        
		CMP     EAX,23
;若写满一屏,跳至显示下一屏的功能块
                        JZ      SHOW_NEXT_PAGE
;若未写满一屏,则继续显示
			JMP     REPEAT_MOVE
GO_ON_DISPLAYING:
			MOV     ES:[EBX],AX
			INC     EBX
			INC     EBX
			INC     EDI
			JMP	REPEAT_MOVE
SHOW_NEXT_PAGE:         
			PUSH	ECX
                        MOV     AH,09H
                        MOV     CX,1820H
                        LEA     DX,PROMPT_1
                        INT     21H
;在保护模式下调用自己写的中断INT21H-09H号功能,显示按"任意键继续"的提示信息
;响铃并等待键盘输入
			PRP_BELL
			CLEAR_SCREEN
			POP	ECX
                        MOV     EBX,0
                        JMP     REPEAT_MOVE
;文件显示结束
FILE_DISP_END:
			LEA	DX,PROMPT_2
                        MOV     CX,1820H
			MOV	AH,9
			INT	21H
                        PRP_BELL
                        CLEAR_SCREEN
;显示版权提示信息
                        MOV     AH,09H
        START_OFFSET    =       0620H
        IRP     LINE_NUM,<1,2,3,4,5,6,7,8,9,A,B>
                        MOV     CX,START_OFFSET
                        LEA     DX,LINE_&LINE_NUM
                        INT     21H
        START_OFFSET    =       START_OFFSET + 0100H
                        ENDM
;全部操作结束,转实模式
;置NORMAL描述符选择子      
	        MOV     AX,NORMAL_SEL
                        MOV     DS,AX
                        MOV     ES,AX
                        MOV     FS,AX
                        MOV     GS,AX
                        CLI
                        MOV     EAX,CR0
                        AND     EAX,0FFFFFFFEH
                        MOV     CR0,EAX
                        JUMP16  REAL_CODE_SEG,REAL_MODE
REAL_MODE:              
;恢复已保存的实模式下相应寄存器内容			
			MOV     AX,REAL_DATA_SEG
			MOV     DS,AX
			MOV     SS,DS:REAL_SS
			MOV     SP,DS:REAL_SP
;关闭第20根地址线
			CALL    CLOSE_A20
			LGDT    FWORD PTR REAL_GDT
			LIDT    FWORD PTR DS:REAL_IDT
			STI
;退出程序
			MOV     AX,4C00H
			INT     21H
;-------------------------------------------------------------------------------
;初始化全局描述符表并得到保护模式下的VGDTR的内容
INIT_GDT                PROC    NEAR
			PUSH    DS
			MOV     AX,GDT_SEG
			MOV     DS,AX
			MOV     CX,GDNUM
			MOV     SI,OFFSET GDT_INIT_BEGIN
INITG:                  MOV     AX,[SI].BASEL
			MOVZX   EAX,AX
			SHL     EAX,4
			SHLD    EDX,EAX,16
			MOV     [SI].BASEL,AX                                                       
			MOV     [SI].BASEM,DL
			MOV     [SI].BASEH,DH
			ADD     SI,SIZE DESCRIPTOR
			LOOP    INITG
			POP     DS
;
			MOV     BX,10H
			MOV     AX,GDT_SEG
			MUL     BX
			MOV     WORD PTR VGDTR.BASE,AX
			MOV     WORD PTR VGDTR.BASE+2,DX
			RET
INIT_GDT                ENDP
;--------------------------------------------------------------------------------------------
;得到保护模式下的VIDTR的内容
INIT_IDT                PROC    NEAR
			MOV     BX,10H
			MOV     AX,IDT_SEG
			MUL     BX
			MOV     WORD PTR VIDTR.BASE,AX
			MOV     WORD PTR VIDTR.BASE+2,DX
			RET
INIT_IDT                ENDP
;----------------------------------------------------------
;打开第20根地址线的子程序
OPEN_A20                PROC    FAR
			PUSH    AX
			IN      AL,92H
			OR      AL,2
			OUT     92H,AL
			POP     AX
			RETF
OPEN_A20                ENDP
;----------------------------------------------------------
;关闭第20根地址线的子程序
CLOSE_A20               PROC    FAR
			PUSH    AX
			IN      AL,92H
			AND     AL,0FDH
			OUT     92H,AL
			POP     AX
			RETF
CLOSE_A20               ENDP
;----------------------------------------------------------
;响铃并等待键盘输入的子程序
_BELL                   PROC    FAR
			PUSH    AX
			PUSH    DX
			MOV     DL,7
			MOV     AH,2
			INT     21H
			MOV     AH,07H
			INT     21H
			POP     DX
			POP     AX
			RETF
_BELL                   ENDP
REAL_CODE_SEG           ENDS
			END     MODE_T_START

⌨️ 快捷键说明

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