10.3. Вход и выход из защищенного режима

Итак, чтобы перейти в защищенный режим, достаточно установить бит РЕ -нулевой бит в управляющем регистре CRO, и процессор немедленно окажется в защищенном режиме. Единственное дополнительное требование, которое предъявляет Intel, - в этот момент все прерывания, включая немаскируемое, долж­ны быть отключены.

; pmO.asm

; Программа, выполняющая переход в защищенный режим и немедленный возврат. :

; Работает в реальном режиме DOS и в DOS-окне Windows 95  (Windows перехватывает

; исключения,   возникающие при попытке перехода в защищенный режим из V86,

; и позволяет нам работать, но только на минимальном уровне привилегий) .

; Компиляция:

; TASM:

;    tasm /m pmO.-asm ;    tlink /х It pmO.obj

; MASM:

;    ml /c pmO.asm ;    linkpmO.obj, , NUL,, , ;    exe2bin pmO.exe pm0.com

; WASM:

;   wasffi pmO.asm

;    wlink file pmO.obj  form DOS COM .model tiny

. code ;

.386p ;  Все наши примеры рассчитаны на 80386.

org       100h ;  Это СОМ-программа.

start:

; Подготовить сегментные регистры.

push

cs

 

pop

ds ;

DS - сегмент данных (и кода) нашей программы.

push

0В800П

 

pop

es                 ■ ;

ES - сегмент видеопамяти.

Проверить,

находимся ли мы уже

защищенном режиме.

mov

eax.crO ;

Прочитать регистр CRO. :

test

al,l :

Проверить бит РЕ,

и

no_V86               ■;

если он ноль - мы можем продолжать, иначе - сообщить об ошибке и выйти.

mov

ah, 9 ;

Функция DOS 09h.

Вход и выход из защищенного режима

mov        dx, offset v86_msg;   DS:DX - адрес строки. int        21 h ;   Вывод на экран,

ret ;   Конец СОИ-программы

;   (поскольку это защищенный режим,   в котором работает наша DOS-программа, то это должен быть

v86_msg db "Процессор в режиме V86 - нельзя переключиться в РМ$"

;   Сюда передается управление,   если мы запущены в реальном режиме. no_V86:

;   Запретить прерывания. cli

; Запретить немаскируемое прерывание.

in

al,70h ;

Индексный порт CMOS.

or

al,80h ;

Установка бита 7 в нем запрещает NM1.

out

70h,al

 

Перейти в

защищенный режим.

 

mov

.

Прочитать регистр CRO.

or

al,l ;

Установить бит РЕ,

mov

crO.eax ;

с этого момента мы в защищенном режиме.

Вывод на

экран.

 

xor

di.di ;

ES:DI - начало видеопамяти.

mov

message

DS:SI - выводимый текст.

mov

cx,message_l

 

rep

movsb ;

Вывод текста. .

mov

ax,0720h ;

Пробел с атрибутом 07h.

mov

cx, rest_scr ;

Заполнить этим  символом  остаток экрана.

rep

stosw

 

Переключиться в реальный

 

mov

eax.crO ;

Прочитать

and

al.OFEh ;

Сбросить бит РЕ.

mov

С этого

момента процессор работает  в реальном режиме.

Разрешить

немаскируемое прерывание.

in

al,70h ;

Индексный порт CMOS.

and

al,07FH ;

Сброс бита 7 отменяет блокирование NMI.

out

70h,al

ч

Разрешить

прерывания.

 

sti

;   Подождать нажатия любой клавиши.

mov       ah, О int 16h

;  Выйти из СОМ-программы. ret

; Текст сообщения с атрибутом после .каждого символа для прямого вывода на экран. message db        ' Н' , 7,' е' ,7, ' Г,7, '-Г ,7, ' о' ,7, '   ' ,7, V ,7,' з' ,7

db '   ' ,7,'Р',7,'М',7

;   Его длина в байтах. message_l = $-message ;  Длина оставшейся части экрана в словах. rest_scr = (80*25)-(2*message_l) end start

в режиме

В разделе 6.1 при рассмотрении адресации в защищенном режиме говорилось о том, что процессор, обращаясь к памяти, должен определить адрес начала сег­мента из дескриптора в таблице дескрипторов, находящейся в памяти, используя селектор, находящийся в сегментном регистре, в качестве индекса. Одновремен­но при этом мы обращаемся к памяти из защищенного режима, вообще не описав никаких дескрипторов, и в сегментных регистрах у нас находятся те же числа, что и в реальном режиме.

Дело в том, что, начиная с процессора 80286, размер каждого сегментного ре­гистра - CS, SS, DS, ES, FS и GS - не два байта, «десять, восемь из котцрых недо­ступны для программ, точно так же, как описанные выше регистры LDTR и TR. В защищенном режиме при записи селектора в сегментный регистр ко­пирует весь определяемый этим селектором дескриптор в скрытую часть сегмен­тного регистра и больше не пользуется этим селектором вообще. Таблицу деск­рипторов можно уничтожить, а обращения к памяти все равно будут выполняться, как и раньше. В реальном режиме при записи числа в сегментный регистр процес­сор сам создает соответствующий дескриптор в его скрытой части. Он описывает 16-битныйсегмент, начинающийся по указанному адресу с границей 64 Кб. Когда мы переключились в защищенный режим в программе pmO.asm, эти дескрипторы остались на месте и мы могли обращаться к памяти, не принимая во внимание, что у нас написано в сегментном регистре. Разумеется, в такой любая

попытка записать в сегментный регистр число привела бы к немедленной ошибке

(исключение #GP с кодом ошибки, равным загружаемому значению).