X86: Modalità protetta, GDT, IDT
Domanda
Ho provato a eseguire un semplice kernel con un bootloader di kolibri. Viene caricato in 1000: 0000. Non capisco, cosa c'è che non va in questa parte:
...
; switch to PM
mov eax, cr0
or al, 1
mov cr0, eax
use32
PROTECTED_ENTRY:
mov ax, 00010000b ; DATA
mov ds, ax
mov ss, ax
mov esp, 0xFFFF
jmp $
mov ax, 00011000b ; VIDEO
mov es, ax
mov edi, 0
mov esi, string
int 1
jmp $
Causa nel debugger sembra così
Cosa sta succedendo qui? Perché ES e DS non vengono cambiati?
PS Sto cercando di far funzionare questo kernel con il caricatore Kolibri:http://wasm.ru/article.php?article=ia32int
Soluzione
Il processore non inserisce automaticamente la modalità protetta quando si imposta il bit protetto cr0
. Entra in modalità protetta quando cs
è cambiato dopo quello. Il modo più semplice per farlo è inserire un salto lontano immediatamente dopo aver scritto cr0
.
mov cr0, eax
.db 066h
jmp CODE_SEGMENT:PROTECTED_ENTRY
use32
PROTECTED_ENTRY:
Spero di aver capito bene. (Sono abituato alla sintassi AT&T.) Quello .db
è un sovraccarico di dimensioni dell'operando per consentire un indirizzo a 32 bit.
Altri suggerimenti
TEE DEBUGGER Smonge il codice a 32 bit (hai detto all'assemblatore di generare codice a 32 bit con il use32
pseudo op) come codice a 16 bit. Quindi l'istruzione mov ax, 10h
è interpretato come mov eax, d88e0010h
, dove il d88e
La parte è in realtà l'opice per la prossima istruzione, mov ds,ax
.
Simile per mov esp, 0xffff
, che viene interpretato come mov sp, 0xffff
e i due byte zero aggiuntivi si presentano come lo spurio add byte ptr...
istruzione.
Ciò che il processore effettivamente esegue, dipende dal suo stato attuale - è in modalità protetta, modalità reale, modalità piatta ecc. Guarda i registri di stato per scoprirlo. Forse puoi dire al debugger di interpretare il codice diverso.