Passer en mode protégé [masm]

Contenu du snippet

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".

A voir également

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.