4.由真實模式到保護模式
阿新 • • 發佈:2018-12-15
學習於網易雲課堂:Linux作業系統, 構建自己的核心,講師:Coding迪斯尼
目標:實現32位定址
之前的暫存器直接存著要訪問的地址,一個暫存器16位,2^16*2^4=2^20=2M,加上偏移2^16=64kb,也就是說,真實模式的定址範圍是2M+(-)64kb,現在要做的是暫存器儲存表結構的偏移地址,然後從表結構中得到32位的程式起始地址和程式的長度,程式所在記憶體的屬性(比如:可讀,可寫)
%include "pm.inc" org 0x9000;基地址 jmp LABEL_BEGIN [SECTION .gdt] ;描述記憶體地址|byte7 |byte6 |byte5 |byte4 |byte3 |byte2 |byte1 |byte0 | ; |7654 3210|7654 3210|7654 3210|7654 3210|7654 3210|7654 3210|7654 3210|7654 3210| ; |*********| |----|...屬性..|*************地址************|-------段長度------| ; 段基址 段長 屬性 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 GdtLen equ $-LABEL_GDT;24位元組,3個Descriptor的長度 GdtPtr dw GdtLen-1 dd 0;資料結構的起始地址 SelectorCode32 equ LABEL_DESC_CODE32-LABEL_GDT;LABEL_DESC_CODE32的地址偏移 SelectorVideo equ LABEL_DESC_VIDEO-LABEL_GDT;LABEL_DESC_VIDEO的地址偏移 [SECTION .sl6] [BITS 16] LABEL_BEGIN: mov ax,cs mov ds,ax mov es,ax mov ss,ax mov sp,0100h xor eax,eax;異或清0 eax暫存器 shl eax,4;cs暫存器*16 add eax,LABEL_SEG_CODE32;cs+偏移,此處是真實模式定址,找到資料結構的偏移地址 mov word [LABEL_DESC_CODE32+2],ax;把資料結構的地址寫入2,3 shr eax,16 mov byte[LABEL_DESC_CODE32+4],al mov byte[LABEL_DESC_CODE32+7],ah xor eax,eax mov ax,ds shl eax,4 add eax,LABEL_GDT mov dword [GdtPtr+2],eax lgdt [GdtPtr];系統從資料結構中找記憶體的起始地址,資料長度 cli in al,92h or al,00000010b out 92h,al mov eax,cr0 or eax,1 mov cr0,eax jmp dword SelectorCode32:0;跳轉到偏移地址 [SECTION .s32] [BITS 32] LABEL_SEG_CODE32: mov ax,SelectorVideo mov gs,ax mov si,msg mov ebx,10 mov ecx,2 showChar: mov edi,(80*11) add edi,ebx mov eax,edi mul ecx mov edi,eax mov ah,0ch mov al,[si] cmp al,0 je end add ebx,1 add si,1 mov [gs:edi],ax jmp showChar end: jmp $ msg: DB "bairuixiang",0 SegCode32Len equ $-LABEL_SEG_CODE32
現在我們已經實現由核心載入器找到我們的程式碼,然後由之前的真實模式的定址變為保護模式的定址,找到真正要執行的程式碼,接著去執行。