Я пытаюсь понять, как строятся стековые фреймы и какие переменные (параметры) помещаются в стек в каком порядке? Некоторые результаты поиска показали, что компилятор C / C ++ принимает решение на основе операций, выполняемых внутри функции. Например, если функция должна была просто увеличить переданное значение int на 1 (аналогично оператору ++) и вернуть его, она поместит все параметры функции и локальные переменные в регистры.
Мне интересно, какие регистры используются для возвращаемых или передаваемых по значению параметров. Как возвращаются ссылки? Как компилятор выбирает между eax, ebx, ecx и edx?
Что мне нужно знать, чтобы понять, как регистры, ссылки на стек и кучи используются, создаются и уничтожаются во время вызовов функций?
Ответы:
В дополнение к тому, что сказал Дирк, важным использованием стековых фреймов является сохранение предыдущих значений регистров, чтобы они могли быть восстановлены после вызова функции. Таким образом, даже на процессорах, где регистры используются для передачи параметров, возврата значения и сохранения адреса возврата, значения этих регистров сохраняются в стеке до вызова функции, чтобы их можно было восстановить после вызова. Это позволяет одной функции вызывать другую, не перезаписывая свои собственные параметры и не забывая свой собственный адрес возврата.
Таким образом, вызов функции B из функции A в типичной «универсальной» системе может включать следующие шаги:
Это ни в коем случае не единственный способ, которым могут работать вызовы функций (и у меня может быть один или два шага не по порядку), но это должно дать вам представление о том, как стек используется, чтобы позволить процессору обрабатывать вызовы вложенных функций.
источник
push
иpop
являются двумя основными операциями в стеке. Стек - это структура «первым пришел - первым вышел», как стопка книг. Когда выpush
, вы помещаете новый объект поверх стека; когда выpop
берете объект с вершины стека. Вы не можете вставлять или удалять объекты в середине, вы можете работать только на вершине стека. Вы можете прочитать больше о стеках в целом и о программном стеке в частности в Википедии.Это зависит от используемого соглашения о вызовах. Тот, кто определяет соглашение о вызовах, может принять это решение, как ему угодно.
В наиболее распространенном соглашении о вызовах в x86 регистры не используются для передачи параметров; параметры помещаются в стек, начиная с самого правого параметра. Возвращаемое значение помещается в eax и может использовать edx, если ему нужно дополнительное пространство. Ссылки и указатели возвращаются в виде адреса в eax.
источник
Если вы хорошо разбираетесь в стеке, тогда вы поймете, как работает память в программе, и если вы поймете, как работает память в программе, вы поймете, как хранится функция в программе, и если вы поймете, как хранится функция в программе, вы поймете, как работает рекурсивная функция, и если вы поймете, как работает рекурсивная функция, вы поймете, как работает компилятор, и если вы поймете, как работает компилятор, ваш ум будет работать как компилятор, и вы очень легко отладите любую программу
Позвольте мне объяснить, как работает стек:
Сначала вы должны знать, как функция хранится в стеке:
Кучи хранят значения динамического выделения памяти. Стек хранить автоматическое размещение и удаление значений.
Давайте разберемся с примером:
Теперь разберитесь в частях этой программы:
Теперь давайте посмотрим, что такое стек и что такое части стека:
Помните одно: если какая-либо функция получит «return», независимо от того, загружены ли все его локальные переменные или что-то, что она немедленно вернет из стека, будет его стековым фреймом. Это означает, что когда любая рекурсивная функция получает базовое условие, и мы ставим return после базового условия, чтобы базовое условие не дожидалось загрузки локальных переменных, находящихся в «остальной» части программы, она немедленно возвращает текущий кадр из стека и теперь, если один кадр возвращать следующий кадр в записи активации. Смотрите это на практике:
Так что теперь, когда функция находит оператор возврата, она удаляет текущий кадр из стека.
при возврате из стека значение вернется в обратном порядке, в котором они размещены в стеке.
Это очень краткое описание, и если вы хотите узнать больше о стеке и двойной рекурсии, прочитайте два поста этого блога:
Подробнее о стеке шаг за шагом
Подробнее о двойной рекурсии шаг за шагом со стеком
источник
То, что вы ищете, называется Application Binary Interface - ABI.
Существует спецификация для каждого компилятора, в которой прописан ABI.
Каждая платформа обычно указывает и ABI для поддержки взаимодействия между компиляторами. Например, x86 соглашение о вызовах прописываются типичными соглашения о вызовах для x86 и x86-64. Однако я бы ожидал более официальный документ, чем википедия.
источник