2010-05-02 4 views
3

Я читал в вики OSDev, что защищенный режим архитектуры x86 позволяет создавать отдельные сегменты для кода и данных, в то время как вы не можете писать в раздел кода. То, что Windows (да, это платформа) загружает новый код в сегмент кода, а данные создаются в сегменте данных. Но, если это так, как известно программе, она должна переключать сегменты в сегмент данных? Если вы понимаете это правильно, обратите внимание, что все инструкции для адреса указывают на сегмент, из которого вы запускаете код, если вы не переключите дескриптор. Но я также читал, что такая компактная модель с плоской памятью позволяет запускать код и данные в одном сегменте. Но я читал это только в связи с ассемблером. Итак, пожалуйста, что происходит с C скомпилированным кодом в Windows? Благодарю.В каких сегментах используется скомпилированная программа C?

ответ

2

Есть два значения для сегмента в объяснении:

  • адрес сегмент 8086 памяти
  • программа объектного модуля раздела сегмент

Первый связан с тем, что загружается в регистр сегмента 80386+; он содержит начальный адрес физической памяти, длину выделения памяти, разрешен доступ для чтения/записи/выполнения и растет ли он от низкого до высокого или наоборот (плюс несколько более неясных флагов, например «копия по ссылке»).

Второе значение - часть языка объектного модуля. В основном существует сегмент с именем code, сегмент с именем data (который содержит инициализированные данные) и сегмент для неинициализированных данных с именем bss (названный в честь псевдо-инструкций сборщиков 1960-х годов, означающий Блок, начинающийся с символа). Когда компоновщик объединяет объектные модули, он объединяет все сегменты кода вместе, все сегменты данных вместе в другом месте и вместе с bss. Когда загрузчик сопоставляет адреса памяти, он просматривает общее пространство кода и выделяет распределение памяти CPU по меньшей мере такого размера и сопоставляет сегмент с кодом (в ситуации виртуальной памяти) или считывает код в выделенную память, для чего он должен временно установить память как доступную для записи данных. Защита записи выполняется через механизм поискового вызова процессора, а также регистр сегментов. Это делается для защиты попыток записи кода, например, с помощью ошибочного адреса данных. Загрузчик также выполняет аналогичную настройку для двух групп сегментов данных. (Помимо этого, создается сегмент стека, его распределение и сопоставление общих изображений.)

Что касается команд выполнения x86, каждый операнд имеет связанный регистр сегментов. Иногда они явны, а иногда они неявные. Код неявно доступен через CS, стек через SS, который подразумевается при регистрации регистра ESP или EBP, а для большинства других операндов подразумевается DS. ES, FS и GS должны быть указаны как переопределение во всех других случаях, за исключением некоторых строковых инструкций, таких как movs и cmps. В плоской модели все регистры сегментов отображаются в одно и то же адресное пространство, хотя CS не позволяет писать.

Итак, чтобы ответить на ваш последний вопрос, у CPU есть четыре (или более) сегментных регистра, настроенных сразу для доступа к пространству виртуальной памяти процесса. Каждый доступ к операнду проверяется на соответствие инструкции (например, не увеличивая адрес CS), а также проверяется блоком защиты пейджинга для разрешения.

3

Информация, которую вы читаете, устарела. В версиях Windows с 1993 года используется 32-разрядная виртуальная память. Значения регистров сегмента CS и DS больше не имеют значения и не могут быть изменены.По-прежнему существует понятие кода и данных, теперь реализуемых атрибутами страницы памяти. Просмотрите допустимые значения, переданные в аргументе flNewProtect для VirtualProtectEx() API function.

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

+2

Значения 'CS' и' DS' * do * все еще имеют значение - им необходимо ссылаться на допустимые дескрипторы в GDT или LDT. Кроме того, 'DS' * может * быть изменен в пользовательском режиме (но большинство программ этого не делают, поскольку это редко полезно). – caf

+0

Спасибо, но я думал, что когда в защищенном режиме у вас все еще есть сегментация, теперь гайка вместо использования сегментных регистров вы используете таблицы дескрипторов. Но внутри каждой таблицы дескрипторов есть место для определения своего кода или данных. Но плоский режим предлагает код и данные в одном и том же сегменте, по сегменту I - одна запись в таблице дескриптора. –

Смежные вопросы