📄 asm7.asm
字号:
GP_Sel = GPCode-DLDT+TIL
;为模拟段不存在故障而安排的数据段描述符及选择子
TestNPS Desc <0ffffh,,,ATDW-80h,,>
TestNPS_Sel = TestNPS-DLDT+TIL
;----------------------------------------------------------------------------
DemoLDNum = ($-DLDT)/(SIZE Desc) ;LDT描述符个数
DemoLDTLen =$
;----------------------------------------------------------------------------
DemoLDTSeg ENDS
;----------------------------------------------------------------------------
;演示任务TSS段
;----------------------------------------------------------------------------
DemoTSSSeg SEGMENT PARA USE16
DemoTaskSS TSS <>
DB 0ffh
DemoTSSLen = $
DemoTSSSeg ENDS
;----------------------------------------------------------------------------
;演示任务的堆栈段
;----------------------------------------------------------------------------
DemoStackSeg SEGMENT PARA USE16
DemoStackLen = 1024
DB DemoStackLen DUP(0)
DemoStackSeg ENDS
;----------------------------------------------------------------------------
;演示任务的数据段
;----------------------------------------------------------------------------
DemoDataSeg SEGMENT PARA USE16
Mess0 DB 'Divide Error (Exception 0)',0
Mess4 DB 'Overflow (Exception 4)',0
MessB DB 'Segment Not Present (Exception 11)',0
MessC DB 'Stack Segment (Exception 12)',0
MessD DB 'General Protection (Exception 13)',0
MessOther DB 'Other Exception',0
ErrMess DB 'Error Code = '
ErrCode DB 4 DUP(0),'H',0
DemoDataLen = $
DemoDataSeg ENDS
;----------------------------------------------------------------------------
;演示任务的代码段
;----------------------------------------------------------------------------
DemoCodeSeg SEGMENT PARA USE16
ASSUME CS:DemoCodeSeg,DS:DemoDataSeg
;----------------------------------------------------------------------------
DemoBegin PROC FAR
mov ax,DemoLDT_Sel
lldt ax ;装载LDTR
mov ax,DemoStack_Sel ;置堆栈
mov ss,ax
mov esp,DemoStackLen
mov ax,ToDemoTSS_Sel
mov gs,ax ;把演示任务LDT选择子填入TSS
mov WORD PTR gs:DemoTaskSS.TRLDTR,DemoLDT_Sel
mov ax,DemoTSS_Sel
ltr ax ;装载TR
mov ax,DemoData_Sel
mov ds,ax ;装载其它数据段寄存器
mov ax,VideoBuf_Sel
mov es,ax
mov ax,XBuffer_Sel
mov fs,ax
mov ax,XBuffer_Sel
mov gs,ax
int 0ffh ;接收要模拟的异常类型号
mov al,BYTE PTR fs:KeyASCII ;按接收的字符模拟异常号
cmp al,'0'
jnz Demo4
mov ax,2000
mov cl,2 ;模拟除法出错故障
div cl ;该指令长2字节
jmp Over
Demo4: cmp al,'4'
jnz Demo11
mov al,100
add al,50
into ;模拟溢出陷阱
JMP OVER
Demo11: cmp al,'B'
jnz Demo12
mov ax,TestNPS_Sel ;模拟段不存在故障
mov gs,ax ;该指令长2字节
JMP Over
Demo12: cmp al,'C'
jnz Demo13
mov ebp,esp ;模拟堆栈出错故障
mov al,[ebp] ;该指令长4字节
jmp Over
Demo13: mov ax,DemoTSS_Sel ;模拟通用保护故障
mov gs,ax ;该指令长2字节
Over: ;转临时代码段
JUMP16 TempCode_Sel,<OFFSET ToDos>
DemoBegin ENDP
;----------------------------------------------------------------------------
DemoCodeLen = $
DemoCodeSeg ENDS
;----------------------------------------------------------------------------
TempCodeSeg SEGMENT PARA USE16 ;临时任务的代码段
ASSUME CS:TempCodeSeg
;----------------------------------------------------------------------------
Virtual PROC FAR
JUMP16 DemoCode_Sel,DemoBegin ;转演示任务
ToDos: mov ax,Normal_Sel ;恢复实方式段描述符高速缓存
mov ds,ax
mov es,ax
mov fs,ax
mov gs,ax
mov ss,ax
mov eax,cr0 ;准备返回实模式
and al,11111110b
mov cr0,eax
JUMP16 <SEG Real>,<OFFSET Real>
Virtual ENDP
;----------------------------------------------------------------------------
TempCodeSeg ENDS
;============================================================================
RDataSeg SEGMENT PARA USE16 ;实方式数据段
VGDTR PDesc <GDTLen-1,> ;GDT伪描述符
VIDTR PDesc <IDTLen-1,> ;IDT伪描述符
NORVIDTR PDesc <3ffh,> ;用于保存原IDTR值
SPVar DW ? ;用于保存实方式下的SP
SSVar DW ? ;用于保存实方式下的SS
Mess DB 'Press a key[0,4,B,C,D]:$';提示信息
RDataSeg ENDS
;----------------------------------------------------------------------------
RCodeSeg SEGMENT PARA USE16 ;实方式代码段
ASSUME CS:RCodeSeg,DS:RDataSeg
;----------------------------------------------------------------------------
Start PROC
mov ax,RDataSeg
mov ds,ax
cld
call InitGDT ;初始化全局描述符表GDT
call InitIDT ;初始化中断描述符表IDT
mov ax,GKeyLDTSeg
mov fs,ax
mov cx,GKeyLDNum
mov si,OFFSET GLDT
CALL InitLDT
mov ax,DemoLDTSeg
mov fs,ax
mov cx,DemoLDNum
mov si,OFFSET DLDT
CALL InitLDT
mov SSVar,ss ;保存堆栈指针
mov SPVar,sp
lgdt QWORD PTR VGDTR ;装载GDTR
sidt QWORD PTR NORVIDTR ;保存IDTR
cli ;关中断
lidt QWORD PTR VIDTR ;装载IDTR
mov eax,cr0
or al,1
mov cr0,eax
JUMP16 <TempCode_Sel>,<OFFSET Virtual>
Real: mov ax,RDataSeg
mov ds,ax
lss sp,DWORD PTR SPVar ;又回到实方式
lidt QWORD PTR NORVIDTR
sti
mov ax,4c00h
int 21h
Start ENDP
;----------------------------------------------------------------------------
InitGDT PROC
push ds
mov ax,GDTSeg
mov ds,ax
mov cx,GDNum
mov si,OFFSET EFFGDT
InitG: mov ax,[si].BaseL
movzx eax,ax
shl eax,4
shld edx,eax,16
mov WORD PTR [si].BaseL,ax
mov BYTE PTR [si].BaseM,dl
mov BYTE PTR [si].BaseH,dh
add si,SIZE Desc
loop InitG
pop ds
mov bx,16
mov ax,GDTSeg
mul bx
mov WORD PTR VGDTR.Base,ax
mov WORD PTR VGDTR.Base+2,dx
ret
InitGDT ENDP
;----------------------------------------------------------------------------
InitIDT PROC
mov bx,16
mov ax,IDTSeg
mul bx
mov WORD PTR VIDTR.Base,ax
mov WORD PTR VIDTR.Base+2,dx
ret
InitIDT ENDP
;----------------------------------------------------------------------------
;入口参数:FS:SI=第一个要初始化的描述符,CX=要初始化的描述符数
;----------------------------------------------------------------------------
InitLDT PROC
ILDT: mov ax,WORD PTR FS:[si].BaseL
movzx eax,ax
shl eax,4
shld edx,eax,16
mov WORD PTR fs:[si].BaseL,ax
mov BYTE PTR fs:[si].BaseM,dl
mov BYTE PTR fs:[si].BaseH,dh
add si,SIZE Desc
loop ILDT
ret
InitLDT ENDP
;----------------------------------------------------------------------------
RCodeSeg ENDS
END Start
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -