Чтобы понять рекурсию, вам нужно понять модель хранилища.Хотя есть несколько вариантов, в основном «автоматическое» хранение, хранилище, используемое для хранения автоматических переменных, параметров, температуры компилятора и информации о вызове / возврате, организовано как «стек».Это структура хранения, начинающаяся в некотором месте в хранилище процессов и «растущая» либо «вверх» (увеличение адресов), либо «вниз» (уменьшение адресов) при вызове процедур.
Можно начать с парыпеременных:
00 -- Variable A -- 27
01 -- Variable B -- 45
Затем мы решаем вызвать процедуру X, поэтому мы генерируем параметр A + B:
02 -- Parameter -- 72
Нам нужно сохранить местоположение, в котором мы хотим контролироватьвернуть.Скажем, инструкция 104 является вызовом, поэтому мы сделаем 105 обратным адресом:
03 -- Return address -- 105
Нам также нужно сохранить размер вышеупомянутого «стека фрейма» - четыре слова, 5 с размером фреймаСамо по себе:
04 -- Frame size -- 5
Теперь мы начинаем выполнение в X. Ему нужна переменная C:
05 -- Variable C -- 123
И она должна ссылаться на параметр.Но как это сделать?Ну, при входе указатель стека был установлен так, чтобы он указывал на «дно» «кадра стека» X.Мы могли бы сделать «низ» любым из нескольких мест, но давайте сделаем его первой переменной в кадре X.
05 -- Variable C -- 123 <=== (Stack frame pointer = 5)
Но нам все равно нужно ссылаться на параметр.Мы знаем, что «ниже» нашего фрейма (на который указывает указатель фрейма стека) находятся (в порядке убывания адреса) размер фрейма, адрес возврата, а затем наш параметр.Поэтому, если мы вычтем 3 (для этих 3 значений) из 5, мы получим 2, которое является местоположением параметра.
Обратите внимание, что на данный момент нам не важно, равен ли наш указатель кадра 5 или 55555- мы просто вычитаем ссылочные параметры, добавляем для ссылки наши локальные переменные.Если мы хотим сделать вызов, мы «складываем» параметры, адрес возврата и размер кадра, как мы это делали при первом вызове.Мы могли бы делать вызов после вызова после вызова и просто продолжать «проталкивать» стековые кадры.
Чтобы вернуть нас, загрузите размер кадра и адрес возврата в регистры.Вычтите размер кадра из указателя кадра стека и поместите адрес возврата в счетчик команд, и мы вернемся к процедуре вызова.
Теперь это упрощение, и существует множество различных способов обработкиуказатель кадра стека, передача параметров и отслеживание размера кадра.Но основы применяются независимо.