Ассемблер

Инструкция на ассемблере: как понять -12(%rbp)

Запись -12(%rbp) в ассемблере означает обращение к памяти по адресу rbp - 12. Это не само число -12, а смещение от базового регистра rbp. Такая форма часто встречается в AT&T-синтаксисе на Linux, особенно если смотреть код, который сгенерировал GCC

Пример:

movl -12(%rbp), %eax

Читается так: взять 4 байта из памяти по адресу rbp - 12 и положить их в eax

Почему именно rbp

rbp часто используется как base pointer — опорная точка текущего стекового кадра функции. Когда функция начинается, компилятор может сделать примерно такую подготовку:

pushq %rbp
movq %rsp, %rbp
subq $16, %rsp

Смысл:

  • старое значение rbp сохраняется в стек;
  • rbp становится опорой текущей функции;
  • rsp отодвигается вниз, чтобы освободить место под локальные переменные.

После этого локальные переменные удобно находить по отрицательным смещениям от rbp: -4(%rbp), -8(%rbp), -12(%rbp)

Что означает -12

В записи:

-12(%rbp)

число -12 — это displacement, то есть смещение. Итоговый адрес считается так:

адрес = значение rbp - 12

Если rbp = 0x7fffffffe000, то -12(%rbp) указывает на:

0x7fffffffdff4

По этому адресу лежит какое-то значение: байт, 4 байта, 8 байт. Размер зависит от инструкции

Откуда понять размер

Размер виден по имени инструкции в AT&T-синтаксисе:

movb -12(%rbp), %al
movl -12(%rbp), %eax
movq -16(%rbp), %rax

Суффиксы:

  • b — 1 байт;
  • w — 2 байта;
  • l — 4 байта;
  • q — 8 байт.

movl -12(%rbp), %eax читает 4 байта. movq -16(%rbp), %rax читает 8 байт

Как это выглядит в Intel-синтаксисе

AT&T:

movl -12(%rbp), %eax

Intel:

mov eax, dword [rbp-12]

Смысл один и тот же: прочитать 4 байта из памяти по адресу rbp - 12

Если вы учитесь по NASM, Intel-синтаксис обычно выглядит понятнее. Если смотрите дизассемблирование GCC или GDB, чаще увидите AT&T-синтаксис

Пример из C

Код:

int main(void) {
    int x = 10;
    return x;
}

Компилятор может создать похожую логику:

movl $10, -4(%rbp)
movl -4(%rbp), %eax

Первая строка кладет число 10 в локальную переменную на стеке. Вторая строка читает эту переменную в eax, чтобы вернуть результат

Почему бывает -12, а не -4

Компилятор размещает локальные переменные с учетом размеров, выравнивания и временных значений. Поэтому одна переменная может лежать по -4(%rbp), другая по -8(%rbp), третья по -12(%rbp). Число не обязано совпадать с номером переменной

Частые ошибки

Думать, что -12 — это значение переменной

Нет. Это смещение адреса. Значение хранится в памяти по адресу rbp - 12

Путать rbp и rsp

rsp меняется при push/pop и выделении места. rbp часто остается стабильной опорой функции

Не видеть размер операции

movl читает 4 байта, movq читает 8 байт. Смещение само по себе не говорит размер

Смешивать синтаксисы

Что почитать дальше по ассемблеру

Если нужен общий маршрут по теме, откройте рубрику ассемблеру. Для соседних задач пригодятся эти разборы:

Подписаться
Уведомить о
guest
0 комментариев
Старые
Новые Популярные

Настройки cookie

0
Оставьте комментарий! Напишите, что думаете по поводу статьи.x