📄 g_page.asm
字号:
;程序文件:\TC\G\DOSEXE_P.ASM 清单
.MODEL HUGE
.386P
include \tc\g\include\g_def.asm ; 描述符结构、常量、宏定义,清单见程序1-1
include \tc\g\include\tos_seg.asm ; 定义TOS堆栈段TOS_STACKSEG与TOS任务状态段TOS_TSSSEG
; 清单见程序1-2
include \tc\g\include\ps_seg_p.asm ; U.EXE任务的各段:堆栈段、任务状态段、LDT表
TOS_CODESEG SEGMENT PARA USE16 ; TOS操作系统的代码段
ASSUME CS:TOS_CODESEG,DS:DATA,SS:TOS_STACKSEG
TOS_BEGIN:
TOS_BEGIN0 ; TOS任务初始处理,在包含\tc\g\include\g_def.asm文件中
;***********page --->start
MOV AX,TOS_TSSASDATA_SEL
MOV DS,AX
MOV EAX,G_PDT_ADDR
mov DS:TOS_TASK.trcr3,eax
;jmp FROM_PAGE ;ok
CALL V_SEL_SETUP ;setup v_sel
;jmp FROM_PAGE ;ok
;***********move to 2M
CALL SEGS_MOV_2M ;all tos_segs(6 segs) --->2M idt_m
CALL PGT_INIT
;***********MODIFY interrupt --- use 200000H idt
MOV AX,TOS_DATA_SEL
MOV DS,AX
MOV DS:IDTLOAD,0
MOV DS:IDTLOAD+2,20h
LIDT FWORD PTR DS:IDTSIZE
;***********MODIFY gdt --- use 202000H gdt
MOV DS:IDTLOAD,2000H
MOV DS:IDTLOAD+2,20h
LGDT FWORD PTR DS:IDTSIZE
;jmp FROM_PAGE ;ok
;***********ENTER PAGE
MOV EAX,G_PDT_ADDR
MOV CR3,EAX ; ;把页目录表基址装入控制寄存器CR3
MOV EAX,CR0
OR EAX,80000000H
MOV CR0,EAX ; ;进入分页模式
JMP SHORT PAGE_BEGIN ; ;清除指令缓冲区
PAGE_BEGIN: ;*********************
DB 0EAH
DW OFFSET V_TOS_CODE_BEGIN
DW V_TOS_CODE_SEL ; USE 2M PROGRAM
V_TOS_CODE_BEGIN:
;jmp PAGE_END ;ok
MOV AX,V_TOS_DATA_SEL ; USE 2M DATA
MOV DS,AX
;CLI should not used
MOV AX,V_TOS_STACK_SEL ; USE 2M STACK
MOV SS,AX
;STI
MOV AX,V_TOS_TSS_SEL ; USE 2M TSS ONLY USEING IN PS_LDT
LTR AX
MOV CX,08D0H ; 清屏
MOV BX,0 ;ds:tos_data fs:data
scr1: MOV ES:[BX],0720H
ADD BX,2
LOOP scr1
;jmp PAGE_END
call disp_TOS_in_tos ; 显示U.EXE的LDT表和开头部分内容,本书未给清单
;jmp PAGE_END ;ok
MOV AH,9 ; 显示"This is a protect_mode program!"
MOV CX,0205H ;15 row 21 column
MOV DX,OFFSET TEST_MSG
INT 21H
;jmp PAGE_END ;OK
MOV BX,V_USER_PSLDT_SEL
LLDT BX
;*** 将c_buffer(放U.EXE)中内容? g_buf
MOV AX,DATA_SEL
MOV FS,AX
MOV ECX,0
MOV CX,FS:C_BUF_SIZE ;DATA_SEL
MOV EAX,OFFSET C_BUFFER
MOV ESI,EAX
MOV EDI,DS:G_BUF_SUM
MOVE_BUF1: MOV AL,FS:[ESI] ;移到g_buf,C_BUF_SIZE:文件大小
MOV GS:[EDI],AL ;GS=G_BUF_SEL
INC EDI
INC ESI
LOOP MOVE_BUF1
;**********************开始处理 U.EXE
MOV AX,TOS_DATA_SEL
MOV DS,AX ;TOS系统数据段
MOV AX,G_BUF_SEL
MOV GS,AX ;.exe(g_buf) 段,EXE头+程序
MOV AX,USER_PS_SEL ;GDT中USER_PS的首址
SUB AX,04H
;jmp PAGE_END ;OK
PUSH FS
CALL G_EXEC ;重定位,创建段表,开始2字节<>4D5AH,则不是DOS .exe
POP FS
;jmp PAGE_END ;OK
CMP AX,1 ;
JZ ERR_EXEFIL
;**********************设置U.EXE的任务状态段
MOV BL,DS:G_WORK[4]
MOV BH,DS:G_WORK[5]
MOV CL,DS:G_WORK[6]
MOV CH,DS:G_WORK[7]
push fs
mov ax,USER_PsTSS_D_SEL
mov fs,ax
mov fs:USER_Ps_TASK.TREIP,cx
mov fs:USER_Ps_TASK.TREIP+2,0
mov fs:USER_Ps_TASK.TRCS,USER_PS_SEL
;此处略去:显示U.EXE的代码段选择子与ip 的程序,请见光盘
;;;;;disp cs ip disable in book
mov ax,cx
mov cx,0E16H
call disp_ax
MOV AH,9
MOV CX,0E10H ;15 row 21 column
MOV DX,OFFSET TEST_IP ;"IP: "
INT 21H
MOV AH,9
MOV CX,0E00H ;10 row 00 column
MOV DX,OFFSET TEST_CS ;"CS: "
INT 21H
mov ax,user_ps_SEL
mov cx,0E06H
call disp_ax
;;;;;disp cs ip disable in book
;jmp PAGE_END ;OK
mov fs:USER_Ps_TASK.TRCS+2,0
mov fs:USER_Ps_TASK.TREFLAG,0
mov fs:USER_Ps_TASK.TRLDT,V_USER_PsLDT_SEL
mov fs:USER_Ps_TASK.TRLDT+2,0
MOV EAX,G_PDT_ADDR ;***************
mov fs:USER_Ps_TASK.trcr3,eax
mov al,ds:g_WORK
mov ah,ds:g_WORK[1]
mov fs:USER_Ps_TASK.TRDS,14h
mov fs:USER_Ps_TASK.TRDS+2,0
mov fs:USER_Ps_TASK.TRES,G_VRAM_SEL
mov fs:USER_Ps_TASK.TRES+2,0
mov fs:USER_Ps_TASK.TRSS0,AX
mov fs:USER_Ps_TASK.TRSS0+2,0
mov fs:USER_Ps_TASK.TRSS,AX
mov fs:USER_Ps_TASK.TRSS+2,0
mov al,ds:g_WORK[2]
mov ah,ds:g_WORK[3]
mov fs:USER_Ps_TASK.TRESP0,AX
mov fs:USER_Ps_TASK.TRESP0+2,0
mov fs:USER_Ps_TASK.TRESP,AX
mov fs:USER_Ps_TASK.TRESP+2,0
mov fs:USER_Ps_TASK.TRFLAG,0
pop fs
call disp_ldt_head ; 显示U.EXE的LDT表和重定位后的开头部分,在
;jmp PAGE_END ;OK
; \tc\g\include\reposit.asm中,本书中未给出该过程的程序,请见光
;盘
DB 0EAH ;通过U.EXE的任务状态段,执行U.EXE
DW 0
dw V_USER_PsTSS_SEL
COMEBACK_TO_TOS: ; 21h---4ch return
JMP PAGE_END
ERR_EXEFIL:
MOV AH,9
MOV CX,1100H
MOV DX,OFFSET ERR_EXEFILE
INT 21H
PAGE_END: ;********************* should have next 3 lines
DB 0EAH
DW OFFSET TURN_TO_REAL_MODE
DW TOS_CODE_SEL
TURN_TO_REAL_MODE:
MOV EAX,CR0 ; ;关闭分页模式
AND EAX,7FFFFFFFH
MOV CR0,EAX
JMP SHORT FROM_PAGE
FROM_PAGE:
; next 2 line exist ok no ok
;MOV AX,TOS_STACK_SEL
;MOV SS,AX
call turn_to_real ;返回实模式,在\tc\g\include\tos_used.asm
;中
include \tc\g\include\tos_used.asm ;
include \tc\g\include\tos_usep.asm ;
include \tc\g\include\reposit0.asm ;
DO_DOS21H4E PROC FAR
RET
DO_DOS21H4E ENDP
TOS_CODELEN = $
TOS_CODESEG ENDS
GDTSEG SEGMENT PARA USE16 ;全局描述符表
GDT LABEL BYTE
G_NULL GDT_DESC <>
REAL_SEG GDT_DESC <0FFFFH,0,0,92H,0,0>
REAL_SEL = REAL_SEG - GDT
GDT_INIT_BEGIN LABEL BYTE
IDT GDT_DESC <IDTLEN,IDTSEG,0,92H,0,0> ;92H=P ,DPL=0,TYPE=2
IDT_SEL = IDT - GDT
TOS_CODE GDT_DESC <0FFFFH,TOS_CODESEG,0,9AH,0,0> ;9AH=exec/read ,DPL=0
;limit must be 0ffffh for returnning to real_mode
TOS_CODE_SEL = TOS_CODE - GDT
TOS_DATA GDT_DESC <DATA_TOSLEN,DATA_TOS,0,92H,0,0> ;92H=P ,DPL=0,TYPE=2
TOS_DATA_SEL = TOS_DATA - GDT
TOS_STACK GDT_DESC <TOS_STACKLEN,TOS_STACKSEG,0,93H,0,0> ;96H=R/W ,DOWN
TOS_STACK_SEL = TOS_STACK - GDT
TOS_TSS GDT_DESC <TOS_TSSLEN,TOS_TSSSEG,0,089H,0,0> ;89H=386TSS DPL=0
TOS_TSS_SEL = TOS_TSS - GDT
GDT_ASDATA GDT_DESC <GDTLEN,GDTSEG,0,92H,0,0>
GDT_ASDATA_SEL = GDT_ASDATA - GDT
TOS_TSSASDATA GDT_DESC <TOS_TSSLEN,TOS_TSSSEG,0,92H,0,0>
TOS_TSSASDATA_SEL = TOS_TSSASDATA - GDT
USER_PsTSS_mov GDT_DESC <USER_PsTSSLEN,USER_PsTSSSEG,0,92H,0,0> ;9AH=exec/read ,DPL=0
USER_PsTSS_mov_SEL = USER_PsTSS_mov - GDT
USER_PsLDT_mov GDT_DESC <USER_PsLDTLEN,USER_PsLDTSEG,0,92H,0,0>
USER_PsLDT_mov_SEL = USER_PsLDT_mov - GDT ;+ 04H
DATASEG GDT_DESC <DATALEN,DATA,0,92H,0,0> ;92H=P ,DPL=0,TYPE=2
DATA_SEL = DATASEG - GDT
GDT_INIT_COUNT = ($ - GDT_INIT_BEGIN)/(SIZE GDT_DESC)
;***********prepare page_memory
G_PDT GDT_DESC <0FFFH,2000H,21H,92H,0,0>;92H=P ,DPL=0,TYPE=2 ,base=2M+68k
G_PDT_SEL = G_PDT - GDT
G_PT0 GDT_DESC <0FFFFH,3000H,21H,92H,0,0>;92H=P ,DPL=0,TYPE=2 ,base=2M+72k ;16 PAGES
G_PT0_SEL = G_PT0 - GDT
G_MOVSEG GDT_DESC <0FFFFH,0,20H,92H,0FFH,0> ;92H=P ,DPL=0,TYPE=2 ,base=2M
G_MOV_SEL = G_MOVSEG - GDT ;LIMIT=1M
;***********next for page_memory
V_DOS_CODE GDT_DESC <0FFFFH,0,0,9AH,0FH,0> ;9AH=exec/read ,DPL=0
V_DOS_CODE_SEL = V_DOS_CODE - GDT
G_VRAM GDT_DESC <0FFFFH,0,0,92H,0,0C0H> ;92H=P ,DPL=0,TYPE=2
G_VRAM_SEL = G_VRAM - GDT ;60h
G_BUF GDT_DESC <0FFFFH,0,G_BUF_BASE,92H,0,0> ;92H=P ,DPL=0,TYPE=2 ,base=4M
G_BUF_SEL = G_BUF - GDT
V_G_PT0 GDT_DESC <0FFFFH,3000H,41H,92H,0,0C0H>
V_G_PT0_SEL = V_G_PT0 - GDT
V_TOS_TSS GDT_DESC <TOS_TSSLEN,1000H,40H,089H,0,0C0H> ;89H=386TSS DPL=0
V_TOS_TSS_SEL = V_TOS_TSS - GDT
V_TOS_CODE GDT_DESC <0FFFFH,3000H,42H,9AH,0,0C0H> ;9AH=exec/read ,DPL=0
;limit must be 0ffffh for returnning to real_mode
V_TOS_CODE_SEL = V_TOS_CODE - GDT
V_TOS_STACK GDT_DESC <TOS_STACKLEN,0,0,93H,0,0> ;96H=R/W ,DOWN
V_TOS_STACK_SEL = V_TOS_STACK - GDT
V_TOS_DATA GDT_DESC <DATA_TOSLEN,0,0,92H,0,0> ;92H=P ,DPL=0,TYPE=2
V_TOS_DATA_SEL = V_TOS_DATA - GDT
V_USER_PsTSS GDT_DESC <USER_PsTSSLEN,USER_PsTSSSEG,0,089H,0,0> ;9AH=exec/read ,DPL=0
V_USER_PsTSS_SEL = V_USER_PsTSS - GDT
V_USER_PsLDTT GDT_DESC <USER_PsLDTLEN,USER_PsLDTSEG,0,82H,0> ;82H=LDT
V_USER_PsLDT_SEL = V_USER_PsLDTT - GDT
USER_PsTSS_D GDT_DESC <USER_PsTSSLEN,USER_PsTSSSEG,0,92H,0,0> ;9AH=exec/read ,DPL=0
USER_PsTSS_D_SEL = USER_PsTSS_D - GDT
USER_PsLDTT_ASDATA GDT_DESC <USER_PsLDTLEN,USER_PsLDTSEG,0,92H,0> ;82H=LDT
USER_PsLDTT_ASDATA_SEL = USER_PsLDTT_ASDATA - GDT
ps_to_TOS_sel = $
GDTLEN = $ - GDT
GDTSEGLEN = $
GDTSEG ENDS
include \tc\g\include\COS_DATA.asm
include \tc\g\include\COS_IDT0.asm
;*************************************************next DOS
CODE SEGMENT PARA USE16 ;PUBLIC 'CODE' ;实模式代码段
ASSUME CS:CODE,DS:DATA,SS:STACK
include \tc\g\include\a20.asm ;见程序1-1
MAIN PROC FAR
START:
REAL_BEGIN_PAGE ;******* ;在\tc\g\include\g_def.asm中,见程序1-1
;
;set idt_desc for IDT0E
MOV AX,IDTSEG
MOV DS,AX
MOV DI,OFFSET IDT0E
MOV AX,OFFSET GINT0EH
MOV DS:[DI].OFF_L,AX
;
mov ax,data
mov ds,ax
call g_input_file ;输入文件名,并将文件取到缓冲区c_buf,在
; \tc\g\include\g_real.asm中,见程序1-2
TURN_TO_PROTECT_MODE:
CALL GDT_INIT ;初始化GDT表,在\tc\g\include\g_real.asm中,见程序1-2
;CALL USER_Ps_LDT_INIT ;初始化LDT表,在\tc\g\include\ps_ldt.asm中
TURN_TO_PROTECT_PAGE ;*****进入TOS任务,在\TC\G\INCLUDE\G_DEF.ASM中,见程序1-1
REAL_MODE:
TO_DOS ;回到DOS 在\TC\G\INCLUDE\G_DEF.ASM中,见程序1-1
MAIN ENDP
include \tc\g\include\g_real.asm
;include \tc\g\include\ps_ldt.asm
CODE ENDS
include \tc\g\include\DOS_DATA.asm
END START
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -