Локальная переменная файла AC не создается в стеке, ее скомпилированный код GCC,

Я работаю в UEFI EDK2 биос источник. Мы создали новый пакет, связанный с платформой, в источнике EDK2. Я обнаружил странную проблему с кодом, связанным с платформой, который мы добавили.

Когда я выполнял отладку на уровне исходного кода, я заметил, что локальная переменная в функции C не создается в стеке при ее компиляции с GCC.

Тот же код UEFI при компиляции с Visual Studio, затем локальная переменная в функции C создается в стеке.

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

Это многоядерная система, но включены только процессоры Boot Strap.

1 ответ

Если вы прочтете спецификацию языка C11, вы обнаружите, что в ней никогда не упоминается стек, кадры стека или помещение переменных в стек. В C нет необходимости помещать автоматические переменные в любой вид стека.

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

Есть только две причины, по которым компилятор должен хранить автоматическую переменную в стеке:

  1. Слишком много переменных и аргументов, чтобы поместить их в регистры

  2. Функция берет адрес переменной (у вас не может быть указателя на регистр)

Таким образом, gcc, вероятно, решает, что ему не нужно создавать пространство стека для вашей переменной, и оно заносится в регистр. Компилятор Visual Studio C всегда был печально известен тем, что им пренебрегали Microsoft, поэтому он, вероятно, не совсем в курсе современных представлений об автоматических переменных.

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

int f()
{
    int i;

    for (i = 0 ; i < 10 ; ++i);
    return 0;
}

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

Другие вопросы по тегам