Я пытаюсь проанализировать инициализацию/очистку стека Linux при вызове/возврате функции, используя этот фрагмент кода ниже. Предназначены неинициализированные переменные.Вопросы о инициализации стека Linux-функций
#define MAX 16
typedef struct _CONTEXT {
int arr[MAX];
int a;
int b;
int c;
};
void init(CONTEXT* ctx)
{
memset(ctx->arr, 0, sizeof(ctx->arr[0]));
ctx->a = 1;
}
void process(CONTEXT* ctx)
{
int trash;
int i;
for (i = 0; i < MAX; i++)
{
trash = ctx->arr[i];
}
}
int main(int argc, char *argv[])
{
CONTEXT ctx;
init(&ctx);
process(&ctx);
return 0;
}
Как я узнал из школы, и из этой лекции slide,
собрание инициализации стеки функции, (в стиле-1) должно выглядеть следующим образом:
pushq %rbp
movq %rsp, %rbp
subq $16, %rsp
movq %rdi, -8(%rbp)
...
leave
ret
Но когда Я компилирую фрагмент кода выше с помощью gcc, функция main
и init
имеет ту же процедуру инициализации стека style-1 включая subq
инструкции, чтобы выделить пространство памяти переменных стека,
, но функция process
не имеет такой инициализации стека.
Я получил эту сборку код (стиль-2):
pushq %rbp
movq %rsp, %rbp
movq %rdi, -24(%rbp)
...
popq %rbp
ret
Так вопросы:
Что политика решения составитель создания различных функций инициализации стека во время компиляции? Я не помещал
__cdecl
или такой код в этот код, но найдена 2 разные инициализации стека.Как узнать адрес и размер выделенной ячейки памяти, когда инициализирована функция style-2?
Какова цель
movq %rdi, -8(%rbp)
?Есть несколько стилей инициализации стека подле стиля-1 и стиль-2 в Linux?
(не говоря уже о__cdecl
или__stdcall
вещей явно)
Как вы его компилировали? вы использовали настройки оптимизации? Если да, то выход может отличаться в зависимости от того, что действительно используется в функции. особенно с таким примером, как это, которые в основном оплодотворяются. – Devolus
Я просто gcc-ed без оптимизации, поэтому оптимизация по умолчанию (-O2?) Была моей настройкой, я думаю. – LocustSpectre
Я сгенерировал другой файл сборки с -O0, но нашел только одно различие (наличие -O0), используя diff между двумя файлами сборки (по умолчанию и -O0). – LocustSpectre