📄 asm11.asm
字号:
;名称:ASM11.ASM
;功能:演示进入和离开V86方式
;编译:TASM ASM11.ASM
;连接:TLINK ASM11.OBJ
;============================================================================
INCLUDE 386SCD.INC
;============================================================================
GDTSeg SEGMENT PARA USE16 ;全局描述符表数据段(16位)
;----------------------------------------------------------------------------
;全局描述符表
GDT LABEL BYTE
;空描述符
DUMMY Desc <>
;规范段描述符及选择子
Normal Desc <0ffffh,,,ATDW,,>
Normal_Sel = Normal-GDT
;显示缓冲区数据段描述符及选择子
Video Desc <07fffh,8000h,0bh,ATDW,,>
Video_Sel = Video-GDT
;----------------------------------------------------------------------------
EFFGDT LABEL BYTE
;V86任务TSS段描述符及选择子
V86TSS Desc <V86TSSLen-1,V86TSSSeg,,AT386TSS,,>
V86TSS_Sel = V86TSS-GDT
;V86任务局部描述符表的描述符及选择子
V86LDT Desc <V86LDTLen-1,V86LDTSeg,,ATLDT,,>
V86LDT_Sel = V86LDT-GDT
;IntFF任务TSS段描述符及选择子
IntFFTSS Desc <IntFFTSSLen-1,IntFFTSSSeg,,AT386TSS,,>
IntFFTSS_Sel = IntFFTSS-GDT
;IntFF任务局部描述符表的描述符及选择子
IntFFLDT Desc <IntFFLDTLen-1,IntFFLDTSeg,,ATLDT,,>
IntFFLDT_Sel = IntFFLDT-GDT
;临时任务的任务状态段描述符及选择子
TempTSS Desc <TempTSSLen-1,TempTSSSeg,,AT386TSS,,>
TempTSS_Sel = TempTSS-GDT
;临时任务代码段描述符及选择子
TempCode Desc <0ffffh,TempCodeSeg,,ATCE,,>
TempCode_Sel = TempCode-GDT
;----------------------------------------------------------------------------
GDNum = ($-EFFGDT)/(SIZE Desc) ;需特殊处理的描述符数
GDTLen = $-GDT ;全局描述符表长度
GDTSeg ENDS ;全局描述符表段定义结束
;============================================================================
IDTSeg SEGMENT PARA USE16 ;V86任务使用的中断描述符表
IDT LABEL BYTE
;对应0--12号中断/异常的中断门描述符
REPT 13
Gate <,TPCode_Sel,,AT386IGate+DPL3,>
ENDM
;通用保护故障处理程序门描述符
Gate <GPBegin,GPCode_Sel,,AT386TGate+DPL3,>
;对应14--254号中断/异常的中断门描述符
REPT 241
Gate <,TPCode_Sel,,AT386IGate+DPL3,>
ENDM
;对应255号中断的任务门描述符
Gate <,IntFFTSS_Sel,,ATTaskGate+DPL3,>
;----------------------------------------------------------------------------
IDTLen = $-IDT
IDTSeg ENDS ;中断描述符表段定义结束
;============================================================================
;IntFF任务的TSS段
IntFFTSSSeg SEGMENT PARA USE16
DD 0 ;链接字
DD 0 ;0级堆栈指针(实例不使用)
DW 0,0 ;0级堆栈选择子(实例不使用)
DD 0 ;1级堆栈指针(实例不使用)
DW 0,0 ;1级堆栈选择子(实例不使用)
DD 0 ;2级堆栈指针(实例不使用)
DW 0,0 ;2级堆栈选择子(实例不使用)
DD 0 ;CR3
DW IntFFBegin,0 ;EIP
DD 0 ;EFLAGS
DD 0 ;EAX
DD 0 ;ECX
DD 0 ;EDX
DD 0 ;EBX
DD IntFFStackLen ;ESP
DD 0 ;EBP
DD 0 ;ESI
DD 0 ;EDI
DW Normal_Sel,0 ;ES
DW IntFFCode_Sel,0 ;CS
DW IntFFStack_Sel,0 ;SS
DW Normal_Sel,0 ;DS
DW Normal_Sel,0 ;FS
DW Normal_Sel,0 ;GS
DW IntFFLDT_Sel,0 ;LDTR
DW 0 ;调试陷阱标志
DW $+2 ;指向I/O许可位图
DB 0ffh ;I/O许可位图结束标志
;----------------------------------------------------------------------------
IntFFTSSLen = $
IntFFTSSSeg ENDS
;============================================================================
;IntFF任务的LDT段
IntFFLDTSeg SEGMENT PARA USE16
FLDT LABEL BYTE
;0级堆栈段描述符及选择子
IntFFStack Desc <IntFFStackLen-1,IntFFStackSeg,,ATDWA,,>
IntFFStack_Sel = IntFFStack-FLDT+TIL
;代码段描述符及选择子
IntFFCode Desc <IntFFCodeLen-1,IntFFCodeSeg,,ATCER,,>
IntFFCode_Sel = IntFFCode-FLDT+TIL
;----------------------------------------------------------------------------
IntFFLDNum = ($-FLDT)/(SIZE Desc)
IntFFLDTLen = $
IntFFLDTSeg ENDS
;============================================================================
;IntFF任务的堆栈
IntFFStackSeg SEGMENT PARA USE16
IntFFStackLen = 512
DB IntFFStackLen DUP(0)
IntFFStackSeg ENDS
;============================================================================
;IntFF任务的代码段
IntFFCodeSeg SEGMENT PARA USE16
ASSUME CS:IntFFCodeSeg
;----------------------------------------------------------------------------
IntFFMess DB 'Return to real mode.'
IntFFMessLen = $-IntFFMess
;----------------------------------------------------------------------------
IntFFBegin PROC FAR
mov si,OFFSET IntFFMess
mov ax,Video_Sel
mov es,ax
mov di,0
mov ah,17h
mov cx,IntFFMessLen
cld
INext: mov al,BYTE PTR cs:[si]
inc si
stosw
loop INext
JUMP16 TempTSS_Sel,0
IntFFBegin ENDP
;----------------------------------------------------------------------------
IntFFCodeLen = $
IntFFCodeSeg ENDS
;============================================================================
;V86任务的TSS段
V86TSSSeg SEGMENT PARA USE16
DD 0 ;链接字
DD V86Stack0Len ;0级堆栈指针
DW V86Stack0_Sel,0 ;0级堆栈选择子
DD 0 ;1级堆栈指针(实例不使用)
DW 0,0 ;1级堆栈选择子(实例不使用)
DD 0 ;2级堆栈指针(实例不使用)
DW 0,0 ;2级堆栈选择子(实例不使用)
DD 0 ;CR3
DW V86Begin,0 ;EIP
DD IOPL3 OR VMFL ;EFLAGS(IO特权级为3,VM=1)
DD 0 ;EAX
DD 0 ;ECX
DD 0 ;EDX
DD 0 ;EBX
DD V86Stack3Len ;ESP
DD 0 ;EBP
DD 0 ;ESI
DD 0 ;EDI
DW V86CodeSeg,0 ;ES
DW V86CodeSeg,0 ;CS
DW V86Stack3Seg,0 ;SS
DW V86CodeSeg,0 ;DS
DW V86CodeSeg,0 ;FS
DW V86CodeSeg,0 ;GS
DW V86LDT_Sel,0 ;LDTR
DW 0 ;调试陷阱标志
DW $+2 ;指向I/O许可位图
DB 4000h/8 DUP(0) ;I/O许可位图
DB 0ffh ;I/O许可位图结束标志
;----------------------------------------------------------------------------
V86TSSLen = $
V86TSSSeg ENDS
;============================================================================
;V86任务的LDT段
V86LDTSeg SEGMENT PARA USE16
VLDT LABEL BYTE
;----------------------------------------------------------------------------
;V86任务线性地址空间中最低端1M字节段的描述符及描述符
VAllMem Desc <0ffffh,,,ATDWA,0fh,>
VAllMem_Sel = VAllMem-VLDT+TIL
;V86任务0级堆栈段描述符及选择子
V86Stack0 Desc <V86Stack0Len-1,V86Stack0Seg,,ATDWA,,>
V86Stack0_Sel = V86Stack0-VLDT+TIL
;V86任务数据段描述符及选择子
V86Data Desc <V86DataLen-1,V86DataSeg,,ATDR,,>
V86Data_Sel = V86Data-VLDT+TIL
;V86任务中断/异常处理程序代码段描述符及选择子
TPCode Desc <TPCodeLen-1,TPCodeSeg,,ATCE,,>
TPCode_Sel = TPCode-VLDT+TIL
;V86任务通用保护异常处理程序代码段描述符及选择子
GPCode Desc <GPCodeLen-1,GPCodeSeg,,ATCE,,>
GPCode_Sel = GPCode-VLDT+TIL
;----------------------------------------------------------------------------
V86LDNum = ($-VLDT)/(SIZE Desc)
V86LDTLen = $
V86LDTSeg ENDS
;============================================================================
;V86任务的0级堆栈
V86Stack0Seg SEGMENT PARA USE16
V86Stack0Len = 512
DB V86Stack0Len DUP(0)
V86Stack0Seg ENDS
;============================================================================
;V86任务的3级堆栈
V86Stack3Seg SEGMENT PARA USE16
V86Stack3Len = 1024
DB V86Stack3Len DUP(0)
V86Stack3Seg ENDS
;============================================================================
;V86任务数据段
V86DataSeg SEGMENT PARA USE16
GPErrMess DB '......General Protection Error......'
GPErrMessLen = $-GPErrMess
V86DataLen = $
V86DataSeg ENDS
;============================================================================
;定义部分代表堆栈单元的符号
Perr EQU <WORD PTR [BP+0]>
Pip EQU <WORD PTR [bp+4]>
Pcs EQU <WORD PTR [bp+8]>
Pflag EQU <WORD PTR [bp+12]>
Psp EQU <WORD PTR [bp+16]>
Pss EQU <WORD PTR [bp+20]>
Pes EQU <WORD PTR [bp+24]>
Pds EQU <WORD PTR [bp+28]>
Pfs EQU <WORD PTR [bp+32]>
Pgs EQU <WORD PTR [bp+36]>
;============================================================================
;V86任务下的中断/异常处理程序代码段
TPCodeSeg SEGMENT PARA USE16
ASSUME CS:TPCodeSeg
;----------------------------------------------------------------------------
TPBegin PROC FAR
Count = 0
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -