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

📄 asm7.asm

📁 保护模式教程源码 The source code of protection mode in dos
💻 ASM
📖 第 1 页 / 共 3 页
字号:
;名称:ASM7.ASM
;功能:模拟异常和演示异常处理
;编译:TASM ASM7.ASM
;连接:TLINK ASM7.OBJ
;----------------------------------------------------------------------------
INCLUDE         386SCD.INC
;----------------------------------------------------------------------------
GDTSeg          SEGMENT PARA USE16                ;全局描述符表数据段(16位)
;----------------------------------------------------------------------------
                ;全局描述符表GDT
GDT             LABEL   BYTE
                ;空描述符
DUMMY           Desc    <>
                ;规范段描述符及选择子
Normal          Desc    <0ffffh,,,ATDW,,>
Normal_Sel      =       Normal-GDT
                ;视频缓冲区段描述符(DPL=3)及选择子
VideoBuf        Desc    <0ffffh,8000h,0bh,ATDW,,>
VideoBuf_Sel    =       VideoBuf-GDT
;----------------------------------------------------------------------------
EFFGDT          LABEL   BYTE
                ;临时代码段描述符及选择子
TempCode        Desc    <0ffffh,TempCodeSeg,,ATCE,,>
TempCode_Sel    =       TempCode-GDT
                ;演示代码段描述符及选择子
DemoCode        Desc    <DemoCodeLen-1,DemoCodeSeg,,ATCE,,>
DemoCode_Sel    =       DemoCode-GDT
                ;演示任务局部描述符表段描述符及选择子
DemoLDT         Desc    <DemoLDTLen-1,DemoLDTSeg,,ATLDT,,>
DemoLDT_Sel     =       DemoLDT-GDT
                ;演示任务TSS段描述符及选择子
DemoTSS         Desc    <DemoTSSLen-1,DemoTSSSeg,,AT386TSS,,>
DemoTSS_Sel     =       DemoTSS-GDT
                ;缓冲数据段描述符及选择子
XBuffer         Desc    <BufferLen-1,BufferSeg,,ATDW,,>
XBuffer_Sel     =       XBuffer-GDT
                ;读键盘任务局部描述符表段描述符及选择子
GKeyLDT         Desc    <GKeyLDTLen-1,GKeyLDTSeg,,ATLDT,,>
GKeyLDT_Sel     =       GKeyLDT-GDT
                ;读键盘任务TSS段描述符及选择子
GKeyTSS         Desc    <GKeyTSSLen-1,GKeyTSSSeg,,AT386TSS,,>
GKeyTSS_Sel     =       GKeyTSS-GDT
                ;显示陷阱处理程序代码段描述符及选择子
EchoCode        Desc    <EchoCodeLen-1,EchoCodeSeg,,ATCE,,>
EchoCode_Sel    =       EchoCode-GDT
                ;显示出错码过程代码段描述符及选择子
SubCode         Desc    <SubCodeLen-1,SubCodeSeg,,ATCE,,>
SubCode_Sel     =       SubCode-GDT
                ;其它中断或异常处理程序代码段描述符及选择子
Other           Desc    <OtherCodeLen-1,OtherCodeSeg,,ATCE,,>
Other_Sel       =       Other-GDT
;----------------------------------------------------------------------------
GDTLen          =       $-GDT                     ;全局描述符表长度
GDNum           =       ($-EFFGDT)/(SIZE Desc)    ;需处理基地址的描述符个数
;----------------------------------------------------------------------------
GDTSeg          ENDS                              ;全局描述符表段定义结束
;----------------------------------------------------------------------------
IDTSeg          SEGMENT PARA USE16                ;中断描述符表数据段(16位)
;----------------------------------------------------------------------------
IDT             LABEL   BYTE                      ;中断描述符表
                ;0号陷阱门描述符(对应除法出错故障)
                Gate    <DivBegin,Divide_Sel,,AT386TGate,>
                ;从1--3的3个陷阱门描述符
                REPT    3
                Gate    <OtherBegin,Other_Sel,,AT386TGate,>
                ENDM
                ;4号陷阱门描述符(对应溢出陷阱)
                Gate    <OFBegin,OF_Sel,,AT386TGate,>
                ;从5--0ah的的6个陷阱门描述符
                REPT    6
                Gate    <OtherBegin,Other_Sel,,AT386TGate,>
                ENDM
                ;0bh号陷阱门描述符(对应段不存在故障)
                Gate    <SNPBegin,SNP_Sel,,AT386TGate,>
                ;0ch号陷阱门描述符(对应堆栈段故障)
                Gate    <SSEBegin,SSE_Sel,,AT386TGate,>
                ;0dh号陷阱门描述符(对应通用保护故障)
                Gate    <GPBegin,GP_Sel,,AT386TGate,>
                ;从0eh--0edh的240个陷阱门描述符
                REPT    240
                Gate    <OtherBegin,Other_Sel,,AT386TGate,>
                ENDM
                ;对应0feh号陷阱门描述符(对应显示中断处理程序)
                Gate    <EchoBegin,EchoCode_Sel,,AT386TGate,>
                ;0ffh号任务门描述符(对应读键盘中断处理任务)
                Gate    <,GKeyTSS_Sel,,ATTaskGate,>
;----------------------------------------------------------------------------
IDTLen          =       $-IDT
;----------------------------------------------------------------------------
IDTSeg          ENDS                              ;中断描述符表段定义结束
;----------------------------------------------------------------------------
;读键盘任务局部描述符表段
;----------------------------------------------------------------------------
GKeyLDTSeg      SEGMENT PARA USE16
;----------------------------------------------------------------------------
GLDT            LABEL   BYTE
                ;代码段描述符及选择子
GKeyCode        Desc    <0ffffh,GKeyCodeSeg,,ATCE,,>
GKeyCode_Sel    =       GKeyCode-GLDT+TIL
                ;堆栈段描述符及选择子
GKeyStack       Desc    <GKeyStackLen-1,GKeyStackSeg,,ATDWA,,>
GKeyStack_Sel   =       GKeyStack-GLDT+TIL
;----------------------------------------------------------------------------
GKeyLDNum       =       ($-GLDT)/(SIZE Desc)      ;需初始化基地址的描述符个数
GKeyLDTLen      =       $                         ;局部描述符表段长度
;----------------------------------------------------------------------------
GKeyLDTSeg      ENDS
;----------------------------------------------------------------------------
;读键盘任务TSS段
;----------------------------------------------------------------------------
GKeyTSSSeg      SEGMENT PARA USE16
                DD      0                         ;链接字
                DD      ?                         ;0级堆栈指针
                DW      ?,?
                DD      ?                         ;1级堆栈指针
                DW      ?,?
                DD      ?                         ;2级堆栈指针
                DW      ?,?
                DD      0                         ;CR3
                DW      GKeyBegin,0               ;EIP
                DD      0                         ;EFLAGS
                DD      0                         ;EAX
                DD      0                         ;ECX
                DD      0                         ;EDX
                DD      0                         ;EBX
                DW      GKeyStackLen,0            ;ESP
                DD      0                         ;EBP
                DD      0                         ;ESI
                DD      0                         ;EDI
                DW      Normal_Sel,0              ;ES
                DW      GKeyCode_Sel,0            ;CS
                DW      GKeyStack_Sel,0           ;SS
                DW      Normal_Sel,0              ;DS
                DW      Normal_Sel,0              ;FS
                DW      Normal_Sel,0              ;GS
                DW      GKeyLDT_Sel,0             ;LDTR
                DW      0                         ;调试陷阱标志
                DW      $+2                       ;指向I/O许可位图的偏移
                DB      0ffh                      ;I/O许可位图结束字节
GKeyTSSLen      =       $
GKeyTSSSeg      ENDS
;----------------------------------------------------------------------------
;读键盘任务堆栈段
;----------------------------------------------------------------------------
GKeyStackSeg    SEGMENT PARA USE16
GKeyStackLen    =       1024
                DB      GKeyStackLen DUP(0)
GKeyStackSeg    ENDS
;----------------------------------------------------------------------------
;读键盘任务代码段
;----------------------------------------------------------------------------
GKeyCodeSeg     SEGMENT PARA USE16
                ASSUME  CS:GKeyCodeSeg,DS:RDataSeg,ES:BufferSeg
;----------------------------------------------------------------------------
GKeyBegin       PROC    FAR
                push    ds
                push    es
                push    fs
                push    gs
                mov     ax,Normal_Sel
                mov     ss,ax                     ;准备转实方式
                mov     eax,cr0
                and     al,11111110b
                mov     cr0,eax                   ;转实方式
                JUMP16  <SEG GetKey>,<OFFSET GetKey>
GetKey:         mov     ax,RDataSeg               ;实方式
                mov     ds,ax
                mov     ebp,esp                   ;恢复实方式部分现场
                lss     sp,DWORD PTR SPVar
                lidt    QWORD PTR NORVIDTR
                sti
                mov     dx,OFFSET Mess
                mov     ah,9
                int     21h                       ;显示提示信息
GetKey1:        mov     ah,0
                int     16h                       ;读键盘
                cmp     al,'0'
                jz      GetKey2
                cmp     al,'4'
                jz      GetKey2
                and     al,11011111b              ;小写转大写
                cmp     al,'B'
                jb      GetKey1
                cmp     al,'D'
                ja      GetKey1                   ;只有[0,4,b,c,d]有效
GetKey2:        mov     dl,al
                mov     ah,2
                int     21h                       ;显示所按字符
                mov     ax,BufferSeg
                mov     es,ax
                mov     BYTE PTR es:KeyASCII,dl   ;保存到缓冲数据段
                cli                               ;准备返回保护方式
                lidt    QWORD PTR VIDTR
                mov     eax,cr0
                or      al,1
                mov     cr0,eax
                JUMP16  <GKeyCode_Sel>,<OFFSET GetKeyV>
GetKeyV:        mov     ax,GKeyStack_Sel          ;又进入保护方式
                mov     ss,ax
                mov     esp,ebp
                pop     gs
                pop     fs
                pop     es
                pop     ds
                iretd
                jmp     GKeyBegin
GKeyBegin       ENDP
;----------------------------------------------------------------------------
GKeyCodeLen     =       $
GKeyCodeSeg     ENDS
;----------------------------------------------------------------------------
;其它中断或异常处理程序的代码段
;----------------------------------------------------------------------------

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -