%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,而之后我想应该是由于描述符有固定的格式,所以它能够从描述附中找到基址这里!这个地方还有点不确定~还要继续查找。
总之总结一下:保护模式的寻址方式就是: 段选择子:偏移地址