Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Блок, относящийся только к системам Майкрософт
Прежде чем писать собственные последовательности кода пролога и эпилога, важно понять, как выложен кадр стека. Также полезно знать, как использовать предопределенную константу __LOCAL_SIZE .
Макет кадра CStack
В данном примере показан стандартный код пролога, который может присутствовать в 32-разрядной функции.
push ebp ; Save ebp
mov ebp, esp ; Set stack frame pointer
sub esp, localbytes ; Allocate space for locals
push <registers> ; Save registers
Переменная localbytes
представляет число байтов, которые требуются в стеке для локальных переменных, а переменная registers
— это заполнитель, представляющий список сохраняемых в стеке регистров. После проталкивания регистров можно разместить в стеке все другие необходимые данные. Ниже приведен соответствующий код эпилога.
pop <registers> ; Restore registers
mov esp, ebp ; Restore stack pointer
pop ebp ; Restore ebp
ret ; Return from function
Стек всегда расширяется в направлении вниз (от старших адресов памяти к младшим). Указатель базы (ebp
) указывает на помещенное в стек значение ebp
. Область локальных переменных начинается с ebp-2
. Для доступа к локальным переменным необходимо вычислить смещение от ebp
путем вычитания соответствующего значения из ebp
.
Константа __LOCAL_SIZE
Компилятор предоставляет константу __LOCAL_SIZE, которую можно использовать использования во встроенном ассемблерном блоке кода пролога функции. Она служит для выделения пространства локальным переменным в кадре стека пользовательского кода пролога.
Значение константы __LOCAL_SIZE определяется компилятором. Это значение представляет общее количество байтов всех определяемых пользователем локальных переменных и временных переменных, создаваемых компилятором. Константу __LOCAL_SIZE можно использовать только в качестве непосредственного операнда, но не в выражениях. Значение этой константы не следует изменять и переопределять. Например:
mov eax, __LOCAL_SIZE ;Immediate operand--Okay
mov eax, [ebp - __LOCAL_SIZE] ;Error
В следующем примере функции naked с пользовательскими последовательностями пролога и эпилога константа __LOCAL_SIZE используется в последовательности пролога.
__declspec ( naked ) func()
{
int i;
int j;
__asm /* prolog */
{
push ebp
mov ebp, esp
sub esp, __LOCAL_SIZE
}
/* Function body */
__asm /* epilog */
{
mov esp, ebp
pop ebp
ret
}
}
Завершение блока, относящегося только к системам Майкрософт