Понимание местоположения адреса, обозначенного Qword ptr?

Я столкнулся со следующей инструкцией по сборке and rax, qword ptr [0xff5ff098]

То, что я хочу знать, это то, что адрес памяти, который будет доступен в следующей инструкции. Будет ли адрес памяти 0xff5ff098 будет расширен ноль или будет расширен самый значимый бит?

В Intel Pin инструмент API IARG_MEMORYREAD_EA дает его как расширенный на 1, т.е. он дает следующий адрес 0xffffffffff5ff098, Этот адрес является возможным адресом?

Я работаю на 64-битной машине.

1 ответ

Решение

Как это закодировано? RIP-относительный или абсолютный?

Если он абсолютный, он использует режим адресации sign-extended-disp32 (потому что 32-битные смещения в режимах адресации всегда расширяются знаком, даже если регистры не задействованы).

Если он относительно RIP, то ваш дизассемблер должен показывать вам правильный конечный адрес, рассчитанный по RIP + rel32.

Ваш дизассемблер или PIN-код показывают его неправильно, поскольку, если он действительно расширен до 64-битного знака, ваш дизассемблер должен показывать вам это.


И да, в x86-64 возможна как относительная, так и абсолютная адресация RIP.

У x86-32 было два избыточных способа кодирования [disp32] режимы адресации без регистров. x86-64 меняет более короткий как RIP-относительный и оставляет более длинный как [sign-extended-disp32] абсолютная адресация.

Я буду использовать синтаксис NASM для примера. Ты можешь использовать default rel использовать RIP-относительный по умолчанию, и вы можете переопределить в каждом конкретном случае, как это:

  MOV     RAX, [abs FS:_start]    ; _start just as something that assembles
  MOV     RAX, [rel FS:_start]    ; RIP-rel for thread-local is usually not useful!

 64 48 8b 04 25 b5 00 40 00   mov rax,QWORD PTR fs:0x4000b5
 64 48 8b 05 e7 fe ff ff      mov rax,QWORD PTR fs:[rip+0xfffffffffffffee7]  # 4000b5 <_start>

Этот адрес является возможным адресом?

Да, адреса в верхней половине канонического диапазона используются. например less /proc/self/maps показывает, что Linux отображает vsyscall страница, которую он экспортирует в большое адресное пространство:

ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]

Канонический адрес означает, что биты [63:48] являются копиями бита 47. т. е. адрес - это то, что вы получили бы от расширения знака младших 48 бит. Неканонические адреса всегда будут давать сбой на текущем оборудовании, поэтому, если вы хотите реализовать что-то вроде помеченных указателей с этими избыточными битами, вам все равно придется перед расширением знака повторить расширение знака.


Обратите внимание, что qword ptr говорит вам размер операнда, а не что-либо о том, как кодируется режим адресации.

Другие вопросы по тегам