Каково назначение сегментных регистров в защищенном режиме x86?

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

mov eax, dword ptr ds:[20037DA0] 

3 ответов


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


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

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, если длина

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

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

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

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

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


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

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

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

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

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

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

подкачки требует 36bits я думаю (Не цитируйте меня ) вот где 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-битные приложения могут эффективно есть столько ОЗУ, сколько они хотят, без ограничений. В пределах разумного. конвертер ofc...:)

надеюсь, что это помогает.