
- •140010, Г. Люберцы, Московской обл., Октябрьский пр-т, 403.
- •Глава 1. Архитектура реального режима
- •1.1. Память и процессор
- •Глава 1
- •Глава 1
- •1.2. Распределение адресного пространства
- •Глава 1
- •1.3. Регистры процессора
- •Глава 1
- •Глава 1
- •9 7H Шестнадцатернчное обозначение числа
- •Глава 1
- •1.4. Сегментная структура программ
- •Глава 1
- •Глава 1
- •Глава 1
- •1.5. Стек
- •Глава 1
- •1.6. Система прерываний
- •Глава 1
- •Глава I
- •1.7. Система ввода-вывода
- •Глава I
- •Глава 1
- •Глава 2. Основы программирования
- •2.1. Подготовка и отладка программы
- •Глава 2
- •Глава 2
- •Глава 2
- •Глава 2
- •Глава 2
- •2.2. Представление данных
- •Глава 2
- •Глава 2
- •2.3. Описание данных
- •Глава 2
- •Глава 2
- •2.4. Структуры и записи
- •Глава 2
- •Глава 2
- •2.5. Способы адресации
- •Глава 2
- •Глава 2
- •Глава 2
- •Глава 2
- •Глава 2
- •Глава 2
- •Глава 2
- •Глава 2
- •Глава 2
- •Глава 2
- •2.7. Вызовы подпрограмм
- •Глава 2
- •2.8. Макросредства ассемблера
- •Глава 2
- •Глава 2
- •Глава 2
- •Глава 3. Команды и алгоритмы
- •Глава 3
- •Глава 3
- •Глава 3
- •Глава 3
- •Глава 3
- •Глава 3
- •Глава 3
- •Глава 3
- •3.2. Циклы и условные переходы
- •Глава 3
- •Глава 3
- •3.3. Обработка строк
- •Глава 3
- •3.4. Использование подпрограмм
- •Глава 3
- •Глава 3
- •3.5. Двоично-десятичные числа
- •Глава 3
- •Глава 3
- •3.6. Программирование аппаратных средств
- •Глава 3
- •37Ah Порт управлсш!я
- •Глава 3
- •Глава 3
- •Глава 4. Расширенные возможности
- •4.1. Архитектурные особенности
- •Глава 4
- •4.2. Дополнительные режимы адресации
- •Глава 4
- •4.3. Использование средств 32-разрядных процессоров в программировании
- •Глава 4
- •Глава 4
- •Глава 4
- •4.4. Основы защищенного режима
- •Глава 4
- •Глава 4
- •Глава 4
- •Глава 4
- •Idiv Деление целых чисел со знаком
- •Imul Умножение целых чисел со знаком
- •In Ввод из порта
- •Inc Инкремент (увеличение на 1)
- •Int Программное прерывание
- •Into Прерывание по переполнению
- •Iret Возврат из прерывания
- •1 Lods Загрузка операнда из строки : lodsb Загрузка байта из строки lodsw Загрузка слова из строки
- •Операнд
- •Xadd память, регистр
- •Xchg Обмен данными между операндами
- •Xlat Табличная трансляция
- •Xor Логическое исключающее или
- •Содержание
Глава 4
Атрибут сегмента, действующий по умолчанию, можно изменить на противоположный с помощью префиксов замены размера операнда (66h) и замены размера адреса (67h). Таким образом, для сегмента с D=0 префикс 66U перед некоторой командой заставляет ее рассматривать свои операнды, как 32-битовые, а для сегмента с D=l тот же префикс 66h, наоборот, сделает операнды 16-битовыми. В некоторых случаях транслятор сам включает в объектный модуль необходимые префиксы, в других случаях их приходится вводить в программу «вручную».
Рассмотрим теперь для примера простую программу, которая, будучи запущена обычным образом под управлением MS-DOS, переключает процессор в защищенный режим, выводит на экран для контроля символ, переходит назад в реальный режим (чтобы не вывести компьютер из равновесия) и завершается стандартным для DOS образом.
Для того, чтобы наша программа могла бы хоть что-то сделать в защищенном режиме, для нее необходимо создать среду защищенного режима, в первую очередь, таблицу глобальных дескрипторов с описанием всех сегментов, с которыми программа будет работать. Кроме нас никто эту таблицу (при работе в DOS) не создаст. Таким образом, наша программа будет в какой-то мере выполнять функции операционной системы защищенного режима.
Для практического исследования защищенного режима придется выполнить некоторую работу по персконфигурированию компьютера. В наше время компьютеры обычно конфигурируются так, что при их включении сразу загружается система Windows. Работы, для которых требуется DOS, выполняются либо в режиме эмуляции DOS, либо в сеансе DOS, организуемом системой Windows. Для запуска прикладной программы защищенного режима такой способ не годится. Нам понадобится DOS в «чистом виде», без следов Windows. Более того, перед запуском программы необходимо выгрузить все драйверы обслуживания расширенной памяти (HIMEM.SYS и EMM386.EXE) и программы, использующие расширенную память, например, SMARTDRV.EXE. Лучше всего загружать DOS с системной дискеты, подготовив файлы CONFIG.SYS и AUTOEXEC.BAT в минимальном варианте.
Обсуждая в начале этого раздела основы защищенного режима, мы не затронули многие, в том числе принципиальные вопросы, с которыми придется столкнуться при написании работоспособной программы. Необходимые пояснения будут даны в конце этого раздела.
Пример 4-4. Программирование защищенного режима .586Р разрешение трансляции всех команд МП 586
;Структура для описания дескрипторов сегментов
dcr struc limit dw base_ldw basc_m db attr Idb
;Имя структуры ;Граница (биты 0...15) ;База, биты 0...15 ;База, биты 16...23 ;Байт атрибутов 1
уширенные возможности современных микропроцессоров
187
;Граница (биты 16...19) и атрибуты 2 ;База,
биты 24...31
baseji db О
dcr ends ;
data segment use!6 ;
;Таблица глобальных деифипторов GOT
gdt_null dcr <0,0,0,0,0,0> ;Селектор О -обязательный
;нулевой дескриптор
gdt_data dcr <data_size-l,0,0,92h,0,0> ;Селектор 8,
;сегмент данных
gdt_code dcr <сос!е_817е-1,0,0,98п,0,0>;Селектор 16,
;сегмент команд
gdt_stack dcr <511,0,0,92h,0,0> ;Селектор 24 —
;сегмент стека
gdt_screen dcr <4095,8000h,OBh,92h,0,0> ;Селектор 32,
видеобуфер
pdescr df 0 ; Псевдодескриптор для команды Igdt
data_size=:S-gdt_iiull ;Размер сегмента данных
data ends ;Конец сегмента данных
text segment use!6 ;Сегмент команд, 16-разрядный режим
assume CS:text,DS:data;
main proc ;
xor EAX,EAX ;Очистим ЕАХ
mov AX,data ;3агрузим в DS сегментный
mov DS,AX ;адрес сегмента данных
;Вычислим 32-битовый линейный адрес сегмента данных
;и загрузим его в дескриптор сегмента данных в GDT.
;В регистре АХ уже находится сегментный адрес.
;Умножим его на 16 сдвигом влево на 4 бита
shl ЕАХ,4 ;В ЕАХ линейный базовый адрес
mov ЕВР,ЕАХ ;Сохраним его в ЕВР для будущего
mov BX,offset gdt_data ;B BX адрес дескриптора
mov [BX].base_I,AX ;3агрузим младшую часть базы
rol ЕАХ,16 ;Обмен старшей и младшей половин ЕАХ
mov [BX].base_m,AL;3arpy3HM среднюю часть базы
;Вычислим 32-битовый линейный адрес сегмента команд
;и загрузим его в дескриптор сегмента команд в GDT хог ЕАХ,ЕАХ ;Очистим ЕАХ
mov AX,CS ;Сегментный адрес сегмента команд
shl ЕАХ,4 ;В ЕАХ линейный базовый адрес
mov BX,offset gdt_code ;В ВХ адрес дескриптора . mov [BX].base_I,AX;3arpy3HM младшую часть базы rol ЕАХ, 16 ;Обмен старшей и младшей половин ЕАХ
mov [BX].base_m,AL;3arpy3HM среднюю часть базы
;Вьгчислим 32-битовый линейный адрес сегмента стека хог ЕАХ,ЕАХ ;Все, как и для других
mov AX,SS дескрипторов
shl EAX,4
188
Глава -t
mov BX,offset gdt_stack
mov {BX].base_l,AX
rol ЕАХД6
mov [BX].base_m,AL ;Подготовим псевдодескриптор pdescr для загрузки регистра GDTR
mov dword ptr pdescr+2,EBP ;База GOT
mov word ptr pdescr,39 ;ГраницаООТ
Igdt pdescr ;3агрузим регистр GDTR
cli ;3апрет прерываний
; Переходим в защищенный режим
mov EAX,CRO ;Получим содержимое CRO
or EAX,1 ;Установим бит защищенного режима
mov CRO,EAX ;3апишем назад в CRO
; Теперь процессор работает в защищенном режиме ; ? ,
;3агружаем в CS:IP селектор смещение точки continue
db OEAh ;Код команды far jmp
dw offset continue ;Смещение
dw 16 ;Селектор сегмента команд
continue: ;Делаем адресуемыми данные
mov АХ,8 ;Селектор сегмента данных
mov DS,AX ;3агрузим в DS
;Делаем адресуемым стек
mov mov
АХ,24 SS,AX
;Селектор сегмента стека ;3агрузим в SS
Инициализируем ES и вьшодим символ
mov AX,32 ;Селектор сегмента видеобуфера
mov ES,AX ;3агрузим в ES
mov BX,2000 ;Начальное смещение на экране
mov AX,09FOFh ;Символ с атрибутом mov ES:[BX],AX ;Вывод в видеобуфер ;Вернемся в реальный режим
; Установим ;значение границы ;для реатъного ;режима
;3агрузим теневой регистр
;сегмента данных
mov gdt_data.limit,OFFFFh mov gdt_code.limit,OFFFFh
mov mov mov mov mov mov mov mov
gdt_stack.limit,OFFFFh
gdt_screen. limit, OFFFFh
AX, 8
DS,AX
;То же для
; стека
;То же
;для регистра ES
АХ,24 SS,AX АХ,32 ES,AX
;Выполним дальний переход, чтобы заново загрузить ;селектор в CS и модифицировать его теневой регистр
Расширенные возможности современных микропроцессоров
189
db OEah ;Код команды jmp far
dw offset go ;Смещение точки перехода
dw 16 ;Селектор сегмента команд
;Переключим режим процессора
go: mov EAX,CRO ;Получим содержимое CRO
and EAX,OFFFFFFFEh;C6pocHM бит РЕ mov CRO,EAX ;3апишем назад в CRO
db OEah ;Код команды far jmp
dw offset return ;Смещение точки перехода
dw text ;Сегментный адрес
^ ^
; Теперь процессор снова работает в реальном режиме ;
^ ^
; Восстановим операционную среду реального режима
return: mov AX,data mov DS,AX mov AX,stk SS,AX SP,512
mov mov sti mov
AX.4COOU
;3агрузим сегментный ;регистр DS ;3агрузим сегментный ;регистр SS восстановим SP ;Разрешим прерывания ;3авершим программу ;обычным образом
2Ih
int
;Размер сегмента команд ; Конец сегмента команд ; Сегмент ; стека
main endp code_size=S -main text ends stk segment stack
db 512 dup О stk ends
;Конец программы и точка входа
Для того, чтобы разрешить использование всех, в том числе привилегированных команд 32-разрядных процессоров, в программу включена директива .586Р.
Программа начинается с объявления структуры dcr, с помощью которой будут описываться дескрипторы сегментов. Сравнивая описание структуры dcr в программе с рис. 4.9, нетрудно проследить их соответствие друг другу. Для удобства программного обращения в структуре dcr база описывается тремя полями: младшим словом (base_l) и двумя байтами: средним (base_m) и старшим (base_h).
В байте атрибутов 1 задается ряд характеристик сегмента. В примере 4.4 используются сегменты двух типов: сегмент команд, для которого байт attr_l должен иметь значение 98h (присутствующий, только исполнение, DPL=0), и сегмент данных (или стека) с кодом 92п (присутствующий, чтение и запись, DPL=0).
Некоторые дополнительные характеристики сегмента указываются в старшем полубайте байта attr_2. Для всех наших сегментов значение этого
end main
190