#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. Я не использую ОС. Я нахожусь в защищенном режиме, поэтому используется дескриптор сегмента, а не фактический номер сегмента. И в моем случае есть только два дескриптора сегмента для данных и кода (не считая нулевого).