почему gcc 4.x значение по умолчанию резервируют 8 байтов для стека на Linux при вызове метода?

как новичок asm, я проверяю, что gcc-S сгенерировал код asm для изучения.

почему gcc 4.x значение по умолчанию резервируют 8 байтов для стека при вызове метода?

func18 является пустой функцией без возврата никакой параметрический усилитель никакой локальный определенный var. Я не могу выяснить, почему 8 байтов резервируются здесь (никакое любое упоминание форума/сайта по причине, люди кажется, принимают как очевидное), это для %ebp, просто продвигают? или возвратите тип?! большое спасибо!

      .globl _func18
  _func18:
     pushl   %ebp 
     movl    %esp, %ebp 
     subl    $8, %esp 
     .text 
7
задан Tim Post 8 March 2010 в 04:01
поделиться

3 ответа

Простой способ узнать: у вас пустая функция вызывает другую функцию с одним параметром. Если параметр хранится непосредственно в стеке (без проталкивания), то для этого нужно дополнительное пространство.

0
ответ дан 7 December 2019 в 07:43
поделиться

Как Ричард упомянул выше, это все из-за оптимизации, показанной ниже. но я все еще не понимаю, почему зарезервированные 8 байтов - это что-то оптимизированное ?!

исходный c

void func18() {}
int main() {return 0;}

компилируется без указанного флага оптимизации

    .text                                                                                   
.globl _func18
_func18:
    pushl   %ebp
    movl    %esp, %ebp
    subl    $8, %esp
    leave
    ret
.globl _main
_main:                                                                                      
    pushl   %ebp
    movl    %esp, %ebp
    subl    $8, %esp
    movl    $0, %eax
    leave
    ret
    .subsections_via_symbols

с флагом оптимизации -Os, без резерва стека

    .text
.globl _func18
_func18:
    pushl   %ebp
    movl    %esp, %ebp
    leave
    ret
.globl _main
_main:
    pushl   %ebp
    xorl    %eax, %eax
    movl    %esp, %ebp
    leave
    ret
    .subsections_via_symbols
0
ответ дан 7 December 2019 в 07:43
поделиться

Некоторые инструкции требуют выравнивания определенных типов данных по 16-байтовой границе (в частности, SSE-тип данных __m128). Чтобы удовлетворить это требование, gcc гарантирует, что стек изначально выровнен по 16 байтам, и выделяет пространство стека кратно 16 байтам. Если нужно переместить только 4-байтовый адрес возврата и 4-байтовый указатель кадра, то для выравнивания стека по 16-байтовой границе требуется 8 дополнительных байт. Однако если gcc определит, что дополнительное выравнивание не нужно (т.е. не используются причудливые типы данных и не вызываются внешние функции), то он может опустить все дополнительные инструкции, используемые для выравнивания стека. Анализ, необходимый для определения этого, может потребовать выполнения определенных проходов оптимизации.

См. также документацию gcc для опции -mpreferred-stack-boundary=num.

7
ответ дан 7 December 2019 в 07:43
поделиться
Другие вопросы по тегам:

Похожие вопросы: