Что такое "пространство теней" в сборке x64?

Я нашел много тем об этом теневом пространстве, но я не мог найти ответ ни в одном из них, поэтому мой вопрос:

Сколько именно байтов мне нужно вычесть из указателя стека, перед тем как войти в процедуру?

И нужно ли выставлять параметры процедуры в стек перед вычитанием "теневого пространства"?

Я разобрал свой код, но не смог найти логику.

Ответы

Ответ 1

Предполагается использовать пространство тени (также иногда называемое Spill space или Home space), чтобы облегчить отладку x64.

Напомним, что первые 4 параметра передаются в регистрах. Если вы входите в отладчик и проверяете стек вызовов для потока, вы не сможете увидеть какие-либо параметры, переданные в функции. Значения, хранящиеся в регистрах, являются временными и не могут быть восстановлены при перемещении стека вызовов.

Здесь начинается домашнее пространство: оно может использоваться компиляторами, чтобы оставить копию значений регистра в стеке для последующей проверки в отладчике. Это обычно происходит для неоптимизированных сборок. Однако, если оптимизация включена, компиляторы обычно обрабатывают пространство "Дом" как доступное для использования с нуля. Никаких копий не осталось в стеке, а отладка сбрасывания сбоев превращается в кошмар.

Задачи отладки Оптимизированный код x64 содержит исчерпывающую информацию о проблеме.

Ответ 2

Теневое пространство - обязательное 32 байта (4x8 байт), которое вы должны зарезервировать для вызываемой процедуры. Это просто означает, что перед вызовом вы должны предоставить 32 байта в стеке. Это пространство можно оставить неинициализированным, это не имеет значения.

Обратите внимание, что в соглашении о вызове x64 аргументы после 4-го числа помещаются в стек, которые находятся поверх этого пространства тени (до 32 байт).

Вкратце, вы можете видеть это, как если бы функции в x64 имели минимум 4 аргумента, но со значением 4 в регистре.

Такие вещи, как выравнивание стека, также должны учитываться при вызове x64.