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

📄 asm11.asm

📁 保护模式教程源码 The source code of protection mode in dos
💻 ASM
📖 第 1 页 / 共 2 页
字号:
                REPT    256                       ;对应256个入口
                IF      Count EQ 21h
Ent21H          LABEL   BYTE                      ;在第21H项处定义标号Ent21H
                ENDIF
                push    bp
                mov     bp,Count                  ;置中断向量号到BP
                jmp     Process                   ;都转统一的处理程序
Count           =       Count+1
                ENDM
Process:        push    bp                        ;保存BP
                mov     bp,sp                     ;堆栈指针送BP
                push    eax
                push    ebx                       ;保存EAX、EBX
                ;在V86堆栈顶形成返回点的现场
                mov     ax,VAllMem_Sel            ;转载描述最低1M字节线性地址
                mov     ds,ax                     ;  空间的描述符选择子
                xor     eax,eax
                mov     ax,Psp                    ;修改在V86任务0级堆栈中保存
                sub     ax,3*2                    ;  的3级堆栈的指针,减3个字
                mov     Psp,ax                    ;  即在栈顶空出3个字
                xor     ebx,ebx
                mov     bx,Pss                    ;使EBX指向V86堆栈顶
                shl     ebx,4
                add     ebx,eax
                mov     ax,Pip                    ;把保存在0级堆栈中的返回地址
                mov     WORD PTR [ebx],ax         ;的偏移部分送V86堆栈
                mov     ax,Pcs
                mov     WORD PTR [ebx+2],ax       ;段值部分送V86堆栈
                mov     ax,Pflag
                mov     WORD PTR [ebx+4],ax       ;标志值送V86堆栈
                ;用对应的中断向量值代替返回地址
                mov     bx,[bp]                   ;取中断向量号
                shl     bx,2                      ;乘4
                mov     ax,[bx]                   ;取实模式下对应中断向量的偏移
                mov     Pip,ax                    ;代替0级堆栈中的EIP
                mov     ax,[bx+2]                 ;取实模式下对应中断向量的段值
                mov     Pcs,ax                    ;代替0级堆栈中的CS
                pop     ebx                       ;恢复现场
                pop     eax
                pop     bp
                pop     bp
                ;从保护方式返回V86方式
                ;先转入对应的中断处理程序,再返回中断发生处
                iretd
TPBegin         ENDP
;----------------------------------------------------------------------------
TPCodeLen       =       $
TPCodeSeg       ENDS
;============================================================================
;V86任务下的通用保护故障处理程序代码段
;----------------------------------------------------------------------------
GPCodeSeg       SEGMENT PARA USE32
                ASSUME  CS:GPCodeSeg
;----------------------------------------------------------------------------
GPBegin         PROC    FAR
                mov     ax,V86Data_Sel
                mov     ds,ax
                mov     si,OFFSET GPErrMess
                mov     ax,Video_Sel
                mov     es,ax
                mov     di,0
                mov     ah,17h
                mov     cx,GPErrMessLen
                cld
GNext:          lodsb
                stosw
                loop    GNext
                add     esp,4
                mov     ax,4c01h
                JUMP16  TPCode_Sel,Ent21H
GPBegin         ENDP
;----------------------------------------------------------------------------
GPCodeLen       =       $
GPCodeSeg       ENDS
;============================================================================
;V86方式执行的8086程序段
V86CodeSeg      SEGMENT PARA USE16
                ASSUME  CS:V86CodeSeg,DS:V86CodeSeg
Message         DB      'V86 is OK!',0dh,0ah,24h
V86Begin        PROC    FAR
                mov     ah,9
                mov     dx,OFFSET Message
                int     21h
                mov     ax,RCodeSeg
                sub     ax,GDTSeg
                mov     dx,OFFSET TSRLine+15
                shr     dx,4
                add     dx,ax
                add     dx,10h
                mov     ax,3100h
                int     21h
V86Begin        ENDP
V86CodeSeg      ENDS
;============================================================================
TempTSSSeg      SEGMENT PARA USE16                ;临时任务的TSS段
                TSS     <>
                DB      0ffh                      ;I/O许可位图结束标志
TempTSSLen      =       $
TempTSSSeg      ENDS
;============================================================================
TempCodeSeg     SEGMENT PARA USE16                ;临时任务的代码段
                ASSUME  CS:TempCodeSeg
;----------------------------------------------------------------------------
Virtual         PROC    FAR
                mov     ax,Normal_Sel
                mov     ds,ax
                mov     es,ax
                mov     fs,ax
                mov     gs,ax
                mov     ss,ax
                mov     ax,TempTSS_Sel            ;装载TR
                ltr     ax
                JUMP16  V86TSS_Sel,0              ;直接切换到演示任务
ToDos:          clts
                mov     eax,cr0                   ;准备返回实模式
                and     al,11111110b
                mov     cr0,eax
                JUMP16  <SEG Real>,<OFFSET Real>
Virtual         ENDP
;----------------------------------------------------------------------------
TempCodeSeg     ENDS
;============================================================================
RDataSeg        SEGMENT PARA USE16                ;实方式数据段
RDataSeg        ENDS
;============================================================================
RCodeSeg        SEGMENT PARA USE16
                ASSUME  CS:RCodeSeg,DS:RCodeSeg
;----------------------------------------------------------------------------
VGDTR           PDesc   <GDTLen-1,>               ;GDT伪描述符
VIDTR           PDesc   <IDTLen-1,>               ;IDT伪描述符
NORVIDTR        PDesc   <>                        ;用于保存原IDTR值
SPVar           DW      ?                         ;用于保存实方式下的SP
SSVar           DW      ?                         ;用于保存实方式下的SS
;----------------------------------------------------------------------------
Start           PROC
                mov     ax,RCodeSeg
                mov     ds,ax
                cld
                call    InitGDT                   ;初始化全局描述符表GDT
                call    InitIDT                   ;初始化中断描述符表IDT
                mov     ax,V86LDTSeg
                mov     fs,ax
                mov     cx,V86LDNum
                mov     si,OFFSET VLDT
                call    InitLDT
                mov     ax,IntFFLDTSeg
                mov     fs,ax
                mov     cx,IntFFLDNum
                mov     si,OFFSET FLDT
                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,cs
                mov     ds,ax
                lss     sp,DWORD PTR SPVar        ;又回到实方式
                lidt    QWORD PTR NORVIDTR
                sti
                mov     ax,4c00h
                int     21h
Start           ENDP
;----------------------------------------------------------------------------
TSRLine         LABEL   BYTE
;----------------------------------------------------------------------------
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
;----------------------------------------------------------------------------
;入口参数:FS:SI=第一个要初始化的描述符,CX=要初始化的描述符数
;----------------------------------------------------------------------------
InitLDT         PROC
                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    InitLDT
                ret
InitLDT         ENDP
;----------------------------------------------------------------------------
InitIDT         PROC
                push    ds
                mov     ax,IDTSeg
                mov     ds,ax
                mov     cx,256-1
                mov     si,OFFSET IDT
                mov     ax,OFFSET TPBegin
IIDT1:          cmp     cx,256-1-13
                jz      IIDT2
                mov     [si],ax
IIDT2:          add     si,8
                add     ax,7
                loop    IIDT1
                pop     ds
                mov     bx,16
                mov     ax,IDTSeg
                mul     bx
                mov     WORD PTR VIDTR.Base,ax
                mov     WORD PTR VIDTR.Base+2,dx
                ret
InitIDT         ENDP
;----------------------------------------------------------------------------
RCodeSeg        ENDS
                END     Start

⌨️ 快捷键说明

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