ПРОЦЕССОР INTEL В ЗАЩИЩЕННОМ РЕЖИМЕ

 

Выпуск №3

 

 

FAQ выпуска №2:

 

- Я не вижу никакой картинки с дескриптором! Что делать?

 

Дело в том, что сама картинка находится здесь: http://brokensword.narod.ru/descriptor.gif, при просмотре второго выпуска рассылки ты должен находится в онлайне и дождаться, пока она полностью загрузится. Потом сохрани ее целиком, как ты обычно это делаешь со страницами, содержащими картинки. У кого НЕТ интернета, а только почта – пишите на brokensword@ukr.net я его вам вышлю по мылу (весит 5 килобайт)

 

__________________________________________________

 

Рассылка постепенно набирает обороты! Я по прежнему жду не дождусь писем с вопросами… Вариантов здесь может быть только два: или вам все сходу понятно, или вообще ничего не понятно… Второй вариант как то не особо впечатляет на дальнейшее продолжение. Хотя, пока слишком мало материала, и спрашивать, по сути, не о чем.

 

 

Таблица дескрипторов

 

Итак, к чему мы пришли: оказывается, сегменты не раскиданы по памяти как попало и непонятно где, теперь мы с уверенностью можем сказать где какой из сегментов начинается, где заканчивается, что это за сегмент (код, данные или стек), вся эта информация хранится в ДЕСКРИПТОРЕ. Казалось бы, чего нам не хватает для полного счастья? Все же вроде ясно и понятно и не о чем здесь больше говорить! Однако, есть еще кое что… Один вопрос, который уже должен был загореться в твоем подсознании… ГДЕ ЖЕ НАХОДИТСЯ САМ ДЕСКРИПТОР ???!!! :)

 

Находиться он может в трех местах:

 

- Глобальная таблица дескрипторов (GDT - Global Descriptor Table)

- Локальная таблица дескрипторов (LDT - Local Descriptor Table)

- Таблица дескрипторов прерываний (IDT Interrupt Descriptor Table)

 

 

Эти таблицы находятся в оперативной памяти (там же, где и собственно сами программы), а не в процессоре, жестком диске или куда еще могут завести тебя фантазии… Поэтому, очевидно, что строить ТАБЛИЦЫ ДЕСКРИПТОРОВ придется «руками», нам самим. И вообще, с этого момента пора привыкать – в защищенном режиме ВСЕ НУЖНО СТРОИТЬ САМОМУ. В этом и заключается сила! :)

 

Несколько слов по поводу первых двух таблиц (на третьей (IDT) мы остановимся в главе посвященной прерываниям в защищенном режиме).

 

 

Глобальная таблица дескрипторов (GDT):

 

ЗАПОМНИ: КАЖДАЯ ОС ДОЛЖНА ИМЕТЬ ОДНУ ТАБЛИЦУ GDT!!! Без нее – никуда! Ей (таблицей) могут пользоваться ВСЕ (!) программы и задачи системы. Что значит «пользоваться таблицей дескрипторов»? Это значит, хранить в ней СВОЙ дескриптор.

Таблица GDT – сама по себе НЕ СЕГМЕНТ! Это структура данных в линейном адресном пространстве (в памяти). НАЧАЛО таблицы GDT храниться В РЕГИСТРЕ GDTR! Регистр GDTR – это самый обыкновенный регистр, такой же обыкновенный, как EAX, EIP, ES, только вот его функция заключается не в хранении каких-то промежуточных данных, а в хранении фиксированного числа – НАЧАЛА ТАБЛИЦЫ GDT. Называние регистра GDTR запомнить очень легко: GDT – это таблица, R – регистр. Не правда ли, пока все просто? )

Да, кстати, не упусти важный момент: мы должны сделать все так, чтобы начало таблицы GDT в памяти было кратно 8. Это связано с архитектурой и так проц быстрее соображает при обращении к таблице.

 

GDTR:

32-битный линейный базовый адрес

16-битный лимит таблицы

 

 

Вот он, регистр GDTR. Весит 48 бит. Как видишь, он содержит не только адрес начала таблицы GDT в памяти, а еще и ее лимит. Лимит таблицы – 16-битное значение, показывает величину таблицы в байтах + 1. (т.е. все как и в случае с лимитом сегмента: если лимит таблицы в GDTR равен 0, то на самом деле это означает что реально (в памяти) лимит равен одному байту).

 

Как ты уже знаешь, сегментный дескриптор ВСЕГДА занимает 8 байт (2 двойных слова). Если уже забыл – посмотри на картинку из 2 выпуска. Следовательно, лимит таблицы дескрипторов – величина, равная 8N-1 байт. Но и N – тоже не резиновая величина. Скоро узнаешь каков предел этого самого N (т.е. сколько всего дескрипторов может содержать таблица)

 

Первый дескриптор в GDT не используется и называется «нулевой дескриптор» (null descriptor). При обращении к памяти через этот дескриптор возникает уже знакомая нам «рука правосудия» с #GP, и все опять вынуждены пасть ниц :)

 

Поэтому первый дескриптор в GDT – РУКАМИ НЕ ТРОГАТЬ!

 

Загрузить/считать значение регистра GDTR можно командами LGDT/SGDT. По умолчанию (т.е. после нажатия на кнопку Reset или включения компа) база GDT равна нулю, а лимит – FFFFh, т.е. фактически по умолчанию выделено максимум места, под FFFFh/8 = 8191 дескрипторов (ну минус один, учитывая null descriptor).

 

 

 

Локальная таблица дескрипторов (LDT):

 

В отличии от GDT совершенно не ОБЯЗАНА присутствовать вообще. И в то же самое время, ПО ЖЕЛАНИЮ, их можно развести великое множество (GDT ДОЛЖНА БЫТЬ только одна). Каждая задача может иметь свою собственную LDT, в то же время несколько задач могут использовать одну LDT на всех.

LDT – это СЕГМНЕТ! (GDT – структура данных). Это принципиально! И вот почему: т.к. LDT – это сегмент, то значит у нее тоже есть свой дескриптор! И где бы вы думали? Да все в той же GDT!!! Да да, звучит несколько странновато – у таблицы дескрипторов есть свой дескриптор!! Но, то ли еще будет! :)

 

Так же, как и у GDT у LDT тоже есть свой регистр – LDTR. В отличии от GDTR этот регистр, помимо инфы про базу и лимит LDT, содержит еще одно поле – сегментный селектор. Пока что не вникай, просто запомни слово – СЕЛЕКТОР.

 

LDTR:

Сегм. Селектор (16 бит)

32-битный линейный базовый адрес

16-битный лимит сегмента

 

Инструкции LLDT и SLDT позволяют писать/читать регистр LDTR. Точно так же, при reset-е значение базы в LDTR падает в ноль, а лимит – в FFFFh

 

 

 

 

Ну и напоследок - ВНИМАНИЕ! КОНКУРС!!! )

 

Перед тобой пример структуры, которая являет собой таблицу GDT (вместо ИКС-ов значения, которые мы еще не рассматривали, поэтому не смотри на них); Тебе предстоит найти РЕАЛЬНЫЕ ЗНАЧЕНИЯ базы и лимита для каждого из описуемых семи сегментов (именно линейные адреса в памяти). Для одного из них дана подсказка в комментарии. Победителей ожидают ценные призы, а того, кто первым пришлет ответ – КВАРТИРА В МОСКВЕ! Поторопитесь!!!

Чтобы было проще – открой картинку с дескриптором и смотри одним глазом на нее, другим - на значения. Да, и помни: смотреть картинку нужно «задом-наперед» (т.е. сначала младшие байты, потом старшие):

 

GDT:

; нулевой дескриптор (ОБЯЗАТЕЛЬНО ДОЛЖЕН ПРИСУТСВОВАТЬ, НО РУКАМИ НЕ ТРОГАТЬ!)

0.                      db    8 dup (0)

 

; Сегмент с  базой в 0 и лимитом в 1235h (не забывай про +1 к лимиту!)

; Линейный адрес базы = 0, линейный адрес лимита = 0 + 1235h = 1235h

1. Descr_code           db    34h,12h,00h,00h,00h,XXh,0X000000b,00h

 

2. Descr_data           db    0C8h,0Dh,36h,12h,00h,XXh,0X100000b,00h

3. Descr_stack          db    0FFh,00h,00h,20h,00h,XXh,1X000000b,00h

4. Descr_code2          db    0DEh,0BCh,01h,20h,10h,XXh,0X001010b,00h

5. Descr_data2          db    00h,00h,00h,00h,00h,XXh,0X000000b,10h

6. Descr_stack2         db    01h,00h,10h,00h,00h,XXh,0X000001b,10h

7. Descr_LDT            db    04h,00h,00h,00h,00h,XXh,1X000000b,20h

 

GDT_limit                =    $-GDT

 

GDTR                    dw    GDT_limit-1

                        dd    ?

 

 

Дополнительные задания:

 

1. Найди ошибку! Один из дескрипторов содержит ОШИБКУ!

2. Покажи, как правильно нужно загрузить регистр GDTR.

 

Ответы присылать сюда: brokensword@ukr.net в таком виде

1.  Линейный адрес базы = 0

    Линейный адрес лимита = 1235h

 

2.  . . .

 

 

Слово «линейный адрес» можешь опустить :)

 

Ариведерчи

 

 

Hosted by uCoz