Какова цель регистров сегментов в режиме защиты x86?

Мне нужно изменить некоторую dll, но я не знаю, что в excelly делает сегментные регистры (DS, SS,...) в защищенном режиме. В школе я узнал о реальном 16-битном режиме, где сегментные регистры умножаются на 16 плюс смещение в нормальном регистре, дает эффективный адрес в физической памяти. В защищенном режиме есть некоторая плоская модель памяти и виртуальная память, где каждый процесс имеет "4 ГБ памяти", поэтому, если регистры имеют 32-битный, я могу адресовать каждый байт виртуальной памяти только регистром "смещения". Итак, какие юности имеют сегментные регистры в защищенном режиме, например

mov eax, dword ptr ds:[20037DA0] 

Ответ 1

В принципе, цель та же, что и в реальном режиме, кроме того, как они работают, немного отличается. DS в вашем примере выбирает один дескриптор памяти в вашем GDT (google этот термин, если вы действительно хотите это понять, "Глобальная таблица дескрипторов" ), который содержит информацию, такую ​​как базовый адрес, конечный адрес, степень детализации и т.д. Ваше смещение затем добавляется к базовому адресу, конец. Если вы находитесь на окнах (я ставлю на linux то же самое), вам не нужно беспокоиться об этих сегментарных регистрах, как вы сказали, его плоской модели, то есть должен быть только один дескриптор для всей памяти, поэтому, если вы не измените эти регистры должны работать так, как будто они даже не существуют.

Ответ 2

Некоторые исторические предпосылки

8086 всегда использовал фиксированное окно 64KiB для каждого сегмента, начальный адрес которого был рассчитан (сегментный регистр * 16). Поскольку в 80286 есть некоторые специальные таблицы в памяти (GDT и LDT). Эти таблицы содержат начальный адрес, длину и права доступа сегмента. Регистры сегментов (CS, DS, ES, SS - и начиная с 80386: FS, GS) содержат индексы в этих таблицах.

Таким образом, теоретически операционная система может устанавливать смещение и длину сегмента так, как он хочет это сделать: на 8086 DS = 0x0123 означает: сегмент составляет 64KiB, начиная с адреса 0x01230. В 32-битном режиме DS = 0x0123 может означать: начало сегмента по адресу 0xABCD, длина - 0xEF байтов - это зависит от содержимого таблиц GDT и LDT, созданных операционной системой. Попытка доступа к сегменту вне этого диапазона (DS: 0x1000, если длина равна < 0x1000) приведет к исключению (прерыванию).

Текущая ситуация

Однако большинство современных 32-разрядных операционных систем больше не используют регистры сегментов. Их значения устанавливаются в зависимости от режима (ядро или пользователя) из-за проблем с правами доступа. Исходный адрес обычно равен 0, а длина - 4GiB.

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

Существует одно исключение: некоторые операционные системы (например, Windows и Linux) используют сегменты FS и/или GS, чтобы действительно указать на другую область памяти.

По этой причине в 64-битном режиме процессоры x86 используют регистр CS только для прав доступа, а FS и GS могут использоваться для добавления смещения на каждый адрес. Насколько я знаю, DS, ES и SS не используются, в то время как содержание регистров FS и GS не имеет значения, но существуют специальные регистры, которые явно дают смещение, которое должно быть добавлено к операции, которая использует FS или GS.

Ответ 3

Я дам вам простой ответ, но для получения дополнительной информации я рекомендую ссылку ниже для документов архитектуры AMD, очень простое чтение. PS: Я не рассматривал Xeon или PAE здесь.

Архитектура IA-32 (x86) имеет 32-битную физическую адресную шину для ОЗУ.

32-битная шина дополнительно разделена на 2x 16 бит сегментов, каждый из которых способен получить доступ к 2 ГБ ОЗУ в сумме 4 ГБ.
Это называется переключением банка памяти.

Чтобы обеспечить защиту Intel вместе с MS решили использовать один сегмент для kernelmode, а другой для usermode - вот почему Windows исторически имела адресное пространство usermode 2 ГБ. Это аппаратное ограничение x86, а не ограничение Windows.

Сегмент регистрирует разделенные пространства ядра и адреса пользовательского пространства. То, как была реализована защита памяти.

Кроме того, у IA-32 вообще были 32-битные внутренние регистры, поэтому он не мог страницы. Это реальный режим (без перевода адреса).

Пейджинг требует 36 бит, я думаю (не цитирую), что там, где вошел IA32e. Дополнительные биты на IA-32e разрешили пейджинг с жесткого диска, это единственный способ, которым он мог работать на x64 Windows, поскольку для x64 требуется NX и он находится в бит 63.

Пожалуйста, прочитайте документы архитектуры AMD, лично я считаю их более информативными, чем версии Intel.

http://developer.amd.com/wordpress/media/2012/10/24593_APM_v21.pdf

PS с плоской памятью AMD64 был введен, устраняя сегменты.

Однако для 32-битных процессов по-прежнему нужны сегментные регистры. На AMD64, когда 32-битный процесс попадает на вершину стека, указатель вызывается на базовый адрес в новом регистре сегментов. Таким образом, 32-разрядные приложения могут эффективно потреблять столько оперативной памяти, сколько они хотят, без ограничений. Ну, в пределах разумного...:)

Надеюсь, что это поможет.