Процессор Intel в защищенном режиме #10 — Архив WASM.RU

Все статьи

Процессор Intel в защищенном режиме #10 — Архив WASM.RU

Об этом мало кто знает...

Можно пропустить

Все, о чем пойдет речь в данном выпуске представляет большой интерес для разработчиков ОС и тех, кому просто хочется видеть все насквозь.

На создание данного выпуска побудила огромная неразбериха, творящаяся в литературе по описанию архитектуры различных ОС. Многие авторы, которые пишут свои книги со слов разработчиков ОС (Хелен Кастер) или сами являющиеся оными (Мэт Питрек) очень часто недоговаривают и перевирают некоторые наиважнейшие понятия (в некоторых случаях это делается специально, ввиду засекреченности того или иного аспекта), но путать три совершенно различных понятия адресного пространства - просто недопустимо. Авторы практически 90% книг копируют друг у друга различные определения, получается нечто вроде "испорченного телефона", а страдаем в конечном итоге мы.

Все дело во взаимосвязи и сути трех наиважнейших понятий в идеологии адресации: ВИРТУАЛЬНОЕ, ЛИНЕЙНОЕ и ФИЗИЧЕСКОЕ адресные пространства. Все эти понятия - отдельные сущности, взаимодействуют между собой, НО НИ В КОЕМ СЛУЧАЕ нельзя путать эти термины, поскольку на их совокупности зиждется любая ОС.

Например, очень часто в литературе по ОС можно встретить такие высказывания: "виртуальное (линейное) адресное пространство процесса..." или некоторые еще хитрее - не указывают, какое именно адресное пространство имеется ввиду - просто "адресное пространство процесса..."

Виртуальное адресное пространство процессора Intel (IA32) в защищенном режиме

Виртуальный адрес (он же логический) в процессорах с 32-х разрядной архитектурой (IA32) - совокупность ВСЕХ возможных адресов вида:

сегментный_регистр:смещение

Например, CS:12345678h - виртуальный (логический) адрес

В старой ОФИЦИАЛЬНОЙ документации (1995 г.) адреса такого вида назывались интеловцами виртуальными, в новой (2002 г.) они дают новое определение - логический, но по сути - это синонимы.

Почему ВИРТУАЛЬНЫЙ? Где здесь виртуальная сущность? Виртуальная сущность в том и состоит, что глядя на нечто вроде 6666h:12345678h НИКОГДА НЕЛЬЗЯ СКАЗАТЬ НАВЕРНЯКА, ОДНОЗНАЧНО, что на самом деле представляют из себя эти два числа. Знакомые с защищенным режимом сразу определят, что это некий адрес, и по левой части (селектору) можно найти число (базу), прибавляя к которой правую часть получится некий другой адрес, в общем, 6666h:12345678h - это некий виртуальный адрес, на самом деле (физически) его и нет вовсе...

Теперь давайте разберемся, каков размер виртуального (логического) адресного пространства процессора. Многие тут же не задумываясь ответят - 4 Гб, потому что так написано во многих книгах, но, однако, внимательный читатель рассылки не будет делать столь скоропалительных выводов.

Итак, рассмотрим правую часть виртуального адреса. Здесь все и так понятно: 2^32 = 4Гб, т.е. правая часть виртуального адреса может принять 4Гб различных значений.

НО ЕСТЬ ЕЩЕ И ЛЕВАЯ ЧАСТЬ ВИРТУАЛЬНОГО АДРЕСА!!! (о которой почему то авторы многих книг забывают).

Здесь самое время привести уже подзабытые иллюстрации:

Селектор - это и есть та самая левая часть виртуального адреса.

Теперь, избавимся от битов, которые НИКАКИМ БОКОМ НЕ ОТВЕЧАЮТ за адресацию. Это два бита RPL. Многие с горяча захотят подмахнуть сюда еще и TI, но этого делать не нужно, т.к. TI - это индикатор таблицы дескрипторов, и он ЕЩЕ КАК отвечает за адрес, который в конце концов вылезет на адресную шину... (но это забегая вперед).

Теперь:

GDT может содержать 8192 дескриптора. 
LDT может содержать 8192 дескриптора.

Нулевой дескриптор в GDT - недоступен.

Значит, имеем 8191 - в GDT и 8192 - в LDT.

Всего - 16383 дескрипторов. И каждый - 4Гб. 
Всего: 16383 * 4Гб = 65532 Гб  (64 Тб)

Иначе говоря, виртуальный адрес - НЕ 32-х РАЗРЯДНЫЙ!!!

ОН - 46 РАЗРЯДНЫЙ!!! (32 бита смещения + 1 бит (TI) + 13 бит (индекс) )

2^46 байт = 65536Гб = 64 ТЕРАБАЙТ !!! - это и есть виртуальное адресное пространство процессора Интел в защищенном режиме.
(но реально, за вычетом нулевого дескриптора из GDT, имеем на 4Гб меньше адресов - 65532Гб)

Всеобщие заблуждения: 64 терабайтное виртуальное адресное пространство, якобы, получается в Pentium Pro процессорах при использовании механизма PAE и PSE-36. На самом деле, PSE-36 ЭТО РАСШИРЕНИЕ ФИЗИЧЕСКОГО АДРЕСНОГО пространства, о нем далее, а на ВИРТУАЛЬНОЕ АДРЕСНОЕ ПРОСТРАНСТВО все эти расширения никак не влияют - оно ВСЕГДА = 64 терабайтам.

(цитата из ОФИЦИАЛЬНОГО мануала Интел-а 2002 г.: "the PAE paging mechanism and support for 36-bit physical addressing were introduced into the IA-32 architecture in the Pentium Pro processors...)

А теперь внимание вопрос на засыпку: чему, по вашему мнению, равен размер виртуального адресного пространства процессора Intel в РЕАЛЬНОМ РЕЖИМЕ? Ответы мыльте на ящик внизу.

Линейное адресное пространство процессора Intel (IA32) в защищенном режиме

Линейный адрес - это 32-х разрядный адрес, получаемый путем прибавления 32-х разрядного смещения (правая часть виртуального адреса) к базе сегмента.

Линейный адрес - ВСЕГДА 32-х разряден. В этом легко убедиться, попытавшись опровергнуть это утверждение. Попробуйте создать сегмент с базой в 4Гб и сделать что то типа jmp селектор_этого_сегмента:2Гб (т.е. фактически должен возникнуть линейный адрес = 4 Гб (база) + 2 Гб (смещение) = 6 Гб). Вместо этого мы получим #GP. Вот и все.

Поэтому, ЛИНЕЙНОЕ АДРЕСНОЕ ПРОСТРАНСТВО процессора Intel в защищенном режиме составляет 4 Гб.

Физическое адресное пространство процессора Intel (IA32) в защищенном режиме

Здесь возможны два варианта:

  1. В режиме сегментной адресации физический адрес ВСЕГДА СОВПАДАЕТ с линейным.
  2. В режиме сегментно-страничной адресации физический адрес НЕ СОВПАДАЕТ с линейным, а получается путем разбиения линейного адреса на 3 части и путешествия по каталогам и таблицам страниц.

По сути, при включенной сегментно-страничной адресации, линейный адрес также таит в себе некую "виртуальную сущность", потому что в принципе может быть представлен в виде X:Y:Z (действительно, он состоит из трех совершенно разных чисел: номера записи в каталоге страниц, номера записи в таблице страниц и смещения в странице), однако не стоит углубляться в такие дебри.

Физический адрес - это тот адрес, который процессор ВЫСТАВЛЯЕТ НА АДРЕСНУЮ шину процессора.

Вот здесь возникает еще одно заблуждение: многие считают, что физический адрес и адрес в оперативной памяти - это одно и то же. На самом деле, если разобраться, физический адрес - МОЖЕТ соответствовать адресу ячейки оперативной памяти (если она существует), либо НЕ МОЖЕТ (если ячейки по такому адресу не существует). В любом случае, следует помнить, что физический адрес - ЭТО НЕ ЕСТЬ АДРЕС ЯЧЕЙКИ ОПЕРАТИВНОЙ ПАМЯТИ, хотя и МОЖЕТ совпадать с ним.

Например, окончательно сформированный процессором из линейного адреса физический адрес составляет 678 Мб, он выставляется на адресную шину. А оперативной памяти на машине стоит, предположим, 256 Мб. Вот и ответьте сами себе: является ли ВЫСТАВЛЕННЫЙ физический адрес одновременно адресом ячейки в оперативной памяти? Конечно же нет! Такой ячейки попросту НЕ СУЩЕСТВУЕТ! Другой интересный вопрос - ЧТО ПРОИЗОЙДЕТ в таком случае дальше? Здесь уже все зависит от чипсета материнской платы - либо процессору будет послан сигнал #RESET (что и происходит в 90% случаях), либо он просто получит фиктивные данные. Но это не суть важно - важно, что множество АДРЕСОВ ЯЧЕЕК ОПЕРАТИВНОЙ ПАМЯТИ ВХОДИТ в множество ФИЗИЧЕСКИХ АДРЕСОВ.

За бортом остались такие интересные вопросы, как, например: "...А как ОС узнает о размере оперативной памяти, установленной на компьютере? Это число не хранится ни в одной ячейке области данных БИОС". Об этом, надеюсь, мы поговорим в следующих выпусках.

К чему я все это веду...

Очень часто, в 99% книг, можно встретить такое высказывание: "...Виртуальное (линейное) адресное пространство процесса составляет 4Гб..."

В одном предложении - сразу 2 ошибки, причем непростительные. Первая ошибка - ВИРТУАЛЬНОЕ и ЛИНЕЙНОЕ адресные пространства - взаимосвязаны, но это НИ В КОЕМ СЛУЧАЕ НЕ ОДНО И ТО ЖЕ!

Вторая ошибка: А ЧЕМУ ЖЕ СОБСТВЕННО, РАВНО ВИРТУАЛЬНОЕ АДРЕСНОЕ ПРОСТРАНСТВО ПРОЦЕССА? Действительно ли 4 Гб? Давайте разберемся...

Как известно, при создании процесса сегм. регистры загружаются такими значениями: CS = X, DS=SS=FS=GS=ES=Y, т.е. CS отличается от всех остальных (что не удивительно - попробуйте загрузить в сегм. регистр кода селектор сегмента данных или наоборот - #GP гарантировано). Поэтому имеем такую картину: ДВА РАЗНЫХ СЕЛЕКТОРА! Какой вывод мы должны сделать из этого? Может, он покажется шокирующим, но это факт - ВИРТУАЛЬНОЕ АДРЕСНОЕ ПРОСТРАНСТВО ПРОЦЕССА В ОС WINDOWS = 8 Гб !!! Т.е. процесс использует 8Гб виртуального адресного пространства из доступного 64 терабайтного! А если бы значения в DS, SS, FS, GS, ES также различались??? Ну что ж, тогда виртуальное адресное пространство процесса в ОС Windows составляло бы 24 Гб (6 сегм. регистров x 4 Гб)!

Итак, ВИРТУАЛЬНОЕ адресное пространство процесса в Win - 8 Гб! А все потому, что мы имеем ДВА РАЗНЫХ СЕЛЕКТОРА, а ведь именно они и участвуют в ФОРМИРОВАНИИ ВИРТУАЛЬНОГО АДРЕСНОГО ПРОСТРАНСТВА, оспорить это невозможно...

Замечание: на самом деле, в ОС Win, при создании процесса в сегм. регистр FS кладется ОТЛИЧНОЕ от DS, SS, GS, и ES значение, и этот регистр указывает на некоторую структуру (сегмент с базой 7FFDE000h и лимитом FFFh), связанную с процессом (структура TEB - Thread Information Block). Данная структура используется при структурной обработке исключений SEH и содержит кучу другой полезной инфы о процессе. Но все дело в том, что размер этой структуры - всего 4 Кб, поэтому его в расчет не берем, чтоб еще больше все не запутать. Но на самом деле, это надо учесть, поэтому вирт. адр. пр-во процесса в ОС Win составляет 8Гб + 4Кб.

А как же обстоит дело с линейным адресным пространством? Здесь все еще проще: линейное адресное пространство процесса ТЕОРЕТИЧЕСКИ могло бы составлять максимум от процессорного - 4 Гб, но т.к. верхние 2 Гб ОС Win NT защищены от доступа на уровне СТРАНИЦ, то получается, что ЛИНЕЙНОЕ АДРЕСНОЕ ПРОСТРАНСТВО ПРОЦЕССА В ОС Win NT = 2 Гб. В Win 9x - чуть больше, 3 Гб.

Вообще, судить о том, принадлежит ли данный адрес к тому или иному адресному пространству процесса можно по тому, возникнет ли исключение при его формировании или не возникнет. По этому признаку можно определить является ли данный адрес одним из адресов адресного пространства процесса или не является.

Например, при создании процесса исключения НЕ ВОЗНИКНЕТ при формировании процессором любого из следующих ВИРТУАЛЬНЫХ АДРЕСОВ:

DS:смещение
CS:смещение
FS:смещение
GS:смещение
SS:смещение

(а это, как мы знаем, 8Гб + 4Кб адресов, а теоретически могло быть и 24 Гб), значит, все эти адреса ВХОДЯТ в виртуальное адресное пространство процесса.

НО ИСКЛЮЧЕНИЕ ВОЗНИКНЕТ (!) при формировании ЛЮБОГО ЛИНЕЙНОГО АДРЕСА, БОЛЬШЕГО 2 ГБ (в NT) и большего 3 Гб (в 9x). Следовательно, та часть ЛИНЕЙНЫХ адресов, при формировании которых ВОЗНИКНЕТ #GP - НЕ ВХОДЯТ В ЛИНЕЙНОГО АДРЕСНОЕ ПРОСТРАНСТВО ПРОЦЕССА, а другие - ВХОДЯТ. В этом соль и это важно ПОНЯТЬ и ОСОЗНАТЬ.

Еще заблуждения:

Во многих книгах можно прочитать что то типа: "...считать данные из страницы", или "сбросить страницу в файл подкачки". Это некорректно. На самом деле, страница - это блок линейного адресного пространства. Страница НЕ МОЖЕ СОДЕРЖАТЬ ДАННЫХ. Данные содержатся в СТРАНИЧНОМ ФРЕЙМЕ (страничный фрейм - это блок физического адресного пространства). Т.е. нужно говорить "считать данные из страничного фрейма".

Таких тонкостей - море. Только до конца разобравшийся в них может считаться специалистом.

Виртуальное адресное пространство процессора Intel (IA32) в реальном режиме.

Да да! Оказывается, и в реальном режиме существует такое понятие.

Вообщем, все очень просто.

Виртуальный адрес в РЕАЛЬНОМ РЕЖИМЕ тоже состоит из двух частей:

сегмент:смещение

Максимальный виртуальный адрес в реальном режиме равен FFFFh:FFFFh, это очевидно. А сколько их ВСЕГО, этих ВИРТУАЛЬНЫХ АДРЕСОВ?

0000:0000
0000:0001
0000:0002
...
1234:5678
...
FFFF:FFFF

ровно FFFFFFFFh штук :)
а это есть 4Гб

Т.е. вывод: виртуальное адресное пространство процессора Интел в реальном режиме составляет 4 Гб.

Теперь, вы конечно же слышали про параграфы. Значит, можете совершенно справедливо заметить, что адрес 0000h:0010h и адрес 0001h:0000h преобразуются в ОДИН И ТОТ ЖЕ ЛИНЕЙНЫЙ АДРЕС 00000010h!!! и будете СОВЕРШЕННО ПРАВЫ! В один и тот же ЛИНЕЙНЫЙ АДРЕС! Но фактически, на него указывают ДВА РАЗНЫХ виртуальных адреса.

;****************************************************************
ПРАВИЛО ПОЛУЧЕНИЯ ЛИНЕЙНОГО АДРЕСА ИЗ ВИРТУАЛЬНОГО В РЕАЛЬНОМ РЕЖИМЕ:

shl сегм.регистр, 4
add сегм.регистр, смещение

Если кто не знаком с асмом то я поясню: shl - это сдвиг "влево" на 4 бита, add - это прибавление. 
На примере все станет ясно.

Пример 1:
1234h:5678h
Сдвинуть 1234h на 4 бита влево. Получаем 12340h.
Прибавляем 5678h. Получается: 12340h+5678h=179B8h

Т.е. вирт. адрес 1234h:5678h = лин. адресу 179B8h

Пример 2:
0001h:0000h

Сдвинуть 0001h на 4 бита влево. Получаем 0010h.
Прибавляем 0000h. Получается: 0010h+0000h=0010h

Т.е. вирт. адрес 0001h:0000h = лин. адресу 0010h
;*****************************************************************

Ну прям как в защ. режиме, только там вместо сдвига берется база и т.д.

Кстати, вот еще вопросец (пусть ответит, кто хочет): приведите пример линейного адреса, который можно получить максимально возможным количеством РАЗЛИЧНЫХ виртуальных адресов.

Ну вот вышеприведенный пример, линейный адрес 00000010h можно получить ТОЛЬКО (!) из двух разных виртуальных адресов. Но ведь, допустим, линейный адрес 00000020h можно получить уже ИЗ ТРЕХ РАЗЛИЧНЫХ ВИРТУАЛЬНЫХ АДРЕСОВ, а именно:

0000h:0020h
0001h:0010h
0002h:0000h

и все эти три виртуальных адреса - это линейный адрес 00000020h !!

В РЕАЛЬНОМ РЕЖИМЕ ЛИНЕЙНЫЙ АДРЕС ВСЕГДА СОВПАДАЕТ С ФИЗИЧЕСКИМ (ВЫСТАВЛЯЕМЫМ НА АДРЕСНУЮ ШИНУ) (кстати, как и в случае сегментной адресации в защ. режиме).

Вывод: линейный адрес НЕ совпадает с физическим ТОЛЬКО при страничной адресации в защ. режиме.

Было бы очень недурно, если бы и вы, уважаемые подписчики, включились в дискуссию, привнесли свое понятие и развили бы эту тему дальше, т.к. она исключительно важна и почему то еще более исключительно затуманена в литературе...

www.wasm.ru - сайт, посвященный программированию на ассемблере под Win, много инструментов и статей. Есть своя рассылка, мощный форум и прекрасно отлаженная команда разработчиков :).

rusfaq.ru - задай любой вопрос по асму (и не только...), и тебе ответят.

2002-2013 (c) wasm.ru