Как компилятор размещает локальные переменные в стеке? - PullRequest
2 голосов
/ 24 ноября 2010

Как мы знаем, локальные переменные расположены в стеке.Однако каков их порядок?Они расположены в порядке их декларации?Это означает, что первая объявленная переменная расположена на более высоком адресе стека (стек увеличивается до более низкого адреса)?В качестве примера:

void foo(){
 int iArray[4];
 int iVar;
}

В стеке локальные переменные - iArray и iVar расположены следующим образом?

Ответы [ 3 ]

5 голосов
/ 24 ноября 2010

Только если у вас отключена оптимизация!

Как только оптимизатор овладеет вашим кодом, все ставки отключены. Общие стратегии агрессивной оптимизации:

  • Удалять переменную, если она никогда не использовалась или является просто копией другой переменной.
  • Переупорядочивайте переменные в порядке их использования. Это очень помогает, если ваше приложение использует пространство подкачки, а также помогает использовать кеш (на некоторых машинах).
  • Перемещение часто используемых переменных в регистры. Обычный на риск инструментах с 32 прекрасными регистрами общего назначения. Не так часто встречается в Intel с ее жалкими восемью регистрами.
  • Изменить тип данных. например приведение небольших целых чисел к целым числам часто ускоряет загрузку и кеширование регистров.
  • изменить порядок хранения, чтобы минимизировать свободные байты. например, char a, double b, char c, int d могут быть переупорядочены на double b, int d, char a, char c, что позволяет сэкономить 10 байтов.
4 голосов
/ 24 ноября 2010

Нет правила, от которого вы можете зависеть.Большинство компиляторов будут использовать порядок объявлений, если вы не начнете оптимизировать код.

Включение оптимизации может привести к повторному использованию стекового пространства, переупорядочению локальных переменных или даже перемещению переменных в регистры ЦП, поэтому они не отображаютсяв стеке.

[EDIT] В некоторых системах стек увеличивается до больших адресов.Таким образом, он начинается с 0x1000, а следующий адрес - 0x1001 вместо того, чтобы начинаться с 0xffff, а следующий адрес - 0xfffe.

1 голос
/ 24 ноября 2010

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...