📄 dosexe.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.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文件中
;JMP TURN_TO_REAL_MODE
MOV CX,08D0H ; 清屏
MOV BX,0 ;ds:tos_data fs:data
scr1: MOV ES:[BX],0720H
ADD BX,2
LOOP scr1
;JMP TURN_TO_REAL_MODE
call disp_TOS_in_tos ; 显示U.EXE的LDT表和开头部分内容,本书未给清单
;JMP TURN_TO_REAL_MODE
MOV AH,9 ; 显示"This is a protect_mode program!"
MOV CX,0205H ;15 row 21 column
MOV DX,OFFSET TEST_MSG
INT 21H
;JMP TURN_TO_REAL_MODE
MOV BX,USER_PsLDT_SEL
LLDT BX
;*** 将c_buffer(放U.EXE)中内容? g_buf
MOV ECX,0
MOV CX,FS:C_BUF_SIZE
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
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
CALL G_EXEC ;重定位,创建段表,开始2字节<>4D5AH,则不是DOS .exe
;JMP TURN_TO_REAL_MODE
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
mov fs:USER_Ps_TASK.TRCS+2,0
mov fs:USER_Ps_TASK.TREFLAG,0
mov fs:USER_Ps_TASK.TRLDT,USER_PsLDT_SEL
mov fs:USER_Ps_TASK.TRLDT+2,0
mov fs:USER_Ps_TASK.trcr3,0
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表和重定位后的开头部分,在
; \tc\g\include\reposit.asm中,本书中未给出该过程的程序,请见光
;盘
DB 0EAH ;通过U.EXE的任务状态段,执行U.EXE
DW 0
dw USER_PsTSS_SEL
COMEBACK_TO_TOS:
JMP TURN_TO_REAL_MODE
ERR_EXEFIL:
MOV AH,9
MOV CX,1100H
MOV DX,OFFSET ERR_EXEFILE
INT 21H
TURN_TO_REAL_MODE:
call turn_to_real ;返回实模式,在\tc\g\include\tos_used.asm
;中
include \tc\g\include\tos_used.asm ;
include \tc\g\include\reposit0.asm ;
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
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
USER_PsTSS GDT_DESC <USER_PsTSSLEN,USER_PsTSSSEG,0,089H,0,0> ;9AH=exec/read ,DPL=0
USER_PsTSS_SEL = USER_PsTSS - 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 GDT_DESC <USER_PsLDTLEN,USER_PsLDTSEG,0,82H,0> ;82H=LDT
USER_PsLDT_SEL = USER_PsLDTT - GDT
GDT_ASDATA GDT_DESC <GDTLEN,GDTSEG,0,92H,0,0>
IDT GDT_DESC <IDTLEN,IDTSEG,0,92H,0,0> ;92H=P ,DPL=0,TYPE=2
IDT_SEL = IDT - GDT
GDT_ASDATA_SEL = $ - GDT
USER_PsLDTT_ASDATA GDT_DESC <USER_PsLDTLEN,USER_PsLDTSEG,0,92H,0,0>
USER_PsLDTt_ASDATA_SEL = USER_PsLDTT_ASDATA - 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)
G_VRAM GDT_DESC <0FFFFH,08000H,0BH,92H,0,0> ;92H=P ,DPL=0,TYPE=2
G_VRAM_SEL = G_VRAM - GDT ;60h
G_BUF GDT_DESC <0FFFFH,0,40H,92H,0,0> ;92H=P ,DPL=0,TYPE=2 ,base=4M
G_BUF_SEL = G_BUF - GDT
V_TOS_CODE_SEL = $
V_TOS_DATA_SEL = $
GDTLEN = $ - GDT
GDTSEG ENDS
include \tc\g\include\COS_DATA.asm
include \tc\g\include\COS_IDT0.asm
;*************************************************TOS above
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
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 + -