что находится в стеке при вызове функции? - PullRequest
2 голосов
/ 08 апреля 2011

я могу только представить 1) параметры; 2) локальные переменные;

что еще?

1) адрес возврата функции? 2) имя функции?

Ответы [ 3 ]

5 голосов
/ 08 апреля 2011

Это действительно зависит от платформы и архитектуры, но обычно:

  • Адрес возврата функции
  • Сохраненные значения регистров ЦП вызывающего абонента - что наиболее важно, значение указателя кадра стека вызывающего абонента
  • Переменные, выделенные с помощью alloca ().
  • Иногда - дополнительный материал для обработки исключений, это ОЧЕНЬ зависит от платформы.
  • Иногда - защитные значения для обнаружения стеков

Насколько мне известно, имя функции никогда не находится в стеке, если только ваш код не поместит его туда.

2 голосов
/ 08 апреля 2011

Это зависит от соглашения о вызовах;для Unix вы обычно просматриваете эту информацию в SYSV ABI (двоичный интерфейс приложения).

Вы можете найти:

  • Адрес возврата (если машина популярна)Архитектура Intel).В более современных архитектурах адрес возврата передается в регистре.

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

  • Любые входящие параметры, которые не могут быть переданы в регистрах.В IA-32 параметры no передаются в регистрах;все они идут в стек.В x86-64 в регистры можно передавать до шести целочисленных и шести параметров с плавающей запятой, поэтому для этой цели редко используется стек.

  • Вы можете или можетене найти сохраненный указатель стека или указатель кадра.Большинство современных соглашений о вызовах обходятся без указателя кадра, чтобы сохранить дополнительные регистры.В этой схеме размер каждого кадра известен во время компиляции, поэтому восстановление старого указателя стека - это просто вопрос добавления константы.Но это усложняет реализацию alloca().

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

  • Локальные переменные с классом хранения auto размещены в стеке.

  • В стеке могут содержаться временные значения компилятора, которые содержат значения, которые "разлиты", еслиаппаратное обеспечение не предоставляет достаточно регистров для хранения всех промежуточных результатов вычислений.(Это происходит, если в какой-то момент количество промежуточных результатов в реальном времени - тех, которые понадобятся позже в программе - превышает число регистров, доступных компилятору для хранения промежуточных результатов.)

  • Вы можете найти переменные, выделенные с помощью alloca().

  • Вы можете найти метаданные, в которых указано, какие диапазоны ПК находятся в области действия, для каких обработчиков исключений, или другие вещи, зависящие от платформы.

  • C и C ++ не поддерживают сборку мусора, но на языке, который это делает, вы часто найдете метаданные, которые определяют, где в фрейме стека вы найдете указатели.

  • Наконец, стек может содержать «заполнение», используемое для обеспечения выравнивания указателя стека на 8-байтовой или 16-байтовой границе.

Соглашения о вызовахэто сложные звери, и расположение стеков не для слабонервных!

2 голосов
/ 08 апреля 2011

Я думаю, что картинка на самом деле это тысяча слов.

...