Почему я не могу изменить значение регистра сегмента?(МАСМ)

StackOverflow https://stackoverflow.com/questions/125532

  •  02-07-2019
  •  | 
  •  

Вопрос

Я решил сам выучить язык ассемблера.

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

В каждой статье, которую я нашел, говорится, что я действительно могу изменить значение по крайней мере 4 сегментных регистров, так что же это дает?

На самом деле меня интересует только то, почему на данный момент у меня нет никакой реальной цели менять эти адреса.

Это было полезно?

Решение

Вы сказали, что вас интересует, почему, так что:

В реальном режиме сегмент представляет собой "окно" в физическую память размером 64 КБ, и эти окна расположены на расстоянии 16 байт друг от друга.В защищенном режиме сегмент представляет собой окно в физическую или виртуальную память, размер и расположение которого определяются операционной системой, и он обладает многими другими свойствами, включая уровень привилегий, которым должен обладать процесс для доступа к нему.

С этого момента все, что я говорю, относится к защищенному режиму.

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

Значение, которое вы загружаете в сегментный регистр, известно как селектор сегментов.Это индекс в GDT или LDT, содержащий немного дополнительной информации о безопасности.Естественно, если программа пытается загрузить дескриптор, который находится за пределами GDT, возникает исключение.Также, если у процесса недостаточно привилегий для доступа к сегменту или что-то еще недопустимо, возникает исключение.

Когда возникает исключение, ядро обрабатывает его.Такого рода исключения, вероятно, были бы классифицированы как ошибка сегментации.Таким образом, операционная система убивает вашу программу.

Есть еще одно последнее предостережение:в наборе команд x86 вы не можете загружать непосредственные значения в сегментные регистры.Вы должны использовать промежуточный регистр или операнд памяти или ПЕРЕЙТИ в сегментный регистр.

MOV DS, 160  ;INVALID - won't assemble

MOV AX, 160  ;VALID - assembles, but will probably result in an
MOV DS, AX   ;exception, and thus the death of your program

Я думаю, следует отметить, что архитектура допускает множество сегментов.Но AFAIK, когда дело доходит до основных операционных систем x86, сегментные регистры служат лишь нескольким целям:

  • Механизмы безопасности, такие как защита процессов пользовательского пространства от нанесения вреда друг другу или операционной системе
  • Работа с несколькими /многоядерными процессорами
  • Поток-локальное хранилище:в качестве оптимизации некоторые операционные системы (включая Linux и Windows) используют сегментные регистры для локального хранилища потоков (TLS).Поскольку потоки используют одно и то же адресное пространство, потоку трудно "узнать", где находится его область TLS, не используя системный вызов или не тратя впустую регистр...но поскольку сегментные регистры практически бесполезны, нет ничего плохого в том, чтобы "тратить" их впустую ради быстрого TLS.Обратите внимание, что при настройке этого параметра операционная система может пропустить сегментные регистры и выполнять запись непосредственно в регистры кэша дескрипторов, которые являются "скрытыми" регистрами, используемыми для кэширования запросов GDT / LDT, запускаемых ссылками на сегментные регистры, и в этом случае, если вы попытаетесь выполнить чтение из сегментных регистров, вы этого не увидите.

Помимо сегмента на поток для TLS, на самом деле используется только несколько сегментов (умноженных на количество процессоров), и только операционной системой.Прикладные программы могут полностью игнорируйте сегментные регистры.

Это связано с дизайном операционной системы, а не с какими-либо техническими ограничениями.Могут существовать встроенные операционные системы, которым требуются программы пользовательского пространства для работы с сегментными регистрами, хотя я не знаю ни о каких из них.

Другие советы

Вы пишете исполняемые файлы для Windows?

В защищенном режиме (Win32) сегментные регистры больше не используются.

Ссылка:

Модель памяти также кардинально отличается от старых времен 16-разрядного мира.В Win32 нам больше не нужно беспокоиться о модели памяти или сегменте!Существует только одна модель памяти:Модель с плоской памятью.Больше нет 64-тысячных сегментов. Объем оперативной памяти составляет 4 ГБ.Это также означает, что вам не нужно играть с сегментными регистрами.Вы можете использовать любой сегментный регистр для обращения к любой точке в области памяти.Это БОЛЬШАЯ помощь программистам.Это то, что делает сборку Win32 программирование таким же простым, как C.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top