Базовые средства программирования защищенного режима
;---------------------------------------------------------; ;Теперь процессор работает в защищенном режиме; ;---------------------------------------------------------; ;Загружаем в CS:IP селектор:смещение точки continue db OEAh; Код команды far jmp dw offset continue; Смещение dw 16; Селектор сегмента команд continue: ;Делаем адресуемыми данные mov AX, 8; Селектор сегмента данных mov DS,AX; Загрузим в DS ;Делаем адресуемым стек mov AX,24; Селектор сегмента стека mov SS,AX; Загрузим в SS ;Инициализируем ES и выводим символ mov AX,32; Селектор сегмента видеобуфера mov ES,AX; Загрузим в ES mov BX,2000; Начальное смещение на экране mov AX,09FOFh; Символ с атрибутом mov ES: [BX], АХ; Вывод в видеобуфер ;Вернемся в реальный режим mov gdt_data.limit,0FFFFh; Установим mov gdt_code.limit,0FFFFh; значение границы mov gdt_stack.limit,0FFFFh; для реального mov gdt_screen.limit,0FFFFh; режима mov AX,8; Загрузим теневой регистр mov DS,AX; сегмента данных mov AX,24; To же для mov SS,AX; стека mov AX,32; To же mov ES, AX; для регистра ES ;Выполним дальний переход, чтобы заново загрузить ;селектор в CS и модифицировать его теневой регистр db0Eah; Код команды jmp far dwoffset go; Смещение точки перехода dw!6; Селектор сегмента команд ;Переключим режим процессора go: mov EAX,CR0; Получим содержимое CR0 and EAX,0FFFFFFFEh; Сбросим бит РЕ mov CR0,EAX; Запишем назад в CR0 db0Eah; Код команды far jmp dwoffset return; Смещение точки перехода dwtext; Сегментный адрес ;---------------------------------------------; ;Теперь процессор снова работает в реальном режиме; ;---------------------------------------------; ;Восстановим операционную среду реального режима return: mov AX,data; Загрузим сегментный mov DS,AX; регистр DS mov AX,stk; Загрузим сегментный mov SS,AX; регистр SS mov SP,512; Восстановим SP sti; Разрешим прерывания mov AX,4C00h; Завершим программу ;обычным образом int 2 In main endp code_size=$-main; Размер сегмента команд text ends /Конец сегмента команд stk segment stack; Сегмент db 512 dup ('); стека stk ends end main; Конец программы и точка входа
Для того, чтобы разрешить использование всех, в том числе привилегированных команд 32-разрядных процессоров, в программу включена директива 0.586Р.
Программа начинается с объявления структуры dcr, с помощью которой будут описываться дескрипторы сегментов. Сравнивая описание структуры dcr в программе с рис. 4.9, нетрудно проследить их соответствие друг другу. Для удобства программного обращения в структуре dcr база описывается тремя полями: младшим словом (base_l) и двумя байтами: средним (base_m) и старшим (base_h).
В байте атрибутов 1 задается ряд характеристик сегмента. В примере 4.4 используются сегменты двух типов: сегмент команд, для которого байт attr_l должен иметь значение 98h (присутствующий, только исполнение, DPL=0), и сегмент данных (или стека) с кодом 92h (присутствующий, чтение и запись, DPL=0).
Некоторые дополнительные характеристики сегмента указываются в старшем полубайте байта attr_2. Для всех наших сегментов значение этого полубайта равно 0 (бит G=0, так как граница указывается в байтах, а D=0, так как программа 16-разрядная).