%include "gdt.inc"
org 07c00h
jmp LABEL_BEGIN
;GDT描述符
[SECTION .gdt]
;GDT base addr base limit properties
LABEL_GDT: Descriptor 0, 0, 0
LABEL_DESC_CODE32: Descriptor 0, SegCode32Len-1, DA_C+DA_32
LABEL_DESC_VIDEO: Descriptor 0B8000h, 0ffffh, DA_DRW
;GDT end
GdtLen equ $-LABEL_GDT
;加载lgdt是需要的东东
GdtPtr dw GdtLen-1 ;GDT limit
dd 0 ;GDT BASE ADDR
;GDT Selector
SelectorCode32 equ LABEL_DESC_CODE32-LABEL_GDT
SelectorVideo equ LABEL_DESC_VIDEO-LABEL_GDT
;end of [SECTION .gdt]
;Attention:SP--stack point register , SS--stack register
[SECTION .s16]
[BITS 16]
LABEL_BEGIN:
mov ax,cs
mov ds,ax
mov es,ax
mov ss,ax
mov sp,0100h
;initialize 32-bits code segment
xor eax,eax ;To make eax return to zero
mov ax,cs
shl ax,4 ;let first 4-bits save LABEL_SEG_CODE32
add ax,LABEL_SEG_CODE32 ;Now the eax's structure:0,cs(high),cs(low),LABEL_SEG_CODE32
mov word [LABEL_DESC_CODE32+2],ax ;LABEL_DESC_CODE32+2-----segment base addr1(3 bytes),now use two bytes
shr ax,16 ;Right shift 16-bits to make the high 2 bytes of eax to the low 2 bytes
mov byte [LABEL_DESC_CODE32+4],al ;segment base addr1
mov byte [LABEL_DESC_CODE32+7],ah ;segment base addr2
;make preparation for load GDTR,especially GdtPtr's gdt base addr
xor eax,eax;
mov ax,ds
shl eax,4
add eax,LABEL_GDT
mov dword[GdtPtr+2],eax
;load GDTR
lgdt [GdtPtr]
;load GdtPtr's 6 BYTES to register gdtr,the structure of gdtr---- 32bits base addr & 16bits limit,ths same as GdtPtr
;disable interrupts
cli
;Open the addr wire A20,we can operate port 92h
in al,92h ;read the value of port 92h to al
or al,00000010b ;make the value of second bit to 1
out 92h,al ;write the value of port 92h from al
;make the preparation for cut over protect mode
mov eax,cr0
or eax,1
mov cr0,eax
;jmp to protect mode
jmp dword SelectorCode32:0
;这个jmp困扰了我很久~我百般不得其解~为何它是跳转到了选择子呢~这样怎么能跳转到保护模式的代码段LABEL_SEG_CODE32呢~他
;自己会找到基址这个解释有点不现实,果然是书中自有黄金屋,后来在书上找到了那么一段解释:保护模式下,段值仍然由原来的16位寄存器cs,ds等寄存器表示,但此时他仅仅成为了一个索引,这个索引指向GDT,那么解释起来就很轻松了:
首先:
;make the preparation for cut over protect mode
mov eax,cr0
or eax,1
mov cr0,eax
这段代码已经进入了保护模式,因为cr0寄存器的PE位为1时表明她已经进入了~所以现在的规则已经按照保护模式的来了~cs指向GDT,所以CS指向选择子,那么在此处相当于指向了描述符LABEL_DESC_CODE32,而jmp dword SelectorCode32:0相当于让cs<---描述符LABEL_DESC_CODE32,而之后我想应该是由于描述符有固定的格式,所以它能够从描述附中找到基址这里!这个地方还有点不确定~还要继续查找。
总之总结一下:保护模式的寻址方式就是: 段选择子:偏移地址