Главная страница Случайная страница КАТЕГОРИИ: АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника |
Процессор Intel в защищенном режиме #3
Таблица дескрипторов Итак, к чему мы пришли: оказывается, сегменты не раскиданы по памяти как попало и непонятно где, теперь мы с уверенностью можем сказать где какой из сегментов начинается, где заканчивается, что это за сегмент (код, данные или стек), вся эта информация хранится в ДЕСКРИПТОРЕ. Казалось бы, чего нам не хватает для полного счастья? Все же вроде ясно и понятно и не о чем здесь больше говорить! Однако, есть еще кое что… Один вопрос, который уже должен был загореться в твоем подсознании… ГДЕ ЖЕ НАХОДИТСЯ САМ ДЕСКРИПТОР???!!!:) Находиться он может в трех местах:
Эти таблицы находятся в оперативной памяти (там же, где и собственно сами программы), а не в процессоре, жестком диске или куда еще могут завести тебя фантазии… Поэтому, очевидно, что строить ТАБЛИЦЫ ДЕСКРИПТОРОВ придется «руками», нам самим. И вообще, с этого момента пора привыкать – в защищенном режиме ВСЕ НУЖНО СТРОИТЬ САМОМУ. В этом и заключается сила!:) Несколько слов по поводу первых двух таблиц (на третьей (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 = 1235h1. Descr_code db 34h, 12h, 00h, 00h, 00h, XXh, 0X000000b, 00h 2. Descr_data db 0C8h, 0Dh, 36h, 12h, 00h, XXh, 0X100000b, 00h3. Descr_stack db 0FFh, 00h, 00h, 20h, 00h, XXh, 1X000000b, 00h4. Descr_code2 db 0DEh, 0BCh, 01h, 20h, 10h, XXh, 0X001010b, 00h5. Descr_data2 db 00h, 00h, 00h, 00h, 00h, XXh, 0X000000b, 10h6. Descr_stack2 db 01h, 00h, 10h, 00h, 00h, XXh, 0X000001b, 10h7. Descr_LDT db 04h, 00h, 00h, 00h, 00h, XXh, 1X000000b, 20h GDT_limit = $-GDT GDTR dw GDT_limit-1 dd?Дополнительные задания: 1. Найди ошибку! Один из дескрипторов содержит ОШИБКУ!
|