Адресация данных с использованием относительных указателей (ассемблер x86-32)

#assembly #x86 #32-bit #addressing #relative-addressing

#сборка #x86 #32-разрядный #адресация #относительная адресация

Вопрос:

Я пишу на 32-разрядном ассемблере x86, и я не совсем уверен, как обращаться к данным, которые всегда находятся в одном и том же отношении к коду. Должен ли я использовать EIP для вычисления абсолютного адреса, или есть способ получше?

Ответ №1:

Вы можете использовать позиционно-независимый код:

    call @f
   dd 42 ; data
@@:
   pop eax ; eax contains offset of data
   mov eax, cs:[eax]
  

или используйте то же самое с дельта-смещениями

    call base
base:
   pop ebp
   sub ebp, base ; to use small offsets, -128 to  127, and smaller instruction size
   ;....
   mov eax, cs:[ebp dataN-base] ; dataN-base is called "delta-offset"
   ;....
data1:
   dd 100
   ;....
dataN:
   dd 200
  

Ответ №2:

Зависит от операционной системы. Обычно сегментные регистры DS (сегмент данных) и CS (сегмент кода) имеют разные значения. Таким образом, вы можете использовать префикс cs, такой как:

 mov    edx, cs:[eax]
  

В этом случае префиксом по умолчанию является регистр сегмента ds.

Комментарии:

1. Я не использую ОС. Я нахожусь в защищенном режиме, поэтому используется дескриптор сегмента, а не фактический номер сегмента. И в моем случае есть только два дескриптора сегмента для данных и кода (не считая нулевого).