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

📄 asm7.asm

📁 保护模式教程源码 The source code of protection mode in dos
💻 ASM
📖 第 1 页 / 共 3 页
字号:
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 + -