Что означает звездочка * перед адресом в сборке x86-64 AT & T? - PullRequest
30 голосов
/ 10 февраля 2012

Что означает следующая строка:

...
401147: ff 24 c5 80 26 40 00    jmpq   *0x402680(,%rax,8)
...

Что означает звездочка перед адресом памяти? Кроме того, что это означает, когда метод доступа к памяти отсутствует, это первое значение регистра?

Обычно это что-то вроде ("% register",% rax, 8), но в этом случае у него нет первого регистра.

Любые советы?

Ответы [ 7 ]

18 голосов
/ 10 февраля 2012

На самом деле это вычисляемая таблица jmp , где 0x402680 - адрес таблицы, а rax - индекс 8-байтового (qword) указателя.

16 голосов
/ 10 февраля 2012

Это синтаксис сборки AT & T:

  • источник до пункта назначения
  • мнемонические суффиксы указывают размер операндов (q для четырехугольника и т. Д.)
  • имеют префикс %, а непосредственные значения $
  • действующие адреса имеют вид DISP(BASE, INDEX, SCALE) (DISP + BASE + INDEX * SCALE)
  • абсолютные операнды перехода / вызова, обозначенные * (в отличие от IP-адреса)

Итак, у вас есть jmpq для перехода к абсолютному адресу, который хранится в %rax * 8 + 0x402680 и является длинным четырехзначным словом.

12 голосов
/ 10 февраля 2012

Введение в синтаксис Intel всегда делает вещи понятнее:

FF24C5 80264000  JMP QWORD PTR [RAX*8+402680]
5 голосов
/ 29 апреля 2014

jmpq - это просто безусловный переход к заданному адресу. 'Q' означает, что мы имеем дело с четырьмя словами (длиной 64 бита).

*0x402680(,%rax,8): это способ записи адреса в сборке x-86. Вы правы, говоря, что обычно перед первой запятой стоит регистр, но вы все равно следуете тем же правилам, если регистр не указан.

Формат работает следующим образом: D(reg1, reg2, scalingFactor) где D обозначает смещение. Смещение в основном просто целое число. reg1 - первый или базовый регистр. reg2 - это второй регистр, а scalingFactor - это один из 2, 4, 8 (возможно, даже 1, но я не уверен в этом). Теперь вы можете получить свой адрес, просто добавив значения следующим образом: Смещение + (значение в reg1) + scalingFactor* (значение в reg2).

Я не совсем уверен, для чего предназначена звездочка перед адресом, но я предполагаю, что это означает, что значение смещения сохраняется по этому адресу.

Надеюсь, это поможет.

5 голосов
/ 10 февраля 2012

Это прыжок к адресу, содержащемуся в памяти. Адрес хранится в памяти по адресу rax*8+0x402680, где rax - текущее значение rax (при выполнении этой инструкции).

4 голосов

Минимальный пример

Чтобы прояснить ситуацию:

.data
    # Store he address of the label in the data section.
    symbol: .int label   
.text   
    # Jumps to label.
    jmp *symbol
    label:

GitHub upstream .

Без *, он перейдет по адресу symbol в разделе .data и segfault.

Мне кажется, что этот синтаксис немного противоречив, потому что для большинства инструкций:

mov symbol, %eax
mov label, %eax

уже перемещает данные по адресу symbol, а $symbol используется для адреса.Синтаксис Intel в этом отношении более последовательный, поскольку он всегда использует [] для разыменования.

*, конечно, является мнемоникой для оператора разыменования C *ptr.

4 голосов
/ 14 марта 2013

Как писал Некролис, синтаксис Intel делает его немного более очевидным, но RTN действительно понятнее.Строка

jmpq   *0x402680(,%rax,8)

будет описана в RTN как:

RIP <- M[0x402680 + (8 * RAX)]

, где M - системная память.

Таким образом, мы можем написать общееформа jmpq *c(r1, r2, k), где c - непосредственная константа, r1 и r2 - регистры общего назначения, а k - 1 (по умолчанию), 2, 4 или 8:

RIP <- M[c + r1 + (k * r2)]
...