没有合适的资源?快使用搜索试试~ 我知道了~
首页X86实模式到保护模式源码详解:从MBR到主引导区示例
X86实模式到保护模式源码详解:从MBR到主引导区示例
需积分: 50 31 下载量 180 浏览量
更新于2024-07-18
收藏 1.13MB PDF 举报
本文档探讨了X86汇编语言从实模式(Real Mode)向保护模式(Protected Mode)的过渡,通过提供源代码来详细展示这一过程。实模式是早期X86架构的基础,它不具备现代操作系统所需的内存保护和多任务支持。在源代码(如文件c05_mbr.asm)中,可以看到作者John·YH展示了如何在主引导扇区(MBR)中设置基本的内存操作和控制,以准备进入保护模式。
在第5-6行,代码`mov ax, 0xb800`设置了指向文本模式显示缓冲区的地址,这是实模式下常见的操作,用于将数据输出到屏幕。接下来的几行通过`mov byte [es:offset]`指令逐个写入字符到内存,构建字符串"Labeloffset:”。
值得注意的是,这段代码并未直接涉及保护模式的初始化,因为主引导扇区的任务通常是加载操作系统引导装载程序(Loader),后者会负责引导进程到保护模式。在保护模式下,硬件提供了一组更复杂的指令集,包括段寄存器的使用、访问权限控制和分页机制等,这些都在操作系统内核中实现。
保护模式的核心特点是:
1. **段寄存器**:引入了段寄存器(如CS、DS、ES和SS等)来组织内存空间,使得程序可以独立于物理地址执行,提高了地址空间的利用率。
2. **分段和分页**:内存被划分为多个逻辑段,每个段有自己的基址和界限,允许程序在不同区域执行,并通过页表管理物理内存的访问权限。
3. **特权级**:保护模式有多个特权级别,每个级别有不同的权限,比如系统态(Ring 0)和用户态(Ring 3),防止恶意代码直接访问敏感系统资源。
4. **内存管理单元(MMU)**:硬件级别的内存管理单元实现了虚拟地址到物理地址的转换,增强了内存安全性。
5. **错误处理和异常处理**:保护模式提供了更精细的错误处理机制,允许程序在遇到问题时执行特定的异常处理代码,而不是立即崩溃。
从源代码中的这部分内容来看,读者可以借此理解实模式与保护模式的基本概念差异,以及如何通过汇编语言逐步过渡到保护模式下的内存管理和控制。深入学习这部分内容对于理解X86架构的进化以及操作系统底层工作原理至关重要。
X86汇编语言 从实模式到保护模式源码 John·YH
240
241 .roll_screen:
242 0000014E 81FBD007 cmp bx,2000
;
光标超出屏幕?滚屏
243 00000152 7C27 jl .set_cursor
244
245 00000154 B800B8 mov ax,0xb800
246 00000157 8ED8 mov ds,ax
247 00000159 8EC0 mov es,ax
248 0000015B FC cld
249 0000015C BEA000 mov si,0xa0
250 0000015F BF0000 mov di,0x00
251 00000162 B98007 mov cx,1920
252 00000165 F3A5 rep movsw
253 00000167 BB000F mov bx,3840
;
清除屏幕最底一行
254 0000016A B95000 mov cx,80
255 .cls:
256 0000016D 26C7072007 mov word[es:bx],0x0720
257 00000172 81C30200 add bx,2
258 00000176 E2F5 loop .cls
259
260 00000178 BB8007 mov bx,1920
261
262 .set_cursor:
263 0000017B BAD403 mov dx,0x3d4
264 0000017E B00E mov al,0x0e
265 00000180 EE out dx,al
266 00000181 BAD503 mov dx,0x3d5
267 00000184 88F8 mov al,bh
268 00000186 EE out dx,al
269 00000187 BAD403 mov dx,0x3d4
270 0000018A B00F mov al,0x0f
271 0000018C EE out dx,al
272 0000018D BAD503 mov dx,0x3d5
273 00000190 88D8 mov al,bl
274 00000192 EE out dx,al
275
276 00000193 07 pop es
277 00000194 1F pop ds
278 00000195 5A pop dx
279 00000196 59 pop cx
280 00000197 5B pop bx
281 00000198 58 pop ax
282
283 00000199 C3 ret
284
285
;===============================================================================
286 SECTION data align=16 vstart=0
287
288 00000000 5374617274696E672E- init_msg db 'Starting...',0x0d,0x0a,0
289 00000009 2E2E0D0A00
290
291 0000000E 496E7374616C6C696E- inst_msg db 'Installing a new interrupt
70H...',0
292 00000017 672061206E65772069-
293 00000020 6E7465727275707420-
294 00000029 3730482E2E2E00
295
296 00000030 446F6E652E0D0A00 done_msg db 'Done.',0x0d,0x0a,0
297
298 00000038 436C6F636B20697320- tips_msg db 'Clock is now working.',0
299 00000041 6E6F7720776F726B69-
300 0000004A 6E672E00
301
302
;===============================================================================
303 SECTION stack align=16 vstart=0
304
305 00000000 <res 00000100> resb 256
-16-
X86汇编语言 从实模式到保护模式源码 John·YH
306 ****************** warning: uninitialized space declared in stack
section: zeroing
307 ss_pointer:
308
309
;===============================================================================
310 SECTION program_trail
311 program_end:
1 ;
代码清单
9-2
2 ;
文件名:
c09_2.asm
3 ;
文件说明:用于演示
BIOS
中断的用户程序
4 ;
创建日期:
2012-3-28 20:35
5
6
;===============================================================================
7 SECTION header vstart=0
;
定义用户程序头部段
8 00000000 [00000000] program_length dd program_end
;
程序总长度
[0x00]
9
10 ;
用户程序入口点
11 00000004 [0000] code_entry dw start
;
偏移地址
[0x04]
12 00000006 [00000000] dd section.code.start
;
段地址
[0x06]
13
14 0000000A 0300 realloc_tbl_len dw (header_end-realloc_begin)/4
15
;
段重定位表项个数
[0x0a]
16
17 realloc_begin:
18 ;
段重定位表
19 0000000C [00000000] code_segment dd section.code.start ;[0x0c]
20 00000010 [00000000] data_segment dd section.data.start ;[0x14]
21 00000014 [00000000] stack_segment dd section.stack.start ;[0x1c]
22
23 header_end:
24
25
;===============================================================================
26 SECTION code align=16 vstart=0
;
定义代码段(
16
字节对齐)
27 start:
28 00000000 A1[1400] mov ax,[stack_segment]
29 00000003 8ED0 mov ss,ax
30 00000005 BC[0001] mov sp,ss_pointer
31 00000008 A1[1000] mov ax,[data_segment]
32 0000000B 8ED8 mov ds,ax
33
34 0000000D B97700 mov cx,msg_end-message
35 00000010 BB[0000] mov bx,message
36
37 .putc:
38 00000013 B40E mov ah,0x0e
39 00000015 8A07 mov al,[bx]
40 00000017 CD10 int 0x10
41 00000019 43 inc bx
42 0000001A E2F7 loop .putc
43
44 .reps:
45 0000001C B400 mov ah,0x00
-17-
X86汇编语言 从实模式到保护模式源码 John·YH
46 0000001E CD16 int 0x16
47
48 00000020 B40E mov ah,0x0e
49 00000022 B307 mov bl,0x07
50 00000024 CD10 int 0x10
51
52 00000026 E9F3FF jmp .reps
53
54
;===============================================================================
55 SECTION data align=16 vstart=0
56
57 00000000 48656C6C6F2C206672- message db 'Hello, friend!',0x0d,0x0a
58 00000009 69656E64210D0A
59 00000010 546869732073696D70- db 'This simple procedure used to
demonstrate '
60 00000019 6C652070726F636564-
61 00000022 757265207573656420-
62 0000002B 746F2064656D6F6E73-
63 00000034 747261746520
64 0000003A 7468652042494F5320- db 'the BIOS interrupt.',0x0d,0x0a
65 00000043 696E74657272757074-
66 0000004C 2E0D0A
67 0000004F 506C65617365207072- db 'Please press the keys on the
keyboard ->'
68 00000058 65737320746865206B-
69 00000061 657973206F6E207468-
70 0000006A 65206B6579626F6172-
71 00000073 64202D3E
72 msg_end:
73
74
;===============================================================================
75 SECTION stack align=16 vstart=0
76
77 00000000 <res 00000100> resb 256
78 ****************** warning: uninitialized space declared in stack
section: zeroing
79 ss_pointer:
80
81
;===============================================================================
82 SECTION program_trail
83 program_end:
1
;===============================================================================
2 SECTION header vstart=0
;
定义用户程序头部段
3 00000000 [00000000] program_length dd program_end
;
程序总长度
[0x00]
4
5 ;
用户程序入口点
6 00000004 [3600] code_entry dw start
;
偏移地址
[0x04]
7 00000006 [00000000] dd section.code.start
;
段地址
[0x06]
8
9 0000000A 0300 realloc_tbl_len dw (header_end-realloc_begin)/4
10
;
段重定位表项个数
[0x0a]
11
-18-
X86汇编语言 从实模式到保护模式源码 John·YH
12 realloc_begin:
13 ;
段重定位表
14 0000000C [00000000] code_segment dd section.code.start
15 00000010 [00000000] data_segment dd section.data.start
16 00000014 [00000000] stack_segment dd section.stack.start
17
18 header_end:
19
20
;===============================================================================
21 SECTION code align=16 vstart=0
;
定义代码段(
16
字节对齐)
22 put_string:
;
显示字符串(
0
结尾)
23
;
输入:
DS:BX=
串地址
24 00000000 50 push ax
25 00000001 53 push bx
26 00000002 56 push si
27
28 00000003 B40E mov ah,0x0e ;INT
0x10
第
0x0e
号功能
29 00000005 89DE mov si,bx
;
字符串起始偏移地址
30 00000007 B307 mov bl,0x07 ;
显示属性
31
32 .gchr:
33 00000009 8A04 mov al,[si]
;
逐个取要显示的字符
34 0000000B 08C0 or al,al
;
如果
AL
内容为零,则
35 0000000D 7406 jz .rett
;
跳转到过程返回指令
36 0000000F CD10 int 0x10
;BIOS
字符显示功能调用
37 00000011 46 inc si ;
下一个字符
38 00000012 E9F4FF jmp .gchr
39
40 .rett:
41 00000015 5E pop si
42 00000016 5B pop bx
43 00000017 58 pop ax
44
45 00000018 C3 ret
46
47
;-------------------------------------------------------------------------------
48 write_dsp:
49 00000019 52 push dx
50 0000001A 50 push ax
51
52 0000001B BA2C02 mov dx,022ch
53 .@22c:
54 0000001E EC in al,dx
55 0000001F 2480 and al,1000_0000b
;
监视
22c
端口的第
7
位,直到它变为
0
56 00000021 75FB jnz .@22c
57
58 00000023 58 pop ax
59 00000024 EE out dx,al
60 00000025 5A pop dx
61
62 00000026 C3 ret
63
64
;-------------------------------------------------------------------------------
65 read_dsp:
66 00000027 52 push dx
67
68 00000028 BA2E02 mov dx,22eh
69 .@22e:
-19-
X86汇编语言 从实模式到保护模式源码 John·YH
70 0000002B EC in al,dx
71 0000002C 2480 and al,1000_0000b
;
监视
22e
端口的位
7
,直到它变成
1
72 0000002E 74FB jz .@22e
73 00000030 BA2A02 mov dx,22ah
74 00000033 EC in al,dx
;
此时可以从
22a
端口读取数据
75
76 00000034 5A pop dx
77
78 00000035 C3 ret
79
80
;-------------------------------------------------------------------------------
81 start:
82 00000036 A1[1400] mov ax,[stack_segment]
83 00000039 8ED0 mov ss,ax
;
修改
SS
时,处理器将在执行下一指
84 0000003B BC[0001] mov sp,ss_pointer ;
令前禁止中断
85
86 0000003E A1[1000] mov ax,[data_segment]
87 00000041 8ED8 mov ds,ax
88
89 00000043 BB[1CE5] mov bx,init_msg
90 00000046 E8B7FF call put_string
91
92 ;
以下复位
DSP
芯片
93 00000049 BA2602 mov dx,0x226
94 0000004C B001 mov al,1
;
第一步,先写
“1”
到复位端口
95 0000004E EE out dx,al
96
97 0000004F 31C0 xor ax,ax
98 .@1:
99 00000051 48 dec ax
100 00000052 75FD jnz .@1
;
一个硬件要求的延时
(
至少
3ms)
101
102 00000054 EE out dx,al
;
第二步,写
“0”
到复位端口
103
104 00000055 E8CFFF call read_dsp
105 00000058 3CAA cmp al,0xaa
;
状态值
0xaa
表示初始化完成
106 0000005A 7409 jz .@4
107
108 0000005C BB[9BE5] mov bx,err_msg ;
显示出错信息
109 0000005F E89EFF call put_string
110 00000062 E9AA00 jmp .idle ;
直接停机
111
112 .@4:
113 00000065 BB[6CE5] mov bx,done_msg
114 00000068 E895FF call put_string
115
116 ;
以下安装中断处理过程
117 0000006B BB[3FE5] mov bx,intr_msg
118 0000006E E88FFF call put_string
119
120 00000071 B00D mov al,0x0d
;IR5
引脚的中断号
121 00000073 B304 mov bl,4
;
每个中断向量占
4
个字节。本段等效于:
122 00000075 F6E3 mul bl ;mov bx,0x0d
123 00000077 89C3 mov bx,ax ;shl bx,2
124
125 00000079 FA cli
;
禁止在修改
IVT
期间发生中断
126
127 0000007A 06 push es ;
临时使用
ES
128 0000007B 31C0 xor ax,ax
129 0000007D 8EC0 mov es,ax
-20-
剩余131页未读,继续阅读
177 浏览量
620 浏览量
431 浏览量
575 浏览量
624 浏览量
2013-10-26 上传
四葉草の幸運
- 粉丝: 12
- 资源: 31
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功