Выделение памяти в стеке
Обновлен: Ноябрь 2007
Выделение памяти в стеке для локальных переменных, сохраненных регистров, а также параметров стека и регистра осуществляется в прологе функции.
Область параметров всегда располагается в нижней части стека (даже если используется функция alloca) и всегда примыкает к адресу, возвращаемому при вызове функции. В области параметров содержится как минимум четыре записи и всегда выделяется объем памяти, достаточный для хранения всех параметров любой вызываемой функции. Обратите внимание, что для параметров регистра память выделяется всегда, даже если они никогда не размещаются в стеке. Также гарантированно выделяется память для всех параметров вызываемого объекта. Чтобы обеспечить выделение непрерывной области памяти при вызове функции, принимающей адрес списка аргументов (va_list) или отдельного аргумента, необходимо предоставить внутренние адреса аргументов регистра. В этой области также хранятся аргументы регистра во время выполнения преобразователя. Кроме того, в ней удобно хранить аргументы регистра, используемые в качестве параметров отладки (например поиск аргументов в процессе отладки является более эффективным, если они хранятся по внутреннему адресу в коде пролога). Даже если вызываемая функция принимает менее четырех параметров, для нее выделяется четыре ячейки стека, которые могут использоваться не только для хранения значений регистра параметров, но и для других целей. Таким образом, во время вызова функции вызывающий объект не может сохранять данные в этой области стека.
Если память для функции выделяется динамически (с помощью функции alloca), необходимо использовать защищенный регистр в качестве указателя кадра, с помощью которого помечается основание фиксированной части стека, а также указывается необходимость сохранения и инициализации регистра в прологе. Обратите внимание, что при использовании функции alloca при вызове одного и того же объекта из одного вызывающего объекта для параметров регистра могут использоваться различные внутренние адреса.
В стеке всегда используется 16-байтовое выравнивание, за исключением пролога (например при помещении возвращаемого адреса) и других случаев, определенных в разделе Типы функций для конкретных классов или функций кадра.
В следующем примере описывается структура стека, в которой функция A вызывает неоконечную функцию B. В прологе функции A уже выделена память в нижней части стека для всех параметров регистра и стека, необходимых для выполнения функции B. В результате вызова в стек помещается возвращаемый адрес, а в прологе функции B выделяется память для ее локальных переменных и защищенных регистров, а также память, необходимая для вызова функций из функции B. Если для функции B используется функция alloca, память выделяется между областью для хранения локальных переменных или защищенного регистра и областью стека параметра.
При вызове другой функции из функции B возвращаемый адрес помещается непосредственно под внутренним адресом регистра RCX.