实模式下不能访问1M以上的内存,而且实模式不能提供内存保护。
启示开启实模式只要3个步骤
1.设置gdt全局描述符表
2.设置a20开始访问1M以上内存的必须步骤
3.设置cr0的pe为1,这个表明已经进入了保护模式中。
;
;protect.ASM
;
;
;
SECTION ALIGN=16 VSTART=0x7E00
MOV AX , [cs:SS_BASE]
MOV SS , AX
XOR SP , SP
MOV AX , [cs:DS_BASE]
MOV DS , AX
MOV BX , 0x7C00
;创建#1描述符,保护模式下的代码段描述符
mov dword [bx],0x0
mov dword [bx+0x04],0x0
;创建#1描述符,保护模式下的代码段描述符
mov dword [bx+0x08],0x7e0001ff
mov dword [bx+0x0c],0x00409800
;创建#2描述符,保护模式下的数据段描述符(文本模式下的显示缓冲区)
mov dword [bx+0x10],0x8000ffff
mov dword [bx+0x14],0x0040920b
;创建#3描述符,保护模式下的堆栈段描述符
mov dword [bx+0x18],0x00007a00
mov dword [bx+0x1c],0x00409600
;创建#4描述符,保护模式下的代码段描述符
mov dword [bx+0x20],0x7e0001ff
mov dword [bx+0x24],0x00F09800
;创建#5描述符,保护模式下的数据段描述符(文本模式下的显示缓冲区)
mov dword [bx+0x28],0x8000ffff
mov dword [bx+0x2C],0x00F0920b
;创建#6描述符,保护模式下的堆栈段描述符
mov dword [bx+0x30],0x00007a00
mov dword [bx+0x34],0x00F09600
mov bx , GDT_SIZE
mov word [bx] , 47
mov dword [bx+2], 0x7C00
lgdt [bx]
in al , 0x92
or al , 0000_0010B
out 0x92,al
cli
mov eax , cr0
or eax , 0x01
mov cr0 ,eax
jmp dword 0x0008:(PROTECT_BEGIN-0x7E00)
DS_BASE DW 0x0000
SS_BASE DW 0x2000
[bits 32]
ZERO_SECTOR DD 0x0,0x0
CS_SECTOR DD 0x0,0x0
DS_SECTOR DD 0x0,0x0
SS_SECTOR DD 0x0,0x0
CS_DPL3_SECTOR DD 0x0,0x0
DS_DPL3_SECTOR DD 0x0,0x0
GDT_SIZE DW 0x00
DGT_BASE DD 0x00000000
PROTECT_BEGIN:
mov ax , 16
mov ds , ax
mov byte [0] , 'P'
mov byte [1] , 0x07
mov byte [2] , 'r'
mov byte [3] , 0x07
mov byte [4] , 'o'
mov byte [5] , 0x07
mov byte [6] , 't'
mov byte [7] , 0x07
mov byte [8] , 'e'
mov byte [9] , 0x07
mov byte [10] , 'c'
mov byte [11] , 0x07
mov byte [12] , 't'
mov byte [13] , 0x07
jmp $
times 512 - ($-$$) db 0
很多人会问设置了cr0不实就进入到保护模式下了么,那么cpu的cs不就开始做检测了么,为什么jmp还能跳转呢,因为CPU其实使用的实cs段的高速缓存,而不实真正的cs,在实模式下也是如此,只不过实模式下的高速缓存的值是cs向左移动4位形成的,而保护模式是使用选择子去找段描述符,在缓存到高速缓存中的,所以在保护模式下不是每次都去cs的段描述符去查找基地址的,而是去缓存中找,这样速度就快多了。
因为此时的缓存中保护的还是实模式下的内存地址所以程序可以继续执行,但是我们要进入保护模式就必须刷新cs让其变成段选择子的地址,这样就用一个长跳转将cs中的值进行刷新。跳转完成后要设置新的ds,fs,ss的选择子,要不就会出现些一想不到的问题。
mov eax , cr0
or eax , 0x01
mov cr0 ,eax
jmp dword 0x0008:(PROTECT_BEGIN-0x7E00)
dd if=protect.bin of=XXXXX.VHD seek=2 bs=512 count=1