C ++, сборка ATT
У меня есть следующий код сборки:
push %ebp
mov %esp, %ebp
sub $0x28, %esp
(...)
Мой учебник утверждает, что вычитая 0x28 из% esp (как часть формирования стека), 12 байтов выделяется для переменных. Почему вычитание десятичного числа 40 из стека выделяет 12 байтов?
Это выделяет 40 байтов в стеке. Тем не менее, есть и другие применения, кроме локальных переменных, поэтому я предполагаю, что остальное используется для выравнивания и аргументов для будущего вызова функции.
Так как аргументы функции также передаются в стеке, должно быть место для любого, который эта функция хочет передать другой. Можно выделить это пространство при выполнении вызова с помощью push
, но это довольно распространено, чтобы выделить место один раз в начале функции и просто использовать mov
чтобы поместить данные в положение позже. Если ваша функция использует 12 байтов для локальных переменных, это оставляет до 28 для аргументов функции, которые будут использоваться позже.
Также может быть немного больше выделено для выравнивания. В дополнение к выравниванию переменных, упомянутому Джерри, многие системы ожидают, что указатель стека будет выровнен по определенному значению, поэтому его необходимо сохранить, если вы собираетесь выполнить вызов функции. В 32-битных системах это часто 8 байтов, но в этом случае также может быть 16.
Я подозреваю, что вы, возможно, неправильно прочитали свою книгу, но если нет, мне кажется, что книга по этому поводу ошибается.
Вычитание 40 из указателя стека выделяет 40 байтов. Это не может всегда быть точно правильным1, но любое отклонение от этого обычно будет довольно маленьким.
char
Локальная переменная, как правило, будет по-прежнему вычитать по крайней мере 4 из указателя стека, чтобы освободить место для нее.