Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь FAQ Написать работу КАТЕГОРИИ: АрхеологияБиология Генетика География Информатика История Логика Маркетинг Математика Менеджмент Механика Педагогика Религия Социология Технологии Физика Философия Финансы Химия Экология ТОП 10 на сайте Приготовление дезинфицирующих растворов различной концентрацииТехника нижней прямой подачи мяча. Франко-прусская война (причины и последствия) Организация работы процедурного кабинета Смысловое и механическое запоминание, их место и роль в усвоении знаний Коммуникативные барьеры и пути их преодоления Обработка изделий медицинского назначения многократного применения Образцы текста публицистического стиля Четыре типа изменения баланса Задачи с ответами для Всероссийской олимпиады по праву Мы поможем в написании ваших работ! ЗНАЕТЕ ЛИ ВЫ?
Влияние общества на человека
Приготовление дезинфицирующих растворов различной концентрации Практические работы по географии для 6 класса Организация работы процедурного кабинета Изменения в неживой природе осенью Уборка процедурного кабинета Сольфеджио. Все правила по сольфеджио Балочные системы. Определение реакций опор и моментов защемления |
Процессор Intel в защищенном режиме #5Содержание книги
Поиск на нашем сайте
FAQ: - Чето ты с этими лимитами нездорового напорол в спецвыпуске... Какие то «реальные лимиты», «лимиты в натуре» и т.п. Нельзя ли обойтись без подобных медитаций, просто, как есть на самом деле? Вообще все это напоминает недавний бум с миллениумом: в 1999 году все СМИ как один гудели про то, что новое тысячелетие начнется в 2000 году. Потом посчитали и оказалось, что в 2000 начнется только ПОСЛЕДНИЙ ГОД УХОДЯЩЕГО ТЫСЯЧЕЛЕТИЯ, а новое начнется только в 2001... Вот и я туда же - начал выдумывать какие то "реальные лимиты", к-рые соотвествуют "концу последнего байта в сегменте" и т.п. медитации. Хотел как лучше, получилось как всегда...:(Вот КАК В ШЕСТИ СТРОЧКАХ ВСЕ ВЫГЛЯДИТ НА САМОМ ДЕЛЕ, без вольных импровизаций и медитаций: При G=0: Адрес последнего байта сегмента = Значение поля «База сегмента» + Значение поля «Лимит сегмента»Размер сегмента = Значение поля «Лимит сегмента» + 1При G=1: Адрес последнего байта сегмента = Значение поля «База сегмента» + Значение поля «Лимит сегмента» * 1000h + 0FFFh Размер сегмента = Значение поля «Лимит сегмента» * 1000h + 1000hВообще, ВОТ С ЭТОГО и стоило начинать, и на этом и закончить, ато расписал на 2 выпуска + спецвыпуск какой то мути, всех запутал и напугал новичков... Вообще на этой проблеме не стоит сосредотачиваться, нас ждут вещи поважнее. РЕЗУЛЬТАТЫ КОНКУРСА: Правильные ответы: 1. Descr_code db 34h,12h,00h,00h,00h,XXh,0X000000b,00h; сегмент с базой = 0 и размером = 1235h 2. Descr_data db 0C8h,0Dh,36h,12h,00h,XXh,0X100000b,00h; сегмент с базой = 1236h и размером = 0DC9h 3. Descr_stack db 0FFh,00h,00h,20h,00h,XXh,1X000000b,00h; сегмент с базой = 2000h и размером = 100000h 4. Descr_code2 db 0DEh,0BCh,01h,20h,10h,XXh,0X001010b,00h; сегмент с базой = 102001h и размером = 0ABCDFh 5. Descr_data2 db 00h,00h,00h,00h,00h,XXh,0X000000b,10h; сегмент с базой = 10000000h и размером = 1 6. Descr_stack2 db 01h,00h,10h,00h,00h,XXh,0X000001b,10h; сегмент с базой = 10000010h и размером = 10002h 7. Descr_LDT db 04h,00h,00h,00h,00h,XXh,1X000000b,20h; сегмент с базой = 20000000h и размером = 5000hДополнительные задания: Ошибка во втором дескрипторе: бит 21 во втором двойном слове дескриптора ДОЛЖЕН ВСЕГДА равняться нулю. Те, кто знакомы с компиляторами типа TASM без труда смогут загрузить GDTR так: mov eax,offset GDTmov dword ptr GDTR+2,eaxlgdt fword ptr GDTR(но вообще это забегая вперед)Краткое содержание предыдущих серий… Итак, сначала ты узнал, что программа состоит из сегментов и все они расположены в памяти. Каждый сегмент описывает специальная структура – дескриптор. Дескриптор хранится в специальной таблице. Найти в океане памяти таблицу можно по специальному регистру (GDTR, LDTR). Это как в той сказке: на острове – дуб, на дубе ларец, в ларце – яйцо, в яйце – игла и т.д. Ну и с битом гранулярности вроде разобрались (слава Богу!), теперь пора двигать дальше. Селектор «Все это хорошо и понятно» - скажешь ты,- «но вот что-то я ничего пока не слыхал про сегментные регистры (ну те самые – CS, DS, SS…). Что-то они себя пока никак не проявили, а мне казалось, что именно ОНИ, как никто другие, должны служить нам при обращении к памяти и все такое…» Если ты заметил, то мы все это время спускаемся вниз по ступенькам: сегмент в памяти <---- дескриптор <---- таблица дескрипторов … Следующей ступенью будет СЕЛЕКТОР. Не правда ли, где-то это слово уже встречалось? Так вот: селектор – это 16-битная структура данных (что??!! ОПЯТЬ??!!!...), которая является идентификатором сегмента. - Боже ж ты мой! Сколько это будет продолжаться??!! У каждого сегмента есть свой дескриптор, мы уже прекрасно знаем где этот чертов дескриптор расположен, а ты нам подсовываешь еще какой-то «селектор»!!! … Селектор указывает не на САМ сегмент в памяти, а на его дескриптор, в таблице дескрипторов… СЕЛЕКТОР ЖИВЕТ В СЕГМЕНТНОМ РЕГИСТРЕ (CS, DS…). -Неужели…?! Ну и хрена с того? Спокойно!!!! Вот он: Поле ИНДЕКС (биты 3-15): указывает на один из 8192 дескрипторов в таблице дескрипторов (GDT или LDT). Почему 8192? А какое максимальное число по-твоему влезет в «биты 3-15»? Во-во… - Подожжи, подожжи… не так быстро… Ведь дескриптор же занимает 8 байт так? А если индекс равен двойке? Так что это, значит, селектор указывает на второй байт дескриптора в таблице или что? ИЛИ ЧТО! ПРОЦЕССОР УМНОЖАЕТ значение поля ИНДЕКС НА 8 И ДОБАВЛЯЕТ к полученному значению АДРЕС БАЗЫ ТАБЛИЦЫ. Т.е. процессор умножит «двойку» на 8, а потом прибавит значение регистра таблицы – и мы благополучно указываем НА НАЧАЛО ДЕСКРИПТОРА, как не крути!!! - Как же узнать, из КАКОЙ ИМЕННО ТАБЛИЦЫ дескриптор? Вот для этого нужен флажок TI (table indicator) (второй бит). Если он = 0, то прибавится значение регистра GDTR (т.е. дескриптор расположен в таблице GDT), если же установлен – LDTR. - А шо за RPL? (Requested Privilege Level) Запрашиваемый уровень привилегий… пока его лучше не трогать. Но видишь, пока что, все что нам не знакомо относится к каким то загадочным уровням привилегий… Теперь внимательно следи: допустим мы ложим в DS число 0000000000110 0 00b. Что это значит? А смотри: сразу разбиваем DS на кусочки (15-3 биты – индекс, 2 – TI, 1-0 – пока лучше не смотрим на них). Индекс равен 6. Значит, шестой по счету дескриптор. А где? В GDT конечно! (TI=0). Ложим (кладем:) в ES число 0000000001000 1 00b. Восьмой дескриптор! На этот раз в LDT! Разобрались! - А учитывается ли нулевой дескриптор (null descriptor) при «счете»? ОБЯЗАТЕЛЬНО! БОЛЕЕ ТОГО! МЫ ДАЖЕ МОЖЕМ ПОЛОЖИТЬ В сегментный регистр (DS, SS…) СЕЛЕКТОР С ПОЛЕМ ИНДЕКС и TI РАВНЫМИ 0!!! Т.е. фактически мы выбираем НУЛЕВОЙ ДЕСКРИПТОР В ТАБЛИЦЕ GDT!! -Но это же невероятно и невозможно!!!!:) Возможно… Ничего страшного не произойдет до тех пор, пока мы не ОБРАТИМСЯ К ПАМЯТИ, используя ТАКОЙ сегментный регистр… А так он может хоть сто лет там пролежать, но как только мы обратимся к памяти используя такой регистр (с индексом = 0) – ВСЕ! ХАНА! #GP!!!! Преобразование логического адреса в линейный И вот мы подобрались к самому важному моменту: как же все таки процессор формирует адрес и знает куда обращаться? Для этого нужно собрать все полученные нами знания в кучу. Что для этого нужно сделать? Уважаемый читатель, представь, что ты процессор... Допустим, сейчас ты выполняешь какой то код в оперативной памяти. И вот как ты размышляешь: о местоположении в памяти инструкции тебе ничего не известно, кроме того, что на нее указывает CS:EIP. По сути - это логический (т.е. некий абстрактный адрес). Как же найти линейный адрес в памяти, руководствуясь только этими двумя значениями: CS и EIP? Теперь мы можем это сделать! Сразу смотрим в CS и ищем в нем поле "Индекс" (см. на селектор выше). Смотрим в поле индекс и тут же узнаем о местоположении нужного дескриптора в таблице дескрипторов. Далее нам нужно узнать АДРЕС БАЗЫ сегмента. Узнали. Что теперь? Теперь осталось только одно: сложить этот адрес базы с EIP - и мы получим линейный адрес инструкции в памяти (к-рый при сегментной организации совпадает с физическим, мы об этом говорили ранее). Еще раз: селектор-->дескриптор-->база... +EIP = ЛИНЕЙНЫЙ адрес. Сегментный регистр В архитектуре процессоров Intel существуют ШЕСТЬ сегментных регистров: CS, DS, SS, ES, GS и FS. Каждый из этих регистров отвечает за свой сегмент в памяти (кода, данных или стека). Итак, даже если программа состоит из ТЫСЯЧИ сегментов, ТОЛЬКО 6 из них могут быть доступны В ДАННЫЙ МОМЕНТ ВРЕМЕНИ. Другие сегменты станут доступны ТОЛЬКО ПОСЛЕ ЗАГРУЗКИ СООТВ. селекторов в сегментные регистры. Помнишь, как в реальном режиме формировались линейные адреса? Значение сегментного регистра умножалось на 10h и прибавлялось смещение. Т.е. никакого селектора явно не существовало, никаких дескрипторов, ничего! Только сегментный регистр и смещение! Один шаг до формирования линейного адреса! В защищеном режиме нужно пройти сквозь огонь, воду и медные трубы (селектор-дескриптор- база...) чтобы докопаться до линейного адреса... Итак, в защищенном режиме сегментный регистр - это 16 битный регистр, содержащий информацию о дескрипторе (а именно - местоположении) и запрашиваемом уровне привилегий. Стоп! Здесь сразу же возникает вопрос: неужели же процессор при каждом обращении к памяти все время повторяет одни и те же действия (ищет дескриптор, потом ищет базу, затем прибавляет к базе смещение...), и так при выполнении фактически каждой команды... КОНЕЧНО ЖЕ НЕТ! НА САМОМ ДЕЛЕ сегментный регистр - это 80-битный регистр (!!! да да!!!), нам же доступны ТОЛЬКО младшие 16 бит, которые и называются СЕЛЕКТОРОМ!!! Остальные 64 бита называются "Теневым регистром" (Shadow register) или "Дескрипторным кэшем" (Descriptor cache), ОНИ И СОДЕРЖИТ ТУ САМУЮ БАЗУ, которую проц по идее должен был бы высчитывать на каждом шаге. Кроме базы этот самый "теневой регистр" содержит еще и лимит, и права доступа. Еще раз: как только мы загружаем в ВИДИМУЮ ЧАСТЬ (в селектор) соответствующее значение, процессор СРАЗУ же по селектору (а конкретно - по полю индекс) выпасает базу, лимит и права доступа из дескриптора и заносит их в "теневую часть" сегмнетного регистра, тем самым облегчая себе жизнь в дальнейшем. А ТЕПЕРЬ ВНИМАНИЕ!!! Если мы вдруг решим неожиданно поменять значение базы в дескрипторе для какого-либо сегмента, селектор которого в данный момент УЖЕ находится в сегментном регистре, то мы также должны позаботиться и о ПЕРЕЗАГРУЗКЕ сегментного регистра, т.к. в теневой части остануться СТАРЫЕ ЗНАЧЕНИЯ базы и лимита, и фактически процу абсолютно наплевать на то, что твориться в таблице дескрипторов, он руководствуется только ТЕКУЩИМ ЗНАЧЕНИЕМ БАЗЫ И ЛИМИТА В ТЕНЕВОЙ ЧАСТИ. Короче запомни золотое правило: поменял базу (или лимит) в дескрипторе - перегрузи соотв. сегментный регистр!!! Загрузить сегментные регистры (явно или неявно) позволяют 16 команд: ЯВНО: MOV - ну это и так ясноPOP - значение из стекаLDS - загрузить DSLES - загрузить ESLSS - загрузить SSLGS - загурзить GSLFS - загрузить FSНЕЯВНО: CALL, JMP, RET, SYSENTER, SYSEXIT, IRET, INTn, INTO, INT3. Чаще всего "неявные" команды изменяют значение именно CS-регистра, но в некторых случаях и других. Кстати, как ты понимешь, в реальном режиме архитектура проца никуда не девается, при загрузке селектора в сегм. регистр процессор сам создает соответствующий дескриптор в его сркытой части. Он описывает 16-битный сегмент, начинающийся по указанному адресу с границей 64 Кб. СТРАНИЧНАЯ АДРЕСАЦИЯ Ну вот, наконец-то мы добрели и до страничной адресации (не прошло и месяца:). Стоит отметить, что подписчики, у которых не возникло проблем с сегментной адресацией также легко и просто освоят страничную. Прежде всего, нужно понять очень важную вещь: при использовании страничной адресации структуры из сегментной адресации (как то – таблицы дескрипторов, селекторы, регистры таблиц дескрипторов) НИКУДА НЕ ДЕВАЮТСЯ! Все остается на своих местах! Так в чем же тогда заключается страничная адресация? Где же она себя проявляет? ВАЖНЫЙ МОМЕНТ: ЕДИНСТВЕННОЕ МЕСТО, ГДЕ СТРАНИЧНАЯ АДРЕСАЦИЯ ДЕЙСТВИТЕЛЬНО ВКЛИНИВАЕТСЯ В ПРОЦЕСС РАБОТЫ ПРОЦЕССОРА – ПРИ ПЕРЕВОДЕ ЛИНЕЙНОГО АДРЕСА В ФИЗИЧЕСКИЙ! Вот в этом вся соль! ЭТИМ НУЖНО ПРОНИКНУТЬСЯ! Придется немного прокрутить пленку назад. Вспомни три понятия: логический, линейный и физический адрес. Логический адрес – это некий абстрактный, на деле ничего не значащий адрес, грубо говоря, CS:EIP – это и есть логический адрес, в самом деле, что он может нам сообщить? Ничего. Только то, что если мы вытащим из CS поле индекс, а затем по этому полю найдем в таблице дескрипторов соотв. дескриптор, а затем к базе из этого дескриптора прибавим EIP – то вот только тогда получим ЛИНЕЙНЫЙ адрес. При использовании сегментной адресации физический адрес совпадает с линейным (физический – это адрес который проц выставляет уже на адресную шину). Т.е. при сегментной адресации проц просто берет линейный адрес и без выкрутасов выставляет на адресную шину. При использовании страничной адресации именно на этапе перевода линейного адреса в физический в действие вступают новые силы, о коих и будет поведано ниже... При использовании страничной адресации линейный адрес не совпадает с физическим, как в случае с сегментной адресацией. Т.е. мы имеем дело с виртуальной памятью. Процессор делит линейное адресное пространство на страницы фиксированного размера (длиной 4Кб, 2Мб или 4Мб), которые, в свою очередь, уже отображаются в физической памяти (или на диске). Когда программа (или задача) обращается к памяти через логический адрес, процессор переводит его в линейный и затем, используя механизму страничной адресации, переводит его в соответсвтующий физический адрес. Если страницы в данный момент нет в физической памяти, то возникает исключение #PF. Это по сути кульминационный момент: обработчик этого исключения (#PF) должен выполнить соответствующие манипуляции по устранению данной проблемы, т.е. подгрузить страницу с харда (или наоборот – скинуть ненужную страницу на диск). Вообщем, все знают что такое своп-файл в винде? Вот по сути это и есть те самые странички памяти на харде, которые после возникновения #PF должны быть загружены в оперативку (или наоборот). По сути - #PF это не есть нечто ужасное и недопустимое (как #GP). НАОБОРОТ! #PF «нам строить и жить помогает!!!» Без него вообще ничего бы и не получилось по сути то дела! Как только страница была благополучно водворена на место, то выполнение прерванной проги продолжается с той самой инструкции, которая вызвала #PF. А кстати, какая инструкция может вызвать #PF? Да в принципе любая, которая так или иначе обращается к памяти... Страничная организация отличается от сегментной еще и тем, что все страницы имеют фиксированный размер (в сегментной размер сегментов абсолютно произволен). Также при сегментной адресации все сегменты обязательно должны присутствовать непосредственно в оперативе, а при страничной возможна ситуация, когда кусок сегмента находится в памяти, а другой кусок фактически того же сегмента – на харде (т.е. другими словами – часть страниц сегмента находится в оперативе, а часть – валяется в то же время на харде). Проц всегда, где это возможно, облегчает себе жизнь. Вспомни про «теневую» часть сегментного регистра. Также и в случае со страничной адресацией – страницы, к которым проц чаще всего обращается кэшируются в процессоре, в области, которая называется буфер с ассоциативной выборкой (TLB - Table lookaside buffer). Т.е. не все такие страницы целиком, а только записи, которые необходимы для доступа к ним (см. ниже). Несколько слов по поводу TLB. Начиная с P6 процев сущестувуют кэши специально для записей, описывающих код и данные, также разные кэши для 4Кб и для 4Мб страниц. Инструкция CPUID позволяет определить размер этих самых TLB в твоем проце. Чем они больше – тем быстрее соответственно будет работать проц. В отличии от теневой части сегментного регистра, куда мы не могли лезть руками и вообще не имели никакого доступа к ней, в TLB мы можем кое что изменять (естественно только в том случае, если мы на самом крутом уровне привилегий, на нулевом). Для этого существует команда INVLPG и др. приемы, на которых не стоит заострять внимания (если кому интересно в подробностях – пишите). Итак, страничная организация непосредственно в проце управляется тремя флажками:
Теперь подробнее. Флаг PG разрешает страничную адресацию. Сразу после установки его в единицу страничная адресация включена. Флаг PSE, если его установить, позволяет использовать страницы больших размеров (4Мб и 2Мб). Если сброшен – страницы имеют размер 4Кб. Флаг PAE позволяет расширить физический адрес до 36 бит (стандартно он 32-х битный). Данный флаг можно использовать ТОЛЬКО в режиме страничной адресации. Узнать, поддерживает ли твой проц данное расширение можно по 17 биту в EDX после CPUID). Кстати, использовать 36-разрядную адресацию можно как с помощью PAE-флага, так и с помощью PSE-флага, это два разных метода, мы их рассмотрим дальше. Каталоги и таблицы страниц. Ну все, хватит лирики, пора приступать к делу. При трансляции линейного адреса в физический (при включенной страничной адресации) процессор использует 4 структуры данных: 1. Каталог страниц – массив 32-битных записей (PDE – page- directory entry), к-рые хранятся в 4Кб странице. Напоминает таблицу дескрипторов, не так ли? А сколько 32-битных записей помещается в 4Кб? Правильно, 1024 штуки. Т.е. всего 1024 PDE- шки... 2. Таблица страниц – массив 32-битных записей (PTE – page-table entry), которые также все расположены в одной 4Кб странице. Т.е. PTE-шек тоже может быть всего 1024 штуки. Забегая вперед – для 2Мб и 4Мб страниц таблица страниц вообще никак не используется – все решают только PDE-шки. 3. Сама страница – 4Кб, 2Мб или 4Мб кусок памяти:) 4. Указатель на каталог страниц – массив 64-битных записей, каждая из которых указывает на каталог страниц. Эта структура данных используется процем только при использовании 36-битной адресации. Все эти таблицы позволяют обращаться к 4Кб или к 4Мб страницам при 32-х битной адресации и к 4Кб, 2Мб или 4Мб страницам при 36-битной адресации. Смотри на таблицу, какие флаги на что влияют: Непонятно тут может быть только одно – что за колонка PSE-36? Дело в том, что этот режим работы (PSE-36) появился только в третьих пнях, а доступен он или нет можно узнать посредством CPUID. Как видишь, при использовании PSE-36 механизма доступны только страницы размером 4Мб. Фактически таким макаром можно адресовать 64 Gb физического адресного пространства. Конечно, на первый взгляд получается несколько туманно и путано, столько флажков, какие то разрядности, но на самом деле все довольно четко и логично, просто надо вникнуть, а потом задать вопросы). Вообщем, расклад таков: при страничной организации существуют 3 способа адресации: 32-х разрядная, 36-разрядная с использованием флага PAE и 36-разрядная с использованием флага PSE. Для начала рассмотрим самую простую и наглядную – 32-х разрядную адресацию. Все о чем пойдет дальше речь – справедливо только для нее.
|
||||
Последнее изменение этой страницы: 2016-06-22; просмотров: 274; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.226.34.148 (0.011 с.) |