操作系统实践(4)——从保护模式返回实模式

好吧,一开始我觉得从保护模式应该就是设置一下cr0然后jmp一下就回到实模式了,这个没必要去实践。不过看到书中里面有些代码觉得有些冗余,然后里面有段话也是没看明白,动手实践才恍然大悟。


于渊在书中写这个例子的思路大概是这样的:
1. 从实模式中跳转进入保护模式。(参考前面几篇)
2. 在保护模式下,访问一个地址偏大点的(实模式寻址范围之外)内存块进行读写,验证一下保护模式寻址范围是不是比实模式寻址大。
3. 返回实模式,返回实模式是这段代码:

; 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  ; 段地址会在程序开始处被设置成正确的值

Code16Len   equ $ - LABEL_SEG_CODE16

; END of [SECTION .s16code]

而跳回实模式之后执行的代码如下:

LABEL_REAL_ENTRY:       ; 从保护模式跳回到实模式就到了这里
    mov ax, cs
    mov ds, ax
    mov es, ax
    mov ss, ax

    mov sp, [SPValueInRealMode]

    in  al, 92h         ;
    and al, 11111101b   ;  | 关闭 A20 地址线
    out 92h, al         ; 

    sti         ; 开中断

    mov ax, 4c00h   ; 
    int 21h         ;   回到 DOS
; END of [SECTION .s16]

问题

  1. 跳回实模式前,设置ds、es、fs、gs、ss有什么作用,跳回实模式之后不是又设置了ds、es等寄存器了么?
    原文描述:

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

    80286开始,保护模式下,为避免每次形成线性地址的时时,都要使用选择子相关的信息而去访问内存,cpu配备了相应的段描述符高速缓冲寄存器。
    所以重新加载一下ds、es、ss相当于清缓存!

  2. 为什么这里跳回实模式的代码段必须是在16位的代码段中?
    原文如下:

    “不能从32位代码段返回实模式,只能从16位代码段中返回。这是因为无法实现从32为位代码段返回时CS高速缓冲寄存器中的属性符合实模式的要求(实模式不能改变段属性)。”

    我的理解,原因还是跟问题1一样,如果在32位的代码段中要跳回16位的实模式,那么设置完cr0后,准备用jmp跳回实模式的地址去,但是此时的cs相关的段描述符高速缓冲里面的属性还是32位保护模式的段属性,必须跟上个问题一样,清一下缓存,但是jmp跳过去之后是16位的实模式了,没法清缓存了!
    后来看了篇文章,与我的理解一致:关于从保护模式切换到实模式的相关说明

  3. 从32位的代码段跳回实模式不行吗?
    从问题2我们知道,保护模式跳回实模式关键的一点,就是要保证跳回实模式后,相关的段的段属性是正确的。之前有个想法就是,从32位的代码段跳回实模式,然后使跳回实模式后代码段属性符合16位实模式下不就行了么?因为跳回去实模式后已经无法修改相关的段属性,所以必须在跳回实模式之前设置好,那么只能在段描述符中设置好,但这有个问题,如果这个描述符标志的是32位的段,从这个32位的段跳回后就无法修改了,所以这个描述符就只能是标志为16位的段。
  4. jmp 0:LABEL_REAL_ENTRY ; 段地址会在程序开始处被设置成正确的值这怎么实现的?
    好吧,这是个小技巧。思路是这样,当这块代码读入内存后,直接修改内存中这个指令。(指令与数据,只是人为的区分,在内存中,它们就都只是二进制数据)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值