📄 00000002.htm
字号:
<HTML><HEAD> <TITLE>BBS水木清华站∶精华区</TITLE></HEAD><BODY><CENTER><H1>BBS水木清华站∶精华区</H1></CENTER> <BR> ┌┐┌┐∞ <BR>【 80386 保护模式简介三 】 ┘└┘└┘ <BR>========================================================================== <BR>前言: <BR> <BR> 前面两集主要是要告诉各位有关 IDT.GDT 的用法 ,虽然这样已经可以简单的进 <BR>入保护模式 ,但是它还不足以让你撰写程式 ,因此笔者还必需往下继续叙说 ,不过再 <BR>往下讲之前 ,又有一票烦且杂的观念要说 ,本篇还是继续在"观念"上打转 ,读者千万 <BR>不要以为本篇又是「干古」 ,如果本篇不懂的话 ,後面的精彩文章您大概也看不懂 , <BR>笔者会尽量把文章写到容易懂的范围。 <BR> <BR>-------------------------------------------------------------------------- <BR>┌————————┐ <BR>│80386 暂存器介绍│ <BR>└————————┘ <BR> <BR> 80386 的暂存器除了扩充成 32 位元以外 ,亦增加了许多新的暂存器 ,除了一般 <BR>使用者暂存器(AX.BX....SI.DI)各位已经了解以外 ,也增加了系统暂存器、以及扩充 <BR>的旗标 暂存器....等等。 <BR> <BR> <BR>A.使用者暂存器 → EAX.EBX.ECX.EDX.ESI,EDI.EBP.ESP <BR> <BR>B.指令指标暂存器 → CS.EIP 两个暂存器 <BR> <BR>C.区段暂存器 → CS.SS.DS.ES.FS.GS <BR> 虽然 80386 已经进入 32 位元时代 ,但是这几个暂存器仍是 16 位元的 ,且多 <BR> 了 FS.GS 两个暂存器 ,这两个暂存器并无特殊意义 ,各位可以把它当做 DS.ES <BR> 来看待。 <BR> <BR>D.系统暂存器 <BR> A. 控制暂存器:包含 CR0.CR2.CR3 三个 ,各位可能看到漏了一个 CR1 ,原因是 <BR> 386.486.586 都没有此暂存器 <BR> B. 除错暂存器:包含 DR0.DR1.DR2.DR3.DR6.DR7 共六个 ,也是漏了 DR4.DR5 两 <BR> 个 ,原因同上 <BR> C. 保护模式分段控制:IDT.GDT.LDT.TR <BR> <BR>-------------------------------------------------------------------------- <BR>┌————┐ <BR>│工作切换│ <BR>└————┘ <BR> <BR> 当您设定某些系统暂存器以後 ,电脑并不会马上反应所设定的工作 ,必需透过工 <BR>作切换的动作才会起动 ,这个工作切换很难难用文字表达 ,笔者认为工作切换就是等 <BR>级切换的动作。可造成工作切换的指令包含 INT_X 、JMP TSS区段...等 ,其中INT_X <BR>是指在 V86 下的程式若发生中断 ,电脑会自动切换至保护模式 ,并呼叫保护模式下的 <BR>中断处理程式 ,再由保护模式下的程式决定是否呼叫原来 V86 下的中断向量表 ,而 <BR>这切换到保护模式、再切回 V86 下 , 共发生两次工作切换...... <BR> <BR>┌——┐ <BR>│等级│ <BR>└——┘ <BR> <BR> 保护模式下 ,等级共有 0.1.2.3 四个等级 ,其中第0级等级最高 ,第3级最低 , <BR>而0级因为是最高等级 ,因此也有人称为「特权等级」 ,而应用程式的等级为多少呢? <BR>这表示在 EFLAG 的 IOPL (BIT12.13) 里 ,在 V86 下的等级多半是最低的第3级 ,所 <BR>以此值为 '11'。 <BR> <BR> 或许各位会认为自己去修改这个旗标将自己的等级调高就好了 ,事实上改好後还 <BR>要经过工作切换的动作 ,等级才能被修改 ,而经过工作切换的动作後 ,你的程式控制 <BR>权将转交给别人 ;再简单的说 ,发生 INT_X 时 ,电脑会将等级切换成最高等级(事实 <BR>上是由中断表上决定的) ,并进入保护模式 ,之後保护模式的程式再来决定将使用者的 <BR>EFLAG 切成什麽等级 ,然後再 IRETD切回 V86 ,於是应用程式根本抢不过最早进入保 <BR>护模式的家伙。(这样你有办法在V86下抢到最高等级吗....不可能嘛) <BR> <BR> 等级的高低可以决定自己有多少控制权 ,例如等级最高的人才可以读写系统暂存 <BR>器 ,其馀的人想读写系统暂存器都会发生 General Protection Error 0D ,你可以把 <BR>它想像成等级不够 ,却要读取系统资源 ,会发生 INT_0D ,而原本这行指令将不会被 <BR>执行 ,而堆叠里所摆的 EIP 值也停在这行上面 ,如果 INT_0D 的处理程式不去跳过 <BR>这个指令 ,则会永远停在这个指令里(形同当机)。 <BR> <BR> 在 V86 下发生中断时 ,会自动 PUSH EIP.CS.EFLAG.ESP.SS......数个暂存器 , <BR>并自动将 SS.ESP 的值替换 ,以免发生中断时 ,会动用到 V86 的堆叠 ,可是如果发 <BR>生的是 General Protection Error(俗称异常),则会在 PUSH EIP 之前再多摆入一 <BR>个DWORD 的错误代码 ,如果您的程式在 IRETD 前不减去这个可能存在的错误代码 , <BR>则会发生不可预知的後果。这也是保护模式下的程式不好写的原因之一。 而SS与ESP <BR>所替换的值 ,则是最初进入保护模式後 ,由最高等级的人决定的(摆於TSS区段)。 <BR> <BR> 第二集里笔者有介绍 GDT 表 ,其中有个 93 代表可写区段 ,如果设成 89 ,则表 <BR>示此区段是 TSS 表格 ,再由 TR 暂存器来指定发生中断时 ,取用那一个区段的表格. <BR> <BR>举例来说 ,下面是 GDT 表格 <BR> <BR>gdttab db 000h,000h,000h,000h,000h,000h,000h,000h ;00 <BR> db 0ffh,0ffh,000h,000h,000h,09bh,000h,000h ;08 <BR> db 0ffh,0ffh,000h,000h,000h,093h,08fh,000h ;10 <BR> db 0ffh,0ffh,000h,000h,000h,089h,000h,000h ;18 <BR> db 0ffh,0ffh,000h,000h,000h,089h,000h,000h ;20 <BR> db 0ffh,0ffh,000h,000h,000h,093h,000h,000h ;28 <BR> db 0ffh,007h,000h,000h,000h,093h,000h,000h ;30 <BR> db 0ffh,0ffh,000h,080h,00bh,093h,000h,000h ;38 <BR> db 0ffh,0ffh,000h,000h,000h,093h,000h,000h ;40 <BR> <BR> 我们可以看到 18.20 两个 Selector 正好就是 89h ,也就是说它们俩个都可以是 <BR>TSS 描述表格 ,如果 MOV AX,0018、LTR AX ,则表示发生工作切换时 ,取用 0018 的 <BR>描述表格。 <BR> <BR>-------------------------------------------------------------------------- <BR>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -