Voici un code simple pour passer en mode protégé et revenir en mode réel.
Comme le seul fait de passer en PMODE me semble assez incomplet, le code charge également la GDT.
Le programme une fois assemblé ne fait RIEN (et oui le PMODE c'est invisible).
Il se lance sous DOS toutefois il est en 32bits et utilise une segmentation de type flat. Vous remarquerez sans doute qu'en mode protégé on utilise 2 descripteur pour le même segment, ceci vient du fait que le premier désigne le segment de code (possédant les droits de lecture/exécution) tandis que le second est le segment de données/pile (possédant les droits de lecture/écriture).
Si vous désirez avoir plus de renseignement sur le PMODE et plus (le multitâche ou le paging), faites un tour sur
http://developer.intel.com
Source / Exemple :
.386p
.dosseg
assume cs:pmode,ds:pmode,ss:pmode,es:pmode,fs:nothing,gs:nothing
pmode segment public use32
startGDT: ;la GDT
null dw 0,\ ;le descripteur nul
00h
db 00h,\
00000000b,\
00000000b,\
00h
code32 dw 00ffffh,\ ;le descripteur du segment de code
00h
db 00h,\
10011010b,\
11001111b,\
00h
data32 dw 00ffffh,\ ;le descripteur du segment de données/pile
00h
db 00h,\
10010010b,\
11001111b,\
00h
endGDT:
pGDT dw endGDT-startGDT-1 ;le pointeur sur la GDT
dd 0
startup: ;point d'entrée du programme
mov eax,pmode ;initialise le selecteur du segment de données
mov ds,eax
mov eax,ds ;initalise du pointeur sur la GDT
shl eax,4
add eax,startGDT
mov dword ptr [pGDT+02h],eax
mov eax,pmode ;sauvegarde le segment courant
mov gs,eax
cli ;désactive les interruptions masquables
in eax,70h ;désactive les NMIs
or eax,10000000b
out 70h,eax
mov eax,cr0 ;teste la présence du mode protégé
test eax,00000001b
jnz exit ;génère une erreur (une sortie directe du programme) si le CPU est déjà en PMODE
lgdt fword ptr [pGDT] ;charge la GDT en mémoire
or eax,00000001b ;passe en mode protégé
mov cr0,eax
jmp far ptr entry ;reinitialise la queue d'instructions
entry:
mov eax,10h ;reinitialise le sélecteur du segment de données
mov ds,eax
mov ss,eax ;reinitialise le sélecteur du segment de pile
mov esp,1000000h
mov es,eax ;reinitialise le sélecteur du segment de données supplémentaire
mov eax,cr0 ;repasse en mode réel
and eax,01100000000000000000000000010000b
mov cr0,eax
jmp far ptr back ;reinitialise la queue d'instructions
back:
mov eax,gs ;reinitialise le sélecteur du segment de données
mov ds,eax
mov ss,eax ;reinitialise le sélecteur du segment de pile
mov es,eax ;reinitialise le sélecteur du segment de données supplémentaire
exit:
in eax,70h ;réactive les NMIs
and eax,7fh
out 70h,eax
sti ;réactive les interruptions masquables
mov eax,4c00h ;rend le contrôle au DOS
int 21h
pmode ends
end startup
Conclusion :
Pour ceux qui ne sauraient pas "GDT" veut dire "Global Descriptor Table" et NMI "Non-Maskable Interruption".
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.