📄 00000004.htm
字号:
<HTML><HEAD> <TITLE>BBS水木清华站∶精华区</TITLE></HEAD><BODY><CENTER><H1>BBS水木清华站∶精华区</H1></CENTER> <BR> ┌┐┌┐∞ <BR>【 80386 保护模式简介五 】 ┘└┘└┘ <BR>========================================================================== <BR>前言: <BR> 底下是进入保护模式、进入 V86 的精简范例 ,执行前请确定 CPU 是处在真实模 <BR>式 ,程式码因为用到 386 指令 ,请用 TASM 3.1 来编译。 <BR>-------------------------------------------------------------------------- <BR>┌——————┐ <BR>│进入保护模式│ <BR>└——————┘ <BR> <BR> 进入保护模式的程式范例 ,其目地是进入保护模式 ,并在保护模式下用绝对记忆 <BR>体读写的方式 ,直接将 'Protection Mode !' 字串写入 Video Ram (B800:0000) , <BR>本程式以最精简的方式撰写 ,没有任何错误处理 ,因此请确定电脑现在处在真实模式 <BR>下才可执行本程式。(禁挂 EMM 系保护模式软体) <BR> <BR> 程式流程如下:(底下所指记忆体位址皆为 32bit 绝对位址) <BR> <BR> 1. 设定 GDTtab 表所在的记忆体位址填入 GDTadds <BR> <BR> 2. 设定 Selector 0008 的记忆体起始位址就是现在 CS 的记忆体位址 <BR> 设定 Selector 0010 的记忆体起始位址就是现在 CS 的记忆体位址 <BR> Selector 0018 的记忆体起始位址就是 000B8000 = (B800:0000) <BR> <BR> 3. 执行 LGDT FWORD PTR CS:GDTadds 告诉 CPU 一但进入保护模式 ,各 <BR> 区段的记忆体起始位址、长度 <BR> <BR> 4. 设定 CR0 的 Bit0 = '1' ,并透过 JMP 指令进入保护模式 <BR> ※ 进入保护模式後 ,DS.ES.SS.CS.GS.FS 等等暂存器定址方式不再 <BR> 是 Segment ,而变成 Selector <BR> <BR> 5. 秀字 将 0010:MSG_1 搬到 0018:0000 <BR> 意即将 'Protection Mode !' 字串搬到 Video Ram 去 <BR> <BR> 6. 设定 CR0 的 Bit0 = '0' ,并透过 JMP 指令回到真实模式 <BR> ※ 回到真实模式後 ,DS.ES.SS.CS.GS.FS 等等暂存器定址方式不再 <BR> 是 Selector ,而变成 Segment <BR> <BR> 5. 秀字 将 CS:MSG_2 搬到 B800:00A0 <BR> 意即将 'Return Real Mode !' 字串搬到 Video Ram 去 <BR> <BR> 6. 结束程式 <BR> <BR>----------------------------- P.ASM ------------------------------------ <BR>code segment <BR> assume cs:code,ds:code <BR>.386p <BR>start proc near <BR> jmp next <BR>gdtadds dw 001fh,0000h,0000h <BR>gdttab db 000h,000h,00h,00h,00h,00h,00h,00h ;00 Null <BR> db 0ffh,0ffh,00h,00h,00h,9bh,00h,00h ;08 PRG Seg <BR> db 0ffh,0ffh,00h,00h,00h,93h,00h,00h ;10 PRG Seg <BR> db 0ffh,0ffh,00h,80h,0bh,93h,00h,00h ;18 B8000 <BR>msg_1 db 'Protection Mode !' <BR>msg_2 db 'Return Real Mode !' <BR> <BR>next : <BR> xor eax,eax ; <BR> xor ebx,ebx ; <BR> mov ax,cs ;设定 GDTadds <BR> shl eax,04h ; <BR> mov bx,offset gdttab ; <BR> add eax,ebx ; <BR> mov di,offset gdtadds+02h ; <BR> mov cs:[di],eax ; <BR> NOP <BR> xor eax,eax ; <BR> xor ebx,ebx ; <BR> mov ax,cs ; <BR> shl eax,04h ; <BR> mov di,offset gdttab+08h ;设定 GDTtab 内的 <BR> mov si,offset gdttab+10h ;Selector 0008 及 0010 <BR> mov cs:[di+02h],ax ;两个段落的记忆体起始位址 <BR> mov cs:[si+02h],ax ; <BR> shr eax,10h ; <BR> mov cs:[di+04h],al ; <BR> mov cs:[si+04h],al ; <BR> mov cs:[di+07h],ah ; <BR> mov cs:[si+07h],ah ; <BR> NOP <BR> cli <BR> lgdt fword ptr cs:gdtadds ;载入 GDT 表格 <BR> mov eax,cr0 ; <BR> or al,01h ; <BR> mov cr0,eax ; <BR> jmp protection_mode ;进入保护模式 <BR>protection_mode : ; <BR> mov ax,0010h ; <BR> mov ds,ax ; <BR> mov si,offset msg_1 ; <BR> mov ax,0018h ;将 0010:MSG_1 搬到 0018:0000 <BR> mov es,ax ; <BR> mov di,0000h ; <BR> mov ah,70h ; <BR> mov cx,0011h ; <BR> cld ; <BR>L1 : ; <BR> lodsb ; <BR> stosw ; <BR> loop L1 ; <BR> NOP <BR> mov eax,cr0 ; <BR> and al,0feh ; <BR> mov cr0,eax ;回到真实模式 <BR> jmp return_real_mode ; <BR>return_real_mode : ; <BR> sti <BR> mov ax,cs ; <BR> mov ds,ax ; <BR> mov si,offset msg_2 ; <BR> mov ax,0b800h ; <BR> mov es,ax ;将 CS:MSG_2 搬到 B800:00A0 <BR> mov di,00a0h ; <BR> mov ah,70h ; <BR> mov cx,0012h ; <BR> cld ; <BR>L2 : ; <BR> lodsb ; <BR> stosw ; <BR> loop L2 ; <BR> mov ax,4cffh <BR> int 21h <BR>start endp <BR>code ends <BR> end start <BR>-------------------------------------------------------------------------- <BR>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -