X86: mode protégé, GDT, IDT
Question
J'ai essayé d'exécuter un noyau simple avec un chargeur de démarrage kolibri. Il est chargé dans 1000: 0000. Je ne comprends pas, quel est le problème dans cette partie:
...
; 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 $
parce que dans le débogueur, cela ressemble à ceci
Que se passe-t-il ici?Pourquoi ES et DS ne sont-ils pas modifiés?
P.S.J'essaye de faire fonctionner ce noyau avec le chargeur kolibri: http://wasm.ru/article.php?article=ia32int
La solution
Le processeur n'entre pas automatiquement en mode protégé lorsque vous définissez le bit protégé dans cr0
.Il entre en mode protégé lorsque cs
est modifié après cela.Le moyen le plus simple de le faire est d'insérer un saut lointain immédiatement après avoir écrit dans cr0
.
mov cr0, eax
.db 066h
jmp CODE_SEGMENT:PROTECTED_ENTRY
use32
PROTECTED_ENTRY:
J'espère que j'ai bien compris.(Je suis habitué à la syntaxe AT&T.) Ce .db
est un remplacement de taille d'opérande pour autoriser une adresse 32 bits.
Autres conseils
Le débogueur Tee désassemble le code 32 bits (vous avez dit à l'assembleur de générer du code 32 bits avec le pseudo op use32
) en tant que code 16 bits.Ainsi, l'instruction mov ax, 10h
est interprétée comme mov eax, d88e0010h
, où la partie d88e
est en réalité l'opcode pour l'instruction suivante, mov ds,ax
.
Similaire pour mov esp, 0xffff
, qui est interprété comme mov sp, 0xffff
et les deux octets zéro supplémentaires apparaissent comme une instruction add byte ptr...
fausse.
Ce que le processeur exécute réellement dépend de son état actuel - est-il en mode protégé, en mode réel, en mode plat, etc. Regardez les registres d'état pour le savoir.Vous pouvez peut-être dire au débogueur d'interpréter le code différemment.