Простая программа переключения режима МППусть необходимо написать программу, которая переключает МП в защищенный режим (PM),изменяет атрибуты устройства отображения на негативное изображение и возвращается в реальный режим (RM) в ДОС. Для большей наглядности работы программы, перед переключением в РМ на экран выдается строка символов %%%%%%. Так как МП здесь еще в RM, то можно воспользоваться прерыванием BIOS int10h (функция 0Eh - вывод символа). Как только МП переходит в режим РМ, то выдается звуковой сигнал низкого тона. Программа переводит в негатив изображение всего экрана. Перед возвращением в режим RM программа выдает высокий тон и восстанавливает прямое изображение. Заметим, что в защищенном режиме нельзя воспользоваться прерыванием ОС и для подачи звукового сигнала, поэтому необходимо разработать подпрограмму с использованием портов. После возврата в RM и в ДОС на экран выводится строка символов ######## и завершается выполнение программы. Таков общий план программы.
Конкретизируем этапы составления программы.
Чтобы подготовить в ОП глобальную дескрипторную таблицу GDT, необходимо, в первую очередь, определить количество и назначение сегментов в программе. Это, в свою очередь, определяет структуру, содержание и размещение по таблицам дескрипторов этих сегментов. Ввиду простоты программы примем, что она имеет нулевой (высший) уровень приоритета, что все дескрипторы размещаются в GDT и тоже имеют нулевой уровень.
Необходимы следующие сегменты: 1. Сегмент глобальной дескрипторной таблицы. Для удобства разместим его на территории кодового сегмента. 2. Кодовый сегмент. 3. Алиас кодового сегмента - псевдосегмент данных. Территориально этот сегмент совпадает с кодовым. Он необходим для того, чтобы можно было изменять содержание дескрипторов, а возможно и кодового сегмента, не нарушая их зашиту в режиме РМ. 4. Стековый сегмент. Необходим для внутрипрограммных процедур. 5. Сегмент данных. 6. Дополнительный сегмент данных. Оба сегмента данных нужны для перезагрузки буфера монитора (видеобуфера) с заменой атрибута символов экрана на негатив. Необходимым оказалось создать еще один сегмент, но которому не нужен дескриптор и селектор. Это фрагмент четырех байт BIOS в ОП по адресу 0040h:0067h, куда помещают смещение (IP) и базовый адрес сегмента (CS), по которым произойдет возврат в реальный режим
Параметры дескрипторов. Структура дескрипторов разного типа приведена в методическом пособии к данной работе. Отметим, что она включает длину сегмент, его базовый адрес и байт атрибутов. Замечания по выбору значений этих параметров следующие. 1. Длина (предел) некоторых сегментов может быть определена точно на этапе трансляции. Например, длина кодового сегмента в байтах равна значению счетчика после последнего оператора программы. На ассемблере имеются такие возможности. Аналогично можно определить длину сегмента дескрипторной таблицы как разность адресов ее начала и конца. Что касается сегментов стека и данных, то их длину не всегда можно определить. Если проблем со свободной ОП нет, то предел можно взять максимальным - FFFF, что соответствует 64kb. 2. Базовый адрес сегмента также может быть иногда указан точно, как это было указано выше для фрагмента BIOS. В нашем примере также известны базовые адреса сегментов данных, т.к. они должны совпадать с адресом B8000 буфера монитора. В общем случае, базовый адрес сегментов определяется загрузчиком ДОС и директивами пользователя этапу трансляции, т.е. в момент выполнения программы базовый адрес известен и находится в сегментном регистре. Как было сказано выше, адрес должен быть переведен в формат защищенного режима прежде, чем будет занесен в дескриптор. 3. У каждого дескриптора должен быть свой байт атрибутов. Структура байта зависит от типа сегмента. Она приведена в методическом пособии к работе. В данном примере сегменты GDT, алиас кодового сегмента, стековый, данных и дополнительных данных имеют одинаковый тип, а именно - тип данных, поэтому байт атрибутов их дескрипторов также одинаков. В самом деле, компоненты байта атрибутов здесь следующие: Р(бит присутствия)=1, DPL(приоритет)=00, S(сегмент несистемный)=1, Е(сегмент кодовый)=0, ED(адресация вниз)=0, V(разрешение записи в сегмент)=1, А(обращение к сегменту уже было)=0. Это соответствует коду 10010010. Для кодового сегмента компоненты байта атрибутов следующие: Р=1, DPL=00, S=1, E=1, C(бит подчиненности)=0, R(разрешение считывания кода как данных с помощью префикса замены сегмента)=1, А=0. Поэтому байт атрибутов равен 10011010 = 9Аh. Параметры селекторов Как приведено в методическом пособии, селектор в защищенном режиме содержит INDEX, TI, RPL. INDEX - это номер дескриптора в таблице. Его можно получить, разделив на 8 относительный адрес дескриптора от начала таблицы, поскольку дескрипторы имеют 8 байт. INDEX смещен в селекторе влево на 3 разряда. Это можно сделать последующим умножением на 8. Значение TI и RPL удобно наложить арифметическим сложением с соответствующей константой. RPL селекторов = 0, DPL дескрипторов сегментов, покрывающих видеобуфер, = 3(011).
|