你的位置:首页 > 操作系统

[操作系统]Linux内核系列—3.操作系统开发之保护模式的优势


在上一篇中我们虽然成功进入了保护模式,但是并没有体验到保护模式带给我们的便利。其实在保护模式下寻址空间可以达到4GB,实模式下1MB的寻址能力差得太远了。那么下面,我们就把程序稍作修改,体验一下它对超过1MB内存的访问能力。

我们来试验一下读写大地址内存。在前面程序的基础上,新建一个段,这个段以5MB为基址,远远超出实模式下1MB的界限。我们先读出开始处8字节的内容,然后写入一个字符串,再从中读出8字节,如下所示:

	call	TestRead	call	TestWrite	call	TestRead

如果读写成功的话,两次读出的内容应该是不同的,而且第二次读出的内容应该是我们写进的字符串。字符串是保存在数据段中的,也是新增加的。增加的两个段如下所示:

LABEL_DESC_DATA:  Descriptor  0,   DataLen-1, DA_DRW  ; DataLABEL_DESC_TEST:  Descriptor 0500000h,   0ffffh, DA_DRWSelectorData		equ	LABEL_DESC_DATA		- LABEL_GDTSelectorTest		equ	LABEL_DESC_TEST		- LABEL_GDT[SECTION .data1]	 ; 数据段ALIGN	32[BITS	32]LABEL_DATA:BootMessage:		db	"Joey, I'm in protected mode!"OffsetPMMessage		equ	BootMessage - $$		;表示字符串BootMessage相对于本节的开始处(LABEL_DATA)的偏移StrTest:		db	"ABCDEFGHIJKLMNOPQRSTUVWXYZ", 0OffsetStrTest		equ	StrTest - $$DataLen			equ	$ - LABEL_DATA; END of [SECTION .data1]

段[SECTION .s32]这个段的开头初始化了ds、es和gs,让ds指向新增的数据段,es指向新增的5MB内存的段,gs指向显存。如下所示:

LABEL_SEG_CODE32:	mov	ax, SelectorData	mov	ds, ax			; 数据段选择子	mov	ax, SelectorTest	mov	es, ax			; 测试段选择子	mov	ax, SelectorVideo	mov	gs, ax			; 视频段选择子(目的)

数据段的基址便是LABEL_DATA的物理地址。于是OffsetStrTest既是字符串相对于LABEL_DATA的偏移,也是其在数据段中的偏移。我们在保护模式下需要用到的正是这个偏移,而不再是实模式下的地址。section的一点妙用指的便是这里的$$。

	; 初始化数据段描述符	xor	eax, eax	mov	ax, ds	shl	eax, 4	add	eax, LABEL_DATA	mov	word [LABEL_DESC_DATA + 2], ax	shr	eax, 16	mov	byte [LABEL_DESC_DATA + 4], al	mov	byte [LABEL_DESC_DATA + 7], ah

运行如下所示:

第一次执行call TestRead时显示8个空字符,第二次执行call TestRead时显示ABCDEFGH。因为TestRead的段寄存器指向的是5MB内存地址处的内容,一开始是没有任何数据。

TestRead:	xor	esi, esi	mov	ecx, 8.loop:	mov	al, [es:esi]	call	DispAL	inc	esi	loop	.loop	ret

然后第190行向这个5MB内存地址处依次写入8字节数据。

 

一个码农的日常 

源码及软盘映像