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

📄 mode_t.asm

📁 操作系统实验教程核心技术与编程实例书中地例子代码
💻 ASM
字号:
.MODEL HUGE
STACK       SEGMENT STACK PARA 'STACK'
            DB 200 DUP(0)
STACK       ENDS
include \tc\g\include\g_def.asm
CODE        SEGMENT WORD PUBLIC 'CODE'
            ASSUME CS:CODE,DS:DATA,SS:STACK
MODE_CHANGE PROC FAR
START:      MOV AX,DATA
            MOV DS,AX
            CLI
            MOV AX,STACK
            MOV SS,AX
            MOV SAVE_SS,AX
            MOV SP,200
            MOV SAVE_SP,SP
            STI
            MOV DS:FILE_OVER,1
            ;
            .386P
            MOV AH,0DFH
            CALL OPEN_A20
            ; save current GDTR & IDTR
            SGDT FWORD PTR SAVE_GDT
            SIDT FWORD PTR SAVE_IDT
            ;set desc for cs
            MOV DI,OFFSET GDT_CS
            MOV AX,CS
            MOV CX,10H
            MUL CX
            MOV [DI].BASE_L,AX
            MOV [DI].BASE_M,DL
            ;set desc for ds
            MOV DI,OFFSET GDT_DS
            MOV DX,0
            MOV AX,DS
            MOV CX,10H
            MUL CX
            MOV [DI].BASE_L,AX
            MOV [DI].BASE_M,DL
            MOV [DI].BASE_H,DH
            ;set desc for ss
            MOV DI,OFFSET GDT_SS
            MOV AX,SS
            MOV CX,10H
            MUL CX
            MOV [DI].BASE_L,AX
            MOV [DI].BASE_M,DL
            ;set desc for gdt_buf
            MOV DI,OFFSET GDT_BUF
            MOV [DI].BASE_L,0      ;base_addr=2M
            MOV [DI].BASE_M,020H
            MOV [DI].GRAN,0FH      ;limit=1M
            ;
            CLI
            MOV AX,DS
            MOV CX,10H
            MUL CX
            ADD AX,OFFSET GDT_DEF 
                         ;DX:AX=32 address for GDT
            ADC DX,0 
            MOV DTLOAD,AX
            MOV DTLOAD+2,DX
            MOV AX,OFFSET GDT_SIZE
            SUB AX,OFFSET DTSIZE
            ADD AX,1
            MOV DTSIZE,AX
            ;***********************************************
                                      ; mov file to c_buffer
            MOV DS:G_BUF_SUM,0
            MOV AX,3D02H              ;for read
            LEA DX,FILE_NAME
            INT 21H
            JNC READ_FILE0
            LEA DX,ERR_FILE
            MOV AH,9
            INT 21H
            MOV AH,4CH
            INT 21H

READ_FILE0: MOV DS:FILE_HANDLE,AX
READ_FILE:  
            MOV DS:SAVE_SS,SS
            MOV DS:SAVE_SP,SP
            SGDT FWORD PTR SAVE_GDT
            SIDT FWORD PTR SAVE_IDT

            MOV BX,DS:FILE_HANDLE  ;file_handle to BX
            MOV CX,1024            ;to read byte_count
            MOV DX,OFFSET C_BUFFER
            MOV AH,3FH             ;read file
            INT 21H
            JNC READ_FILE1
            MOV AX,0
            MOV DS:C_BUF_SIZE,AX
            MOV DS:FILE_OVER,AX
            MOV AH,3EH            ;close file
            INT 21H
            JMP PROTECT_MODE
READ_FILE1: MOV DS:C_BUF_SIZE,AX  ;read really byte_count
            CMP AX,1024
            JNL PROTECT_MODE
            MOV DS:FILE_OVER,0
            MOV BX,DS:FILE_HANDLE  
            MOV AH,3EH            ;close file
            INT 21H
            ;*********************************************
PROTECT_MODE:
            cli
            LGDT FWORD PTR DTSIZE
            
            MOV AX,GDT_DS_SEL
            MOV DS,AX
            MOV ES,AX
            MOV FS,AX
            MOV GS,AX
            sti
            ;
            MOV EAX,00000001H
            MOV CR0,EAX
            JMP EDS_FLUSH         ;clear instructors
EDS_FLUSH:  DB 0EAH
            DW OFFSET MOVE_BUF
            DW GDT_CS_SEL
            ;****************************************
MOVE_BUF:   
            MOV AX,GDT_DS_SEL
            MOV FS,AX
            MOV AX,GDT_BUF_SEL
            MOV GS,AX
            CMP FS:C_BUF_SIZE,1
            JL VRAM_DISP           ;file have be read over

            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]        ;move to 2M
            MOV GS:[EDI],AL
            INC EDI
            INC ESI
            LOOP MOVE_BUF1

            MOV FS:G_BUF_SUM,EDI
            CMP FS:FILE_OVER,1
            JL VRAM_DISP
            ;***************** ;read again->start real_mode
            CLI       
            MOV EAX,CR0
            AND AX,NOT PE_ON
            MOV CR0,EAX
            ;
            DB 0EAH
            DW OFFSET REAL_MODE0
            DW CODE
REAL_MODE0: MOV AH,0DDH
            CALL CLOSE_A20
            ;
            MOV AX,DATA
            MOV DS,AX
            LGDT FWORD PTR SAVE_GDT
            LIDT FWORD PTR SAVE_IDT
            cli
            MOV SS,SAVE_SS
            MOV SP,SAVE_SP
            sti
            JMP READ_FILE                 ;read again
            ;***************************************
            ; all of file are moved to g_buf

VRAM_DISP:  
            MOV AX,GDT_DS_SEL
            MOV FS,AX
            MOV AX,GDT_BUF_SEL
            MOV GS,AX
            MOV AX,VRAM_SEL
            MOV ES,AX
            MOV CX,08D0H
            MOV BX,0
L1:         MOV ES:[BX],0720H
            ADD BX,2
            LOOP L1

            MOV ECX,FS:G_BUF_SUM
            CMP ECX,2048
            JL  LL
            MOV ECX,2048
LL:         MOV ESI,0
            MOV EBX,480
L2:         MOV AL,GS:[ESI]
            MOV AH,22
            MOV ES:[EBX],AX
            ADD EBX,2
            INC ESI
            LOOP L2
;turn to real_mode
            CLI
            MOV EAX,CR0
            AND AX,NOT PE_ON
            MOV CR0,EAX
            ;
            DB 0EAH
            DW OFFSET REAL_MODE
            DW CODE
REAL_MODE:  MOV AH,0DDH
            TO_DOS
            .8086
MODE_CHANGE ENDP
include \tc\g\include\a20.asm

CODE        ENDS
DATA        SEGMENT WORD PUBLIC 'DATA'
FILE_NAME   DB '\TC\G\MODE.TXT',0
FILE_HANDLE DW 0
FILE_OVER   DW 0
ERR_FILE    DB 0DH,0AH,'Open file error$'
OK_MSG      DB 0DH,0AH,'Have a nice day,Bye!   $'
SAVE_GDT    DW 4 DUP(0)
SAVE_IDT    DW 4 DUP(0)
SAVE_SS     DW 0
SAVE_SP     DW 0
DTSIZE      DW 0
DTLOAD      DW 0,0
GDT_DEF     EQU $
            GDT_DESC <0,0,0,0,0,0>
GDT_CS      GDT_DESC <0FFFFH,0,0,9AH,0,0>
                           ;9AH=exec/read ,DPL=0
GDT_DS      GDT_DESC <0FFFFH,0,0,92H,0,0>
                           ;92H=P ,DPL=0,TYPE=2
GDT_SS      GDT_DESC <0,0,0,96H,0,0>   
                           ;96H=R/W ,DOWN
GDT_VRM     GDT_DESC <0FFFFH,08000H,0BH,92H,0,0>
                           ;92H=P ,DPL=0,TYPE=2
GDT_BUF     GDT_DESC <0FFFFH,0,0,92H,0,0>
                           ;92H=P ,DPL=0,TYPE=2 ,length=1M
GDT_SIZE    DW 0

C_BUF_SIZE  DW 0
G_BUF_SUM   DD 0
C_BUFFER    DB 1024 DUP(?)
DATA        ENDS
            END START

⌨️ 快捷键说明

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