Установка сегментных регистров не изменит содержимое памяти (фактически, в режиме реального времени к памяти вообще нет доступа), оно только изменит представление ЦП памяти (от логического к линейномуперевод).
Наличие двух сегментных регистров с одним и тем же значением означает, что одно и то же смещение X может использоваться с обоими для доступа к одним и тем же данным.
Это удобно, если мы не хотимчтобы указать ассемблеру, как считать смещение для разных сегментов.
Если мы напишем программу на ассемблере наивно, нам не хватит информации о сегменте для ассемблера, который будет считать нашу программу отдельным сегментом кода.Таким образом, ассемблер будет использовать один и тот же счетчик смещения для и данных и кода, но во время выполнения эти две области являются доступами с различным сегментом (а именно DS
и CS
), если вы не переопределите его для каждой загрузки / сохранения.
Если свойство выше не было истинным, смещения данных, сгенерированные ассемблером, не будут совпадать, если загрузчик загрузил программу.
Это также полезно при получении указателя на функции или обработке данных в стеке через указатель (т. Е. Без фиксированного смещения от bp
), он по сути преобразует каждый указатель в ближний указатель.
Итаксмещение переменной фактически становится адресом переменной, без дальнейшей необходимости также учитывать сегмент.Это облегчает рассуждение об адресах / смещениях, потому что теперь, если переменная имеет смещение X
, это единственное смещение, о котором мы должны беспокоиться, X
- это то же самое, что мы используем CS
, DS
или SS
.
Таким образом, X
сопоставляется 1-1 с его переменной var, если мы должны были принимать во внимание сегменты, каждая переменная может иметь до 64Ki / 16 смещений, и этот набор не отделяется отнабор смещений другой переменной (т. е. смещение X
может обозначать две разные переменные при использовании с двумя разными сегментами), и поэтому указатели должны были быть далеко.
Поскольку у нас есть только несколько эффективно свободных регистров сегментов, далекоуказатели (помимо удвоения размера указателя) оказывают большое давление на стратегию размещения регистров.
Конечно, размещение всего кода, данных и стека в одном сегменте может быть сложной задачей из-за относительно небольшого размерасегмент (64 КБ).
Код и данные обычно не устанавливаются программистом (их компоновка фиксируется после создания двоичного файла), поэтомунастроен только стек, следует соблюдать осторожность, чтобы указатель стека не устанавливался слишком близко к концу данных и кода.
Правильной обработкой стека часто можно пренебречь при расчете задней части салфеткиМаксимальная глубина цепочки вызовов, но если мы не можем связать наши цепочки вызовов или у нас так много кода / данных, что размер стека составляет сотни байтов, нам, вероятно, потребуется рефакторинг.
Правильное управление стеком в реальном режиметрудно из-за отсутствия функций, я не могу придумать способ лучше, чем проверка указателя стека на каждую запись функции.
Если у нас нет нескольких сегментов для каждого типа данных (данные / стек, код), используяотдельные сегменты увеличивают адресуемую память бесплатно, но при инициализации несколько строк (если мы не берем указатели на функции).
Наличие одного и того же сегмента для стека и данных полезно при передаче указателей на структуры в стеке,Исполняемые файлы
DOS .com
являются примером программ, в которых CS
, DS
и SS
имеют одинаковое значение.Исполняемые файлы DOS .exe
часто собираются / компилируются для небольшой модели памяти, где у нас есть только сегменты кода (CS
) и данных (DS
, SS
).
Однако они могут обрабатывать другие модели памяти,в том числе огромный, где мы можем иметь несколько сегментов для типа данных (код, стек, данные).
Программирование с несколькими сегментами подвержено ошибкам, поэтому 32-разрядные ОС перестали его использовать, а 64-разрядные ОС не могут его использовать (но ограниченным образом).
Однако сегменты также полезны,они могут создать удобный вид в памяти, особенно при доступе к регионам MMIO и ISA.
Эту стену текста трудно разобрать, если у вас недостаточно (болезненный?) Опыт работы с сегментами, я советую начать с работающей программы и намеренно навредить себе, перемещая данные в (излишне) разделенные сегменты.
Только помните, как логические адреса (сегмент: смещение) переводятся в линейные адреса (сегмент * 16 + смещение).