ФЭНДОМ


В большинстве вычислительных систем эффективным адресом называется адрес, по которому с точки зрения программиста происходит обращение к памяти; численно он совпадает с виртуальным адресом, причём последний термин используется значительно чаще. Однако в случае архитектуры IA-32 ситуация несколько сложнее. Здесь эффективным адресом называется смещение, то есть один из двух компонентов логического адреса. Другой компонент — селектор сегмента — в состав эффективного адреса не входит и автоматически учитывается процессором при преобразовании логического в линейный адрес и далее в физический адрес. Таким образом, технически эффективный адрес является лишь одним из компонентов адреса, по которому происходит обращение к памяти с точки зрения программы. Однако во всех популярных операционных системах для платформы IA-32, включая Windows и Linux, механизм сегментации используется в минимально необходимой степени, и программы работают в плоском адресном пространстве, манипулируя лишь смещениями, но не селекторами сегментов. В результате можно считать, что эффективный и виртуальный адреса являются эквивалентными (например, говоря о передаче адресов при системных вызовах, документация Microsoft использует термин «виртуальный адрес», однако технически передаётся именно смещение, т.е. значение эффективного адреса, а не полный логический адрес).

Эффективный адрес в общем случае является суммой базового адреса, находящегося в базовом регистре, индекса из индексного регистра и отклонения (displacement), являющегося константой, заданной в команде, например:

mov  ax, 1234h [bx+si]    ; Загрузка слова по эффективному адресу 1234h + BX + SI

В этом примере 1234h является отклонением, регистр BX содержит базовый адрес, а SI — индекс.

Любой из компонентов эффективного адреса может отсутствовать, однако хотя бы один из них должен быть указан. При 16-разрядной адресации в качестве базового регистра могут использоваться только BX и BP, а в качестве индексного — только SI и DI. Отклонение имеет длину 8 или 16 бит и рассматривается как число со знаком. Таким образом, возможны восемь комбинаций регистров, не считая прямой адресации, при которой регистры при вычислении эффективного адреса не используются, и его значение равно отклонению. Если в качестве базового задан регистр BP, то операнд по умолчанию находится в сегменте стека (совместно с эффективным адресом используется сегментный регистр SS), а если базовый регистр не задан или им является BX, то по умолчанию операнд находится в сегменте данных (используется сегментный регистр DS). В любом случае используемый сегмент может быть переопределён с помощью префикса замены сегмента.

При 32-разрядной адресации эффективный адрес также является суммой базового адреса, индекса и отклонения, однако в роли базового регистра может выступать любой регистр общего назначения, а в роли индексного — любой, кроме ESP, причём и базовым, и индексным может быть один и тот же регистр. Кроме того, значение индекса может масштабироваться (автоматически умножаться на 2, 4 или 8), что облегчает адресацию в массивах с элементами указанных размеров. Отклонение является 8- или 32-разрядной величиной со знаком. Примеры такой адресации:

mov   eax, [1234h]          ; Загрузка двойного слова из ячейки с эффективным адресом 1234h
mov   eax, 1234h [ecx]      ; Загрузка из ячейки с эффективным адресом 1234h + ECX
mov   eax, [ebx+4*edx]      ; Загрузка из ячейки с эффективным адресом EBX + 4*EDX

При 64-разрядной адресации эффективный адрес формируется в целом аналогично, однако есть и некоторые особенности:

  • используются не 32-, а 64-разрядные регистры;
  • с помощью префикса REX при формировании эффективного адреса можно в роли базового и индексного использовать новые регистры R8-R15;
  • отклонение является 8- или 32-разрядной величиной, рассматриваемой как число со знаком. 64-разрядного отклонения не предусмотрено;
  • отсутствует возможность адресации памяти только с помощью отклонения (обязательно наличие базового и/или индексного регистра). Исключением является команда MOV, у которой имеются формы, использующие прямую 64-разрядную адресацию памяти;
  • появилась возможность адресации относительно указателя инструкции RIP. В этом случае эффективный адрес равен сумме 64-разрядного адреса следующей команды и 32-разрядного смещения, рассматриваемого как число со знаком;
  • сегментные регистры FS и GS могут использоваться в качестве дополнительных базовых регистров (подробнее об этом написано в разделе Управление памятью в режиме IA-32e).