从保护模式到实模式的问题

发布于 2022-09-26 13:05:25 字数 1589 浏览 5 评论 0

在《自己动手写操作系统》一书上看到一段代码,从实模式跳到保护模式,再从保护模式跳回实模式。
从保护模式跳回实模式这一块不是很明白。

书中提到“在准备结束保护模式回到实模式前,需要加载一个合适的描述符选择子到有关的段寄存器,以使对应段描述符高速缓冲寄存器中案有合适的段界限和属性。”
(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;

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

如果没有 2022-10-03 13:05:25

原帖由 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 后,就脱离了残骸,回到了实模式之中

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文