Я читал длинный каталог очень хороших статей по Windows x64 ABI. Очень второстепенным аспектом этих статей является описание указателя фрейма. Общая суть состоит в том, что, поскольку правила стека вызовов Windows x64 настолько жесткие, выделенный указатель кадра обычно не требуется, хотя и является необязательным.
Единственное исключение, которое я постоянно отмечал, - это когда используется alloca()
для динамического выделения памяти в стеке. Функции, выполняющие это, очевидно, требуют указателя фрейма. Например, чтобы процитировать документацию Microsoft по «Распределение стека» (курсив и жирным шрифтом добавлены мной):
Если пространство в функции выделяется динамически (alloca), то энергонезависимый регистр должен использоваться в качестве указателя кадра, чтобы отметить основание фиксированной части стек, и этот регистр должен быть сохранен и инициализирован в прологе. Обратите внимание, что при использовании alloca вызовы одного и того же вызываемого абонента от одного и того же вызывающего абонента могут иметь разные домашние адреса для своих параметров регистра.
К этому alloca()
документация Microsoft к этому загадочно добавляет:
_alloca должен быть выровнен по 16 байт и дополнительно необходим для использования указателя кадра.
Прежде всего, зачем его использовать? Я предполагаю, что стек вызовов раскручивается при исключении, но я еще не нашел удовлетворительного объяснения.
Следующий вопрос: куда он должен указывать? В первой из двух приведенных выше цитат говорится, что он «должен» использоваться для обозначения основания «фиксированной части стека». Что такое «фиксированная часть стека»? У меня сложилось впечатление, что этот термин обозначает в данном кадре диапазон адресов, который включает (от более высоких адресов к более низким):
- адрес возврата вызывающего абонента (если вы считаете его частью текущего фрейма функции);
- адреса, по которым пролог функции сохранял энергонезависимые регистры; а также
- адреса, где хранятся локальные переменные.
Опять же, я не нашел удовлетворительного определения этой «фиксированной части». Страница «Распределение стека», на которую я ссылалась выше, содержит приведенную ниже диаграмму со словами "если используется, указатель стека будет обычно указывать сюда":
Это отличное сообщение в блоге столь же расплывчато. , включая диаграмму, на которой указатель кадра «указывает где-то здесь», где «здесь» - адреса для сохраненных энергонезависимых регистров и локальных переменных.
И последний кусочек загадочности из статьи Microsoft MSDN, озаглавленной «Построение области стека динамических параметров», который содержит только это:
Если используется указатель кадра, существует возможность динамического создания области стека параметров. В настоящее время это не делается в компиляторе x64.
Что значит «в целом»? Где «где-то здесь»? Какой вариант существует? Есть ли правило? Какая разница?
Или, tl; dr: О чем спрашивает название. Любой ответ, содержащий аннотированную сборку, с благодарностью принимается.