Что такое "пространство теней" в сборке x64?
Я нашел много тем об этом теневом пространстве, но я не мог найти ответ ни в одном из них, поэтому мой вопрос:
Сколько именно байтов мне нужно вычесть из указателя стека, перед тем как войти в процедуру?
И нужно ли выставлять параметры процедуры в стек перед вычитанием "теневого пространства"?
Я разобрал свой код, но не смог найти логику.
Ответы
Ответ 1
Предполагается использовать пространство тени (также иногда называемое Spill space или Home space), чтобы облегчить отладку x64.
Напомним, что первые 4 параметра передаются в регистрах. Если вы входите в отладчик и проверяете стек вызовов для потока, вы не сможете увидеть какие-либо параметры, переданные в функции. Значения, хранящиеся в регистрах, являются временными и не могут быть восстановлены при перемещении стека вызовов.
Здесь начинается домашнее пространство: оно может использоваться компиляторами, чтобы оставить копию значений регистра в стеке для последующей проверки в отладчике. Это обычно происходит для неоптимизированных сборок. Однако, если оптимизация включена, компиляторы обычно обрабатывают пространство "Дом" как доступное для использования с нуля. Никаких копий не осталось в стеке, а отладка сбрасывания сбоев превращается в кошмар.
Задачи отладки Оптимизированный код x64 содержит исчерпывающую информацию о проблеме.
Ответ 2
Теневое пространство - обязательное 32 байта (4x8 байт), которое вы должны зарезервировать для вызываемой процедуры. Это просто означает, что перед вызовом вы должны предоставить 32 байта в стеке. Это пространство можно оставить неинициализированным, это не имеет значения.
Обратите внимание, что в соглашении о вызове x64 аргументы после 4-го числа помещаются в стек, которые находятся поверх этого пространства тени (до 32 байт).
Вкратце, вы можете видеть это, как если бы функции в x64 имели минимум 4 аргумента, но со значением 4 в регистре.
Такие вещи, как выравнивание стека, также должны учитываться при вызове x64.