免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 4251 | 回复: 1
打印 上一主题 下一主题

从保护模式到实模式的问题 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-10-23 13:15 |只看该作者 |倒序浏览
在《自己动手写操作系统》一书上看到一段代码,从实模式跳到保护模式,再从保护模式跳回实模式。
从保护模式跳回实模式这一块不是很明白。

书中提到“在准备结束保护模式回到实模式前,需要加载一个合适的描述符选择子到有关的段寄存器,以使对应段描述符高速缓冲寄存器中案有合适的段界限和属性。”
(1)请问:实模式下还要用到描述符吗?实模式下寻址直接用CS*4+IP不就完事了吗?为什么还得使“描述符高速缓冲寄存器中案有合适的段界限和属性”?

书中还提到“不能从32位代码段返回实模式,只能从16位代码段中返回。这是因为无法实现从32为位代码段返回时CS高速缓冲寄存器中的属性符合实模式的要求(实模式不能改变段属性)”
(1)这句话又是什么意思?16位代码段返回就符合要求了??16位,32位代码段除了操作数宽度还有什么区别?


返回实模式的一段代码:
最后有一跳指令:jmp 0:LABEL_REAL_ENTRY
最开始在实模式下时,修改了这条指令,将实模式下CS的值保存在“0”的位置


; 16 位代码段. 由 32 位代码段跳入, 跳出后到实模式
[SECTION .s16code]
ALIGN        32

[BITS        16]
LABEL_SEG_CODE16:
        ; 跳回实模式:
        mov        ax, SelectorNormal
        mov        ds, ax
        mov        es, ax
        mov        fs, ax
        mov        gs, ax
        mov        ss, ax

        mov        eax, cr0
        and        al, 11111110b
        mov        cr0, eax

LABEL_GO_BACK_TO_REAL:
        jmp        0:LABEL_REAL_ENTRY;


请各位帮我解惑...
谢谢!

论坛徽章:
0
2 [报告]
发表于 2007-10-24 22:58 |只看该作者
原帖由 forandom 于 2007-10-23 13:15 发表
书中提到“在准备结束保护模式回到实模式前,需要加载一个合适的描述符选择子到有关的段寄存器,以使对应段描述符高速缓冲寄存器中案有合适的段界限和属性。”
(1)请问:实模式下还要用到描述符吗?实模式下寻址直接用CS*4+IP不就完事了吗?为什么还得使“描述符高速缓冲寄存器中案有合适的段界限和属性”?


答:此本说得的确不错,在返回实模式之前确实要加载合适 segment descriptor 进入各个 segment 寄存器。
    是必须要这么做,因为,在进入实模式后,segment 寄存器的 limit 及 attributes 就不能改变了。
    例如:在现代的 OS中,保护模式下 CS/DS 等的 limit 一般都为 0xFFFFFFFF,attribute 中 D 位是 1,也就是 32 位代码的。
    实模式下 limit 必须为 0xFFFF, D 须清 0 ,即 16 位。



原帖由 forandom 于 2007-10-23 13:15 发表
书中还提到“不能从32位代码段返回实模式,只能从16位代码段中返回。这是因为无法实现从32为位代码段返回时CS高速缓冲寄存器中的属性符合实模式的要求(实模式不能改变段属性)”
(1)这句话又是什么意思?16位代码段返回就符合要求了??16位,32位代码段除了操作数宽度还有什么区别?

答:这一点上,此书说错了。当然可以从 32 位代码返回实模式了。在 descriptor 中可以设定目标代码段是 32 bit 还是 16 bit 。
    descriptor 中的 D 位,就是用于这一目的。descriptor 的 G 位清0,limit 设为 FFFF,就符合了实模式代码的要求。


原帖由 forandom 于 2007-10-23 13:15 发表
返回实模式的一段代码:
最后有一跳指令:jmp 0:LABEL_REAL_ENTRY
最开始在实模式下时,修改了这条指令,将实模式下CS的值保存在“0”的位置


答:在各方面条件都准备好之后,最后一跳就返回到实模式下
下面这段代码:
  1. [SECTION .s16code]
  2. ALIGN        32

  3. [BITS        16]
  4. LABEL_SEG_CODE16:
  5.         ; 跳回实模式:
  6.         mov        ax, SelectorNormal
  7.         mov        ds, ax
  8.         mov        es, ax
  9.         mov        fs, ax
  10.         mov        gs, ax
  11.         mov        ss, ax

  12.         mov        eax, cr0
  13.         and        al, 11111110b
  14.         mov        cr0, eax

  15. LABEL_GO_BACK_TO_REAL:
  16.         jmp        0:LABEL_REAL_ENTRY;
复制代码


这段代码无须搞成 16 位模式,和 32 位下一样。
在还没 jmp 之前,可以说此时在保护摸式的残骸之中,此时 CR0.PG 已经被清 0,属于在实模式与保护摸式的混沌之中。
执行 jmp 后,就脱离了残骸,回到了实模式之中
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP