Эти две строки являются частью пролога функции, используемого для установки нового стека (или активации) фрейма. Первый, pushq %rbp
помещает базовый указатель в стек. Второй, movq %rsp, %rbp
, перемещает базовый указатель на указатель стека. Должна быть по крайней мере другая строка, где мы вычитаем некоторое значение из точки стека, это приводит к смещению точки стека вниз.
Напомним, что на платформах Intel стек растет вниз, а базовый указатель (rbp) обозначает дно стека, а указатель стека (rsp) указывает на вершину стека.
Теперь на 64-битных машинах больше регистров, поэтому зависимость от использования стека для временного хранения снижается, поэтому эти инструкции могут отсутствовать в 64-битном коде.
Эти инструкции являются частью соглашения о вызовах, или то, как функции называются в вашей книге, должно содержать описание того, что требуется для вызова функции. Однако обратите внимание, что между 32-разрядной и 64-разрядной версиями Intel существуют различия в способах вызова функций.
Адрес, к которому мы возвращаемся (значение в rip - указатель инструкции) помещается вызывающим в стек и не будет виден в коде вызываемого. Обычно вы вызываете функцию с помощью call <fnct_name>
, однако это можно заменить на последовательность:
pushq %rip
jmp <fnct_address>
(возможно, неверный синтаксис - я не очень часто использую синтаксис AT & T).
Теперь, то, что мы сделали со стеком, должно быть невыполнено в эпилоге функции, поэтому мы в основном добавляем некоторое значение к точке стека (т. Е. Перемещаем указатель стека туда, где мы начали), выскакиваем из стек, поэтому базовый указатель возвращается к нему, который был в вызывающей программе, а затем мы запускаем eip, чтобы программа знала, где возобновить выполнение.