OrangeS一个操作系统的实现--保护模式

以一段汇编代码介绍操作系统进入保护模式:
编译:▹ nasm pmtest1.asm -o pmtest1.bin
参数:软盘映像a.img和Bochs的配置文件bochsrc
写入:将生成的二进制写入软盘映像,▹ dd if=pmtest1.bin of=a.img bs=512 count=1 conv=notrunc
运行:Bochs (补图)

1 ; ==========================================
2 ; pmtest1.asm
3 ; 编译方法:nasm pmtest1.asm -o pmtest1.bin
4 ; ==========================================
5
6 %include ”pm.inc” ; 常量,, 以及一些说明
7
8 org 07c00h
9 jmp LABEL_BEGIN
10
11 [ SECTION .gdt]
12 ; GDT
13 ; 段基址, 段界限 , 属性
14 LABEL_GDT: Descriptor 0, 0, 0 ; 空描述符
15 LABEL_DESC_CODE32: Descriptor 0, SegCode32Len - 1, DA_C + DA_32; 非一致代码段
16 LABEL_DESC_VIDEO: Descriptor 0B8000h, 0ffffh, DA_DRW ; 显存首地址
17 ; GDT 结束
18
19 GdtLen equ $ - LABEL_GDT ; GDT长度
20 GdtPtr dw GdtLen - 1 ; GDT界限
21 dd 0 ; GDT基地址
22
23 ; GDT 选择子
24 SelectorCode32 equ LABEL_DESC_CODE32 - LABEL_GDT
25 SelectorVideo equ LABEL_DESC_VIDEO - LABEL_GDT
26 ; END of [SECTION .gdt]
27
28 [ SECTION .s16]
29 [ BITS 16]
30 LABEL_BEGIN:
31 mov ax, cs
32 mov ds, ax
33 mov es, ax
34 mov ss, ax
35 mov sp, 0100h
36
37 ; 初始化 32 位代码段描述符
38 xor eax, eax
39 mov ax, cs
40 shl eax, 4
41 add eax, LABEL_SEG_CODE32
42 mov word [LABEL_DESC_CODE32 + 2], ax
43 shr eax, 16
44 mov byte [LABEL_DESC_CODE32 + 4], al
45 mov byte [LABEL_DESC_CODE32 + 7], ah
46
47 ; 为加载GDTR 作准备
48 xor eax, eax
49 mov ax, ds
50 shl eax, 4
51 add eax, LABEL_GDT ; eax <- gdt 基地址
52 mov dword [GdtPtr + 2], eax ; [GdtPtr + 2] <- gdt 基地址
53
54 ; 加载 GDTR
55 lgdt [GdtPtr]
56
57 ; 关中断
58 cli
59
60 ; 打开地址线A20
61 in al, 92h
62 or al, 00000010b
63 out 92h, al
64
65 ; 准备切换到保护模式
66 mov eax, cr0
67 or eax, 1
68 mov cr0, eax
69
70 ; 真正进入保护模式
71 jmp dword SelectorCode32:0 ; 执行这一句会把SelectorCode32 装入cs,
72 ; 并跳转到Code32Selector:073 ; END of [SECTION .s16]
74
75
76 [ SECTION .s32]; 32 位代码段. 由实模式跳入.
77 [ BITS 32]
78
79 LABEL_SEG_CODE32:
80 mov ax, SelectorVideo
81 mov gs, ax ; 视频段选择子(目的)
82
83 mov edi, (80 * 11 + 79) * 2 ; 屏幕第11,79列。
84 mov ah, 0Ch ; 0000:黑底 1100:红字
85 mov al, 'P'
86 mov [gs:edi], ax;
87
88 ; 到此停止
89 jmp $
90
91 SegCode32Len equ $ - LABEL_SEG_CODE32
92 ; END of [SECTION .s32]

说明:这段代码将实现由实模式到保护模式的转换。执行▹ nasm pmtest1.asm -o pmtest1.bin 生成纯二进制文件。程序中定义的section没有实质的作用。

代码解读:
[SECTION .gdt]:Descriptor是在pm.inc中定义的宏(如下所示),表示的不是一段代码,而是一个数据结构,它的大小是8字节。

251 ; 描述符
252 ; usage: Descriptor Base, Limit, Attr
253 ; Base: dd
254 ; Limit: dd (low 20 bits available)
255 ; Attr: dw (lower 4 bits of higher byte are always 0)
256 %macro Descriptor 3
258 dw %1 & 0FFFFh ; 段基址1
257 dw %2 & 0FFFFh ; 段界限1
259 db (%1>>16) & 0FFh ; 段基址2
260 dw ((%2>>8) & 0F00h) | (%3 & 0F0FFh) ; 属性1+段界限2+属性2
261 db (%1>>24) & 0FFh ; 段基址3
262 %endmacro;8 字节

在段[SECTION.gdt]中并列有3个Descriptor,是个结构数组,这个数组的名字叫做GDT。GdtLen是GDT的长度,GdtPtr也是个小的数据结构,它有6字节,前2字节是GDT的界限,后4字节是GDT的基地址。另外还定义了两个形如SelectorXXXX的常量。
[ SECTION .s16]: 再往下到了一个代码段,[BITS 16]明确地指明了它是一个16位代码段。你会发现,这段程序修改了一些GDT中的值,然后执行了一些不常见的指令,最后通过jmp指令实现一个跳转(第71行)。正如代码注释中所说的,这一句将“真正进入保护模式”。[ SECTION .s32]: 实际上,它将跳转到第三个section,即[SECTION .s32]中,这个段是32位的,执行最后一小段代码。这段代码看上去是往某个地址处写入了2字节,然后就进入了无限循环。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值