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

📄 asm9.asm

📁 保护模式教程源码 The source code of protection mode in dos
💻 ASM
📖 第 1 页 / 共 2 页
字号:
                DB      11111011b                 ;端口40h--47h
                DB      3 DUP(0ffh)               ;端口48h--5fh
                DB      11111101b                 ;端口60h--67h
                DB      0                         ;端口68h--6fh
                DB      0ffh                      ;I/O许可位图结束标志
TestTSSLen      =       $
TestTSSSeg      ENDS
;----------------------------------------------------------------------------
;测试任务的堆栈段
TestStackSeg    SEGMENT PARA USE32
TestStackLen    =       1024
                DB      TestStackLen DUP(0)
TestStackSeg    ENDS
;----------------------------------------------------------------------------
;测试任务的代码段
TestCodeSeg     SEGMENT PARA USE32
                ASSUME  CS:TestCodeSeg
;----------------------------------------------------------------------------
Test3Begin      PROC    FAR
                cli                               ;I/O敏感指令
                clts                              ;特权指令
                iretd
                jmp     Test3Begin
Test3Begin      ENDP
;----------------------------------------------------------------------------
TestBegin       PROC    FAR
                mov     al,0b6h                   ;使扬声器发出一长声
                out     43h,al
                mov     al,2
                out     42h,al
                mov     al,34h
                out     42h,al
                in      al,61h
                mov     ah,al
                or      al,3
                out     61h,al
                mov     ecx,1234567h
                loop    $
                mov     al,ah
                out     61h,al
                iretd
                jmp     TestBegin
TestBegin       ENDP
;----------------------------------------------------------------------------
TestCodeLen     =       $
TestCodeSeg     ENDS
;----------------------------------------------------------------------------
;演示任务TSS段
DemoTSSSeg      SEGMENT PARA USE16
DemoTaskSS      TSS     <>
                DB      0ffh                      ;I/O许可位图结束字节
DemoTSSLen      =       $
DemoTSSSeg      ENDS
;----------------------------------------------------------------------------
;演示任务的堆栈段
DemoStackSeg    SEGMENT PARA USE32
DemoStackLen    =       1024
                DB      DemoStackLen DUP(0)
DemoStackSeg    ENDS
;----------------------------------------------------------------------------
;演示任务的代码段
DemoCodeSeg     SEGMENT PARA USE32
                ASSUME  CS:DemoCodeSeg
;----------------------------------------------------------------------------
DemoBegin       PROC    FAR
                mov     ax,ToTestTSS_Sel
                mov     ds,ax
                mov     ebx,OFFSET TestTaskSS
                ;把测试任务1的入口点,堆栈指针和标志值(含IOPL)填入测试任务TSS
                mov     WORD PTR [ebx].TRSS,Test1Stack_Sel
                mov     DWORD PTR [ebx].TRESP,TestStackLen
                mov     WORD PTR [ebx].TRCS,Test1Code_Sel
                mov     DWORD PTR [ebx].TREIP,OFFSET TestBegin
                mov     DWORD PTR [ebx].TREFLAG,IOPL1
                ;通过任务门调用测试任务
                CALL32  Test_Sel,0
                ;把测试任务2的入口点,堆栈指针和标志值(含IOPL)填入测试任务TSS
                mov     WORD PTR [ebx].TRSS,Test2Stack_Sel
                mov     DWORD PTR [ebx].TRESP,TestStackLen
                mov     WORD PTR [ebx].TRCS,Test2Code_Sel
                mov     DWORD PTR [ebx].TREIP,OFFSET TestBegin
                mov     DWORD PTR [ebx].TREFLAG,IOPL1
                ;通过任务门调用测试任务
                CALL32  Test_Sel,0
                ;把测试任务TSS描述符内的属性置为"可用"
                mov     ax,ToGDT_Sel
                mov     fs,ax
                mov     fs:TestTSS.Attributes,AT386TSS
                ;把测试任务3的入口点,堆栈指针和标志值(含IOPL)填入测试任务TSS
                mov     WORD PTR [ebx].TRSS,Test3Stack_Sel
                mov     DWORD PTR [ebx].TRESP,TestStackLen
                mov     WORD PTR [ebx].TRCS,Test3Code_Sel
                mov     DWORD PTR [ebx].TREIP,OFFSET Test3Begin
                mov     DWORD PTR [ebx].TREFLAG,IOPL2
                ;通过任务门调用测试任务
                CALL32  Test_Sel,0
                ;把测试任务TSS描述符内的属性置为"可用"
                mov     ax,ToGDT_Sel
                mov     fs,ax
                mov     fs:TestTSS.Attributes,AT386TSS
                ;把测试任务4的入口点,堆栈指针和标志值(含IOPL)填入测试任务TSS
                mov     WORD PTR [ebx].TRSS,Test3Stack_Sel
                mov     DWORD PTR [ebx].TRESP,TestStackLen
                mov     WORD PTR [ebx].TRCS,Test3Code_Sel
                mov     DWORD PTR [ebx].TREIP,OFFSET Test3Begin
                mov     DWORD PTR [ebx].TREFLAG,IOPL3
                ;通过任务门调用测试任务
                CALL32  Test_Sel,0
                JUMP32  TempCode_Sel,<OFFSET ToDOS>
DemoBegin       ENDP
;----------------------------------------------------------------------------
DemoCodeLen     =       $
DemoCodeSeg     ENDS
;----------------------------------------------------------------------------
TempCodeSeg     SEGMENT PARA USE16                ;演示任务的临时代码段
                ASSUME  CS:TempCodeSeg
;----------------------------------------------------------------------------
Virtual         PROC    FAR
                ;置数据段寄存器为空
                mov     ax,0
                mov     ds,ax
                mov     es,ax
                mov     fs,ax
                mov     gs,ax
                ;置堆栈指针
                mov     ax,DemoStack_Sel
                mov     ss,ax
                mov     esp,DemoStackLen
                ;置任务寄存器
                mov     ax,DemoTSS_Sel
                ltr     ax
                ;转演示代码段
                JUMP16  DemoCode_Sel,DemoBegin
ToDOS:          clts
                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
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
                lgdt    QWORD PTR VGDTR           ;装载GDTR
                mov     SSVar,ss                  ;保存堆栈指针
                mov     SPVar,sp
                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
;----------------------------------------------------------------------------
RCodeSeg        ENDS
                END     Start

⌨️ 快捷键说明

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