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

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

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

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

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

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


person Divya    schedule 08.03.2017    source источник
comment
Возможно, GCC поместил переменную в регистр или оптимизировал ее, поскольку она не использовалась? Вы не можете описать, почему это проблема (и, конечно же, не можете показать какой-либо код).   -  person unwind    schedule 08.03.2017
comment
Может дело в оптимизации? И локальные переменные (также известные как автоматические переменные) не должны находиться в стеке.   -  person Some programmer dude    schedule 08.03.2017


Ответы (1)


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

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

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

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

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

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

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

int f()
{
    int i;

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

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

person JeremyP    schedule 08.03.2017