实模式保护模式:实模式与保护模式切换实例



2.有关实现步骤注释
(1)切换到保护模式准备工作
建立全局描述符表这里全局描述符表含有两个16位数据段描述符、个16位代码段描述符和个16位堆栈段描述符此外GDT中还有个32位代码段描述符描述32位代码段该描述符属性字段中D位为1
(2)由实模式切换到保护模式
由实模式切换到保护模式32位代码段思路方法和切换到16位代码段思路方法相同由保护模式16位代码段切换回实模式思路方法和例子相似
在保护模式下通过如下直接段间转移指令从32位代码段切换到16位代码段:
JUMP32 Code16_Sel ,< OFFSET SPM16 >
从该宏指令定义可知该转移指令含48位指针其高16位是16位代码段选择子低32位是16位代码段入口偏移 该指令在32位方式下预取并执行 由于在32位方式下执行所以要使用48位指针
(3)显示指定内存区域内容
在本例子中采用直接写显示缓冲区思路方法实现显示假设显示缓冲区开始物理地址是0B8000H 3号文本显示模式在屏幕行进行显示
3.特别介绍说明
本例子在保护方式下使用了涉及堆栈操作指令因此建立了个16位保护模式下堆栈段
本例子仍作了大量简化处理如:没有建立IDT和LDT等各特权级均是0也没有采用分页管理机制
从本例子GDT中可见两个数据段界限都是根据实际大小而设置从源代码段CSEG3可见在切换到实模式的前个指向似乎没有用数据段描述符Normal选择子装载到DS和ES这是为什么呢?
实模
式下
段描
述符
高速
缓冲
寄存

内容 段寄存器 段基地址 段界限(固定) 段属性(固定)
存在性 特权级 已存取 粒度 扩展方向 可读性 可写性 可执行 堆栈大小 致特权
CS 当前CS*16 0000FFFFH Y 0 Y B U Y Y Y - N
SS 当前SS*16 0000FFFFH Y 0 Y B U Y Y N W -
DS 当前DS*16 0000FFFFH Y 0 Y B U Y Y N - -
ES 当前ES*16 0000FFFFH Y 0 Y B U Y Y N - -
FS 当前FS*16 0000FFFFH Y 0 Y B U Y Y N - -
GS 当前GS*16 0000FFFFH Y 0 Y B U Y Y N - -

在分段管理机制文中已介绍过每个段寄存器都配有段描述符高速缓冲寄存器这些高速缓冲寄存器在实方式下仍发挥作用只是内容上和保护模式下有所区别如上表所示其中“Y”表示“是”; “N”表示“否”;“B”表示字节;“U”表示向上扩展“W”表示以字方式操作堆栈段基地址仍是 32位其值是相应段寄存器值(段值)乘以16在把段值装载到段寄存器时刷新由于其值是16位段值乘上16所以在实模式下基地址实际上有效位只有20位每个段32位段界限都固定为0FFFFH段属性许多位也是固定所谓固定是指在实方式下不可设置这些属性值只能继续沿用保护方式下所设置因此在准备结束保护模式回到实模式的前要通过加载个合适描述符选择子到有关段寄存器以使得对应段描述符高速缓冲寄存器中含有合适段界限和属性本例子GDT中描述符Normal就是这样个描述符在返回实模式的前把对应选择子Normal_Sel加载到DS和ES就是此目由于SS段描述符中内容已符合实模式需要所以尽管也改变了SS但不需要重新加载SS(本例子中重新加载了SS这除了稍增加运行时间外并没有什么坏处)16位代码段描述符中内容也符合实模式需要所以在通过16位代码段返回实模式时CS段描述符中内容也符合实模式要求需要注意不能从32位代码段返回实模式这是无法实现从32位代码段返回时CS高速缓冲寄存器中属性符合实模式要求(实模式不能改变段属性)顺便说以下例子描述符都是符合实模式要求段描述符高速缓冲寄存器中含有合适段界限


4.有关32位代码段设计介绍说明
在32位代码段中缺省操作数大小是32位缺省存储单元地址大小是32位由于串操作指令使用指针寄存器是ESI和EDILOOP指令使用计数器是ECX所以在代码段CSEG2中为了使用串操作指令对ESI和EDI等寄存器赋初值请比较代码段CSEG3中相关片段和例子相关片段它们是16位代码段
Tags:  系统实模式 实模式 实模式和保护模式 实模式保护模式

延伸阅读

最新评论

发表评论