Примечание
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Блок, относящийся только к системам Майкрософт
Прежде чем писать собственные последовательности кода пролога и эпилога, важно понять, как выложен кадр стека. Также полезно знать, как использовать __LOCAL_SIZE
символ.
Макет кадра стека
В данном примере показан стандартный код пролога, который может присутствовать в 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-4
. Для доступа к локальным переменным необходимо вычислить смещение от ebp
путем вычитания соответствующего значения из ebp
.
__LOCAL_SIZE
Компилятор предоставляет символ для __LOCAL_SIZE
использования в блоке встроенного сборщика кода пролога функции. Этот символ служит для выделения пространства локальным переменным в кадре стека пользовательского кода пролога.
Компилятор определяет значение __LOCAL_SIZE
. Это значение представляет общее количество байтов всех определяемых пользователем локальных переменных и временных переменных, создаваемых компилятором. __LOCAL_SIZE
можно использовать только в качестве немедленного операнда; его нельзя использовать в выражении. Значение этого символа не следует изменять и переопределять. Например:
mov eax, __LOCAL_SIZE ;Immediate operand--Okay
mov eax, [ebp - __LOCAL_SIZE] ;Error
В следующем примере голой функции, содержащей пользовательские последовательности пролога и эпилога, используется __LOCAL_SIZE
символ в последовательности пролога:
// the__local_size_symbol.cpp
// processor: x86
__declspec ( naked ) int main() {
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
}
}
Завершение блока, относящегося только к системам Майкрософт