Какие сегменты используют C -программное использование C?
-
02-10-2019 - |
Вопрос
Я читаю на Osdev Wiki, этот защищенный режим архитектуры X86 позволяет создавать отдельные сегменты для кода и данных, в то время как вы не можете записать в раздел кода. Что Windows (да, это платформа) загружает новый код в сегмент кода, а данные создаются в сегменте данных. Но, если это так, как программа узнает, что должна переключаться на сегменты на сегмент данных? Потому что, если я понимаю это правильно, все инструкции по адресу указывают на сегмент, из которого вы запускаете код, если вы не переключите дескриптор. Но я также прочитал, что сдержанная модель плоской памяти позволяет запускать код и данные в одном сегменте. Но я прочитал это только в связи с ассемблером. Итак, пожалуйста, в чем дело с C, скомпилированным кодом в Windows? Спасибо.
Решение
Есть два значения для сегмент В объяснении:
- Сегмент адреса адреса 8086
- сегмент раздела программы объекта модуля
Первый связан с тем, что загружается в реестр сегмента 80386+; Он содержит адрес начала физической памяти, длину распределения памяти, разрешенный доступ к чтению/записи/выполнению, и рост он с низкого до высокого или наоборот (плюс еще несколько неясных флагов, таких как «Копировать на ссылке»).
Второе значение является частью языка модуля объекта. По сути, есть сегмент, названный code
, сегмент по имени data
(который содержит инициализированные данные) и сегмент для ненициализированных данных, названных bss
(Назван в честь псевдо инструкций 1960 -х годов, значения Блок, начиная с символа). Когда линкер объединяет модули объектов, он объединяет все сегменты кода, все сегменты данных вместе в другом месте, а также BSS вместе. Когда загрузчик отображает адреса памяти, он рассматривает общее пространство кода и выделяет распределение памяти ЦП, по крайней мере, этого размера и отображает сегмент коду (в ситуации виртуальной памяти) или считывает код в выделенную память, для которого Он должен временно установить память как данные, доступную для данных. Защита от записи осуществляется с помощью механизма пейджинга процессора, а также регистра сегментов. Это для защиты попыток написания кода, например, ошибочного адреса данных. Погрузчик также выполняет аналогичную настройку для двух групп сегмента данных. (Кроме того, существует настройка сегмента стека и распределяет его, а также отображение общих изображений.)
Что касается инструкций по выполнению x86, каждый операнд имеет соответствующий регистр сегмента. Иногда они явные, а иногда они неявно. Код неявно доступен через CS
, сложить через SS
что подразумевается, когда ESP
или EBP
регистр задействован, и DS
подразумевается для большинства других операндов. ES
, FS
, и GS
Должен быть указан как переопределение во всех других случаях, за исключением некоторых инструкций по строке, таких как movs
и cmps
. Отказ В плоской модели все регистры сегмента отображают в одном и том же адресном пространстве, хотя CS не позволяет писать.
Таким образом, чтобы ответить на ваш последний вопрос, в процессоре есть четыре (или более) регистров сегмента, установленных сразу для доступа к плоскому пространству виртуальной памяти процесса. Каждый доступ операндов проверяется на то, чтобы быть подходящим для инструкции (например, не увеличивая CS
адрес), а также проверяется подразделением защиты пейджинга для получения разрешения.
Другие советы
Информация, которую вы прочитали, устарела. Версии Windows с 1993 года используют плоское 32-разрядное пространство виртуальной памяти. Значения регистров сегмента CS и DS больше не имеют значения и не могут быть изменены. По -прежнему существует понятие кода против данных, которые теперь реализованы атрибутами страницы памяти. Просмотрите разрешенные значения, передаваемые в аргументе Flnewprotect для Функция API VirtualProtectex ().
Вы очень редко используете этот API самостоятельно, атрибуты устанавливаются исполняемым загрузчиком изображения и менеджером Heap.