Почему я не могу изменить значение регистра сегмента? (MASM) - PullRequest
7 голосов
/ 24 сентября 2008

Я решил научить себя ассемблеру.

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

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

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

Ответы [ 2 ]

8 голосов
/ 20 ноября 2008

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

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

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

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

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

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

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

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, на самом деле используется только несколько сегментов (умноженное на число процессоров) и только ОС. Прикладные программы могут полностью игнорировать регистры сегментов.

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

2 голосов
/ 24 сентября 2008

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

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

Ссылка

Модель памяти также резко отличается от старых дней 16-битный мир. Под Win32 нам не нужно беспокоиться о модели памяти или сегмент больше! Здесь только один модель памяти: плоская модель памяти. Там нет больше 64К сегментов. память представляет собой большое непрерывное пространство 4ГБ. Это также означает, что у вас нет играть с сегментными регистрами. Вы можно использовать любой сегментный регистр для адрес любой точки в пространстве памяти. Это большая помощь для программистов. Это то, что делает сборку Win32 программирование так просто, как C.

...