Вопрос по – Объясните концепцию стекового фрейма в двух словах

154

Кажется, я понялcall stack в дизайне языка программирования. Но я не могу найти (возможно, я просто не достаточно много искал) какого-либо достойного объяснения того, чтоstack frame является.

Поэтому я хотел бы попросить кого-нибудь объяснить мне это в нескольких словах.

Ваш Ответ

6   ответов
40

Быстрое завершение. Может быть, у кого-то есть лучшее объяснение.

Стек вызовов состоит из 1 или нескольких стековых кадров. Каждый кадр стека соответствует вызову функции или процедуры, которая еще не завершена с возвратом.

Чтобы использовать кадр стека, поток сохраняет два указателя, один из которых называется указателем стека (SP), а другой - указателем кадра (FP). SP всегда указывает на «вершину» стека, а FP всегда указывает на «верх» рамы. Кроме того, поток также поддерживает программный счетчик (ПК), который указывает на следующую команду, которая должна быть выполнена.

В стеке хранятся следующие данные: локальные переменные и временные значения, фактические параметры текущей инструкции (процедура, функция и т. Д.)

В отношении очистки стека существуют разные соглашения о вызовах.

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded
-1

Кадр стека - это упакованная информация, связанная с вызовом функции. Эта информация обычно включает аргументы, передаваемые в функцию, локальные переменные и куда возвращаться после завершения. Запись активации - это другое имя стекового фрейма. Расположение кадра стека определяется в ABI производителем, и каждый компилятор, поддерживающий ISA, должен соответствовать этому стандарту, однако схема расположения может зависеть от компилятора. Обычно размер кадра стека не ограничен, но существует концепция, называемая «красная / защищенная зона»; разрешить выполнение системных вызовов ... и т. д. без вмешательства в кадр стека.

Всегда имеется SP, но в некоторых ABI (например, ARM и PowerPC) FP является необязательным. Аргументы, которые нужно было поместить в стек, можно сместить только с помощью SP. Будет ли кадр стека сгенерирован для вызова функции или нет, зависит от типа и количества аргументов, локальных переменных и от того, как вообще доступны локальные переменные. В большинстве ISA, во-первых, используются регистры, и если имеется больше аргументов, чем регистров, выделенных для передачи аргументов, они помещаются в стек (например, x86 ABI имеет 6 регистров для передачи целочисленных аргументов). Следовательно, иногда некоторые функции не нуждаются в размещении кадра стека в стеке, просто адрес возврата помещается в стек.

13

& quot; Стек вызовов состоит из кадров стека ... & quot; & # xA0; & # x2014; & # xA0;Википедия

Фрейм стека - это то, что вы кладете в стек. Это структуры данных, которые содержат информацию о подпрограммах для вызова.

Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded ikostia
Error: User Rate Limit ExceededmustError: User Rate Limit Exceeded
Error: User Rate Limit Exceededcompile timeError: User Rate Limit Exceeded
Error: User Rate Limit Exceeded ikostia
153

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

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

EDIT:

Существует большая разница между стеками вызовов более высокого уровня и стеком вызовов процессора.

Когда мы говорим о стеке вызовов процессора, мы говорим о работе с адресами и значениями вbyte/word level в сборке или машинном коде. Существуют «стеки вызовов» когда речь идет о языках более высокого уровня, но они являются средством отладки / выполнения, управляемым средой выполнения, так что вы можете регистрировать, что пошло не так с вашей программой (на высоком уровне). На этом уровне такие вещи, как номера строк, имена методов и классов, часто известны. К тому времени, когда процессор получает код, он совершенно не имеет понятия об этих вещах.

Error: User Rate Limit Exceeded
42

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

Позвольте мне объяснить, как работает стек:

Сначала вы должны знать, как функция хранится в стеке:

Кучи хранят значения динамического выделения памяти. Стек хранить автоматическое размещение и удаление значений.

enter image description here

Давайте разберемся с примером:

def hello(x):
    if x==1:
        return "op"
    else:
        u=1
        e=12
        s=hello(x-1)
        e+=1
        print(s)
        print(x)
        u+=1
    return e

hello(4)

Теперь разберитесь в частях этой программы:

enter image description here

Теперь давайте посмотрим, что такое стек и что такое части стека:

enter image description here

Allocation of the stack :

Запомните одну вещь, если какая-либо функция get & # x201C; return & # x201D; независимо от того, загрузили ли он все свои локальные переменные или что-либо еще, он немедленно вернется из стека в его кадр стека. Это означает, что когда любая рекурсивная функция получает базовое условие, и мы ставим return после базового условия, чтобы базовое условие не дожидалось загрузки локальных переменных, которые находятся в & # x201C; else & # x201D; часть программы будет немедленно возвращать текущий кадр из стека и теперь, если один кадр возвращает следующий кадр в записи активации. Смотрите это на практике:

enter image description here

Deallocation of the block:

Так что теперь, когда функция находит оператор возврата, она удаляет текущий кадр из стека.

при возврате из стека значение вернется в обратном порядке, в котором они размещены в стеке.

enter image description here

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

Подробнее о стеке шаг за шагом

Подробнее о двойной рекурсии шаг за шагом со стеком

Error: User Rate Limit Exceededstackoverflow.com/questions/1677415/…
Error: User Rate Limit ExceededCORRECT DIAGRAM HERE
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceededhello()Error: User Rate Limit Exceededhello()Error: User Rate Limit Exceededhello()Error: User Rate Limit Exceededhello()?
2

У программистов могут возникнуть вопросы о фреймах стека не в широком смысле (что это единичная сущность в стеке, которая обслуживает только один вызов функции и сохраняет адрес возврата, аргументы и локальные переменные), но в узком смысле & # x2013; когда срокstack frames упоминается в контексте параметров компилятора.

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

Например, компилятор Microsoft Visual Studio 2015 C / C ++ имеет следующий параметр, связанный сstack frames:

  • /Oy (Frame-Pointer Omission)

GCC имеют следующее:

  • -fomit-frame-pointer (Don't keep the frame pointer in a register for functions that don't need one. This avoids the instructions to save, set up and restore frame pointers; it also makes an extra register available in many functions)

Компилятор Intel C ++ имеет следующее:

  • -fomit-frame-pointer (Determines whether EBP is used as a general-purpose register in optimizations)

который имеет следующий псевдоним:

  • /Oy

Delphi имеет следующую опцию командной строки:

  • -$W+ (Generate Stack Frames)

В этом конкретном смысле, с точки зрения компилятора, кадр стека - это простоentry and exit code for the routine, который вставляет привязку в стек & # x2013; это также может быть использовано для отладки и обработки исключений. Инструменты отладки могут сканировать данные стека и использовать эти якоря для поиска, находяcall sites в стеке, т.е. чтобы отображать имена функций в том порядке, в котором они были вызваны иерархически. Для архитектуры Intel этоpush ebp; mov ebp, esp или жеenter для входа иmov esp, ebp; pop ebp или жеleave для выхода.

Вот почему для программиста очень важно понять, что такое фрейм стека, когда дело доходит до параметров компилятора & # x2013; потому что компилятор может контролировать, генерировать ли этот код или нет.

В некоторых случаях кадр стека (код входа и выхода для подпрограммы) может быть пропущен компилятором, и переменные будут напрямую доступны через указатель стека (SP / ESP / RSP), а не через удобный базовый указатель (BP / ESP / РСП). Условия пропуска стекового фрейма, например:

  • the function is a leaf function (i.e. an end-entity that doesn’t call other functions);
  • there are no try/finally or try/except or similar constructs, i.e. no exceptions are used;
  • no routines are called with outgoing parameters on the stack;
  • the function has no parameters;
  • the function has no inline assembly code;
  • etc...

Пропуск стековых кадров (код входа и выхода для подпрограммы) может сделать код меньше и быстрее, но это также может негативно повлиять на отладчики & # x2019; возможность отследить данные в стеке и отобразить их для программиста. Это параметры компилятора, которые определяют, при каких условиях функция должна иметь код входа и выхода, например: (a) всегда, (b) никогда, (c) при необходимости (с указанием условий).

Похожие вопросы