оптимизация стека gcc - PullRequest
       9

оптимизация стека gcc

4 голосов
/ 23 февраля 2011

Привет У меня есть вопрос о возможной оптимизации стека с помощью gcc (или g ++) ..

Пример кода под FreeBSD (имеет ли значение здесь разница UNIX?):

void main() {
   char bing[100];
   ..
   string buffer = ....;
   ..
}

Что я нашел в gdb для coredump этой программы, так это то, что адрес Bing на самом деле ниже, чем этот буфер (а именно, & bing [0] <& buffer). </p>

Я думаю, что это полностью противоречит сказанному в учебнике. Мог там быть некоторой оптимизацией компилятора, которая реорганизует макет стека в такой способ

Это, кажется, единственно возможное объяснение, но я не уверен ..

Если вам интересно, coredump вызван переполнением буфера bing to buffer (но это также подтверждает & bing [0] <& buffer). </p>

Спасибо!

Ответы [ 2 ]

9 голосов
/ 23 февраля 2011

Компиляторы могут свободно организовывать кадры стека (при условии, что они даже используют стеки) любым способом, каким они пожелают.

Они могут делать это по причинам выравнивания, или по соображениям производительности, или вообще без причины. Вам было бы неразумно принимать какой-либо конкретный заказ.

Если бы вы не вызвали неопределенное поведение из-за переполнения буфера, вы, вероятно, никогда бы об этом не узнали, и так оно и должно быть.

Компилятор может не только реорганизовать ваши переменные, но и оптимизировать их из существования, если он может установить, что они не используются. С кодом:

#include <stdio.h>
int main (void) {
   char bing[71];
   int x = 7;
   bing[0] = 11;
   return 0;
}

Сравните нормальный вывод ассемблера:

main:
    pushl   %ebp
    movl    %esp, %ebp
    andl    $-16, %esp
    subl    $80, %esp
    movl    %gs:20, %eax
    movl    %eax, 76(%esp)
    xorl    %eax, %eax
    movl    $7, (%esp)
    movb    $11, 5(%esp)
    movl    $0, %eax
    movl    76(%esp), %edx
    xorl    %gs:20, %edx
    je      .L3
    call    __stack_chk_fail
.L3:
    leave
    ret

с безумно оптимизированным:

main:
    pushl   %ebp
    xorl    %eax, %eax
    movl    %esp, %ebp
    popl    %ebp
    ret

Заметили что-нибудь пропущенное в последнем? Да, есть нет стековых манипуляций для создания пространства для bing или x. Их не существует Фактически вся последовательность кода сводится к:

  • установить код возврата на 0.
  • возвращение.
8 голосов
/ 23 февраля 2011

Компилятор может размещать локальные переменные в стеке (или сохранять их в регистре, или делать с ними что-то еще), однако он считает это целесообразным: стандарты языка C и C ++ ничего не говорят об этих деталях реализации, и ниделает POSIX или UNIX.Я сомневаюсь, что ваш учебник говорил вам иначе, и если бы это было так, я бы искал новый учебник.

...