【os-tutorial】十一,进入32-bit模式

理论基础

进入32-bit保护模式需要进行以下几个步骤:

  1. 关闭所有中断(不响应所有中断)
  2. 导入设计好的GDT
  3. 将CPU控制寄存器CR0的bit0设置为1
  4. 通过一个设计好的jmp指令跳跃到保护模式中
  5. 更新所有的段寄存器
  6. 更新栈设置
  7. 调用一个标签,该标签包含32bit保护模式下第一个有用的指令
    接下来对每个步骤进行说明.

1.关闭中断

使用cli指令可以屏蔽所有可屏蔽中断

2.导入设计好的GDT

在设计GDT那一节,我们设计了GDT描述符,用来确定GDT,而使用lgdt可以将GDT描述符导入GDT寄存器(GDTR,6个字节)中,之后GDTR就可以告诉CPU,GDT的各个参数为多少.

3.将CPU控制寄存器CR0的bit0设置为1

CR0是CPU的控制寄存器,其结构如下图
在这里插入图片描述
其中bit0,即PE(Protected Mode Enable)负责使能保护模式.

4.通过一个设计好的jmp指令跳跃到保护模式中

进入保护模式运行的前提是,“进入GDT中的代码段”,因此使用jmp CODESEG:某标签即可进入GDT中的代码段.

5.更新所有的段寄存器

将所有段寄存器置为GDT中的数据段DATASEG

6.更新栈设置

将栈底和栈顶更新为32-bit模式下的栈底和栈顶

7.调用一个标签,该标签包含32bit保护模式下第一个有用的指令

本节保护模式下第一个有用的指令为32-bit模式下的VGA打印函数.

源码

[bits 16]
switch_to_pm:
    cli; 1. 禁止所有中断
    lgdt [gdt_descriptor] ; 2. 载入GDT描述符, 注意GDT描述符有6个字节
    mov eax, cr0
    or eax, 0x1 ; 3. 使能保护模式,CR0的bit0
    mov cr0, eax
    jmp CODE_SEG:init_pm ; 4. 跳转到另一个段

[bits 32]
init_pm: ;现在处于32bit指令模式
    ; 5. 更新段寄存器内的值
    mov ax, DATA_SEG 
    mov ds, ax
    mov ss, ax
    mov es, ax
    mov fs, ax
    mov gs, ax

    mov ebp, 0x90000 ; 6. 在空闲区域设置栈
    mov esp, ebp

    call BEGIN_PM ; 7. 调用一个标签,该标签包含32bit保护模式下第一个有用的指令

32bit-main.asm 主程序

[org 0x7C00]

    mov bp, 0x9000; 设置栈
    mov sp, bp

    mov bx, MSG_REAL_MODE
    call print

    call switch_to_pm
    jmp $ ; 事实上,不会执行到这里

%include "../05-bootsector-functions-strings/boot_sect_print.asm"
%include "../09-32bit-gdt/32bit-gdt.asm"
%include "../08-32bit-print/32bit-print.asm"
%include "32bit-switch.asm"

[bits 32]
BEGIN_PM: ; 切换到保护模式之后就会执行这个标签
    mov ebx, MSG_PORT_MODE
    call print_string_pm ; 记得这个函数会将内容打印到屏幕左上角
    jmp $


MSG_REAL_MODE db "Started in 16-bit real mode", 0
MSG_PORT_MODE db "Loaded 32-bit protected mode", 0 


times 510 - ($ - $$) db 0
dw 0xAA55

实验结果

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值