Объясните концепцию стекового фрейма в двух словах
кажется, что я понял идею стек вызовов в дизайне языка программирования. Но я не могу найти (наверное, я просто не достаточно усердно ищу) какое-либо достойное объяснение того, что стек есть.
поэтому я хотел бы попросить кого-нибудь объяснить мне в нескольких словах.
6 ответов:
кадр стека-это кадр данных, который помещается в стек. В случае стека вызовов фрейм стека будет представлять вызов функции и ее данные аргументов.
Если я правильно помню, адрес возврата функции сначала помещается в стек, а затем Аргументы и пространство для локальных переменных. Вместе они составляют "каркас", хотя это, вероятно, зависит от архитектуры. Процессор знает, сколько байтов находится в каждом кадре и перемещает указатель стека соответственно, как кадры толкнул и выскочил из стека.
EDIT:
существует большая разница между стеками вызовов более высокого уровня и стеком вызовов процессора.
когда мы говорим о стеке вызовов процессора, мы говорим о работе с адресами и значениями в байт/слово Уровень в сборке или машинном коде. Существуют "стеки вызовов", когда речь идет о языках более высокого уровня, но они являются инструментом отладки/выполнения, управляемым среда выполнения, чтобы вы могли регистрировать, что пошло не так с вашей программой (на высоком уровне). На этом уровне часто известны такие вещи, как номера строк, имена методов и классов. Когда процессор получает код, это не имеет абсолютно никакого понятия об этих вещах.
быстрое завершение. Может, у кого-то есть лучшее объяснение.
стек вызовов состоит из 1 или нескольких кадров стека. Каждый кадр стека соответствует вызову функции или процедуры, которая еще не завершилась возвращением.
чтобы использовать кадр стека, поток содержит два указателя, один из которых называется указателем стека (SP), а другой-указателем кадра (FP). SP всегда указывает на " вершину "стека, а FP всегда указывает на" вершину " стека. рамка. Кроме того, поток также поддерживает счетчик программ (PC), который указывает на следующую инструкцию, которая должна быть выполнена.
в стеке хранятся: локальные переменные и временные значения, фактические параметры текущей инструкции (процедуры, функции и др.).)
существуют различные соглашения о вызовах, касающиеся очистки стека.
Если вы понимаете стек очень хорошо, то вы поймете, как память работает в программе и если вы понимаете, как память работает в программе вы поймете, как функция хранить в программе и если вы понимаете, как функция хранить в программе вы поймете, как рекурсивная функция работает и если вы понимаете, как рекурсивная функция работает вы поймете, как работает компилятор и если вы понимаете, как работает компилятор ваш ум будет работать как компилятор и вы будете отлаживать любую программу очень хорошо легко
позвольте мне объяснить, как стек работает:
сначала вы должны знать, как хранить функции в стеке :
кучи хранить динамические значения выделения памяти. Стек хранит значения автоматического выделения и удаления.
давайте разберемся с Пример :
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)теперь разбираемся в частях этой программы:
теперь давайте посмотрим, что такое стек и что такое части стека:
выделение стека :
помните одну вещь, если какая-либо функция получает "return" независимо от того, что она загрузила все свои локальные переменные или что-то, что она немедленно вернет из стека, будет его кадр стека. Это означает, что когда любая рекурсивная функция получает базовое условие, и мы ставим return после базового условия, поэтому базовое условие не будет ждать загрузки локальных переменных, которые находятся в "else" часть программы он немедленно вернет текущий кадр из стека и теперь, если один кадр возвращает следующий кадр в записи активации. Смотрите это на практике:
освобождение блока:
поэтому теперь всякий раз, когда функция находит оператор return, он удаляет текущий кадр из стека.
при возврате из стека значение будет возвращаться в обратном порядке, в котором они выделены в стек.
Это очень краткое описание, и если вы хотите узнать больше о стеке и двойной рекурсии, прочитайте два сообщения этого блога:
"стек вызовов состоит из кадров стека..."- Википедия
кадр стека является то, что вы кладете в стек. Это структуры данных, содержащие информацию о вызываемых подпрограммах.
у программистов могут возникнуть вопросы о кадрах стека не в широком смысле (что это объект паленого в стеке, который обслуживает только один вызов функции и сохраняет обратный адрес, Аргументы и локальные переменные), а в узком смысле – когда термин
stack framesупоминается в контексте параметров компилятора.имел ли автор вопроса в виду это или нет, но понятие кадра стека с точки зрения параметров компилятора является очень важным вопросом, не охватываемым другим ответы здесь.
например, компилятор Microsoft Visual Studio 2015 C/C++ имеет следующий параметр, связанный с
stack frames:
- /Oy (Пропуск Указателя Кадра)
GCC имеют следующее:
- - fomit-frame-pointer (не держите указатель кадра в регистре для функций, которые в нем не нуждаются. Это позволяет избежать инструкций по сохранению, настройке и восстановлению указателей кадров; это также делает дополнительный регистр доступным во многих функции)
компилятор Intel C++ имеет следующее:
- - fomit-frame-pointer (определяет, используется ли EBP в качестве универсального регистра в оптимизациях)
, который имеет следующие псевдонимы:
- / Oy
Delphi имеет следующий параметр командной строки:
- - $W+ (Генерация Стековых Кадров)
в этом конкретном смысле, от компилятора перспектива, кадр стека-это просто код входа и выхода для процедуры, что толкает якорь в стек – это также может быть использован для отладки и обработки исключений. Отладочные инструменты могут сканировать данные стека и использовать эти якоря для отслеживания в обратном направлении при поиске
call sitesв стеке, т. е. для отображения имен функций в том порядке, в котором они были вызваны иерархически. Для архитектуры Intel, этоpush ebp; mov ebp, espилиenterдля входа иmov esp, ebp; pop ebpилиleaveдля выход.вот почему очень важно понять для программиста, что такое кадр стека, когда речь заходит о параметрах компилятора – потому что компилятор может контролировать, генерировать ли этот код или нет.
в некоторых случаях фрейм стека (код входа и выхода для подпрограммы) может быть опущен компилятором, и переменные будут напрямую доступны через указатель стека (SP/ESP/RSP), а не удобный базовый указатель (BP/ESP/RSP). Условия для пропуска кадр стека, например:
- функция является конечной функцией (т. е. конечной сущностью, которая не вызывает другие функции);
- нет try / finally или try / except или подобных конструкций, т. е. никаких исключений не используется;
- никакие подпрограммы не вызываются с исходящими параметрами в стеке;
- функция не имеет параметров;
- функция не имеет встроенную сборку код;
- etc...
пропуск кадров стека (код входа и выхода для подпрограммы) может сделать код меньше и быстрее, но это также может негативно повлиять на способность отладчиков отслеживать данные в стеке и отображать их программисту. Это параметры компилятора, которые определяют, при каких условиях функция должна иметь код входа и выхода, например: (A) всегда, (b) никогда, (c) при необходимости (указание условий).
кадр стека-это упакованная информация, связанная с вызовом функции. Эта информация обычно включает в себя аргументы, передаваемые в функцию th, локальные переменные и место возврата после завершения. Запись активации-это другое имя для кадра стека. Макет кадра стека определяется в ABI производителем, и каждый компилятор, поддерживающий ISA, должен соответствовать этому стандарту, однако схема компоновки может зависеть от компилятора. Обычно размер кадра стека не ограничен, но есть это понятие называется "Красная / защищенная зона", чтобы разрешить системные вызовы...etc для выполнения без вмешательства в кадр стека.
всегда есть SP, но на некоторых ABIs (например, ARM и PowerPC) FP является необязательным. Аргументы, которые должны быть помещены в стек, могут быть смещены только с помощью SP. Генерируется ли кадр стека для вызова функции или нет, зависит от типа и количества аргументов, локальных переменных и общего доступа к локальным переменным. На большинстве МСА, во-первых, используются регистры, и если существует больше аргументов, чем регистров, выделенных для передачи аргументов, они помещаются в стек (например, x86 ABI имеет 6 регистров для передачи целочисленных аргументов). Следовательно, иногда некоторые функции не нуждаются в кадре стека, который должен быть помещен в стек, просто обратный адрес помещается в стек.





Comments