Реализация вызова подпрограммы и возврата из нее в основную программу

Адрес ячейки памяти, на которую следует возвратиться после выполнения подпрограммы, становится известным только в момент обработки процессором команды ВЫЗОВ ПОДПРОГРАММЫ. Фактически этим адресом является адрес команды, следующей за командой вызова подпрограммы. При этом мы знаем, что в момент после выборки этой команды из памяти в регистр команд процессора адрес, находящийся в это время в регистре — счетчике команд процессора, становится равным адресу следующей по порядку команды. Другими словами, в момент, когда процессор приступает к интерпретации команды вызова подпрограммы, нужный нам адрес возврата из подпрограммы находится в регистре — счетчике команд процессора. Поэтому вполне естественным для обеспечения в процессе выполнения команды вызова подпрограммы возможности правильного возврата из этой подпрограммы является предварительное сохранение текущего содержимого счетчика команд (адреса возврата) перед тем, как оно будет замещено адресом начала подпрограммы, чтобы им можно было воспользоваться при возврате из подпрограммы. Именно поэтому, в частности, для перехода к подпрограмме не могут быть использованы рассмотренные ранее команды безусловных и условных переходов.

Таким образом, главным вопросом, который должен быть решен при запоминании адреса возврата (состояния регистра — счетчика команд), является определение места, в котором он должен быть сохранен и откуда он может быть извлечен при возврате из подпрограммы. Следует учесть, что это не может быть какая- либо единственная запоминающая ячейка или регистр. Если мы хотим реализовать возможность реализации вложенных подпрограмм, то возникает необходимость при их вызовах последовательно запоминать адреса возврата для каждой вызываемой подпрограммы (см. рис. 10.2). И при этом, чтобы не нарушать логику выполнения программы, сохраненные адреса возврата должны извлекаться во вложенных подпрограммах для возврата из них в порядке, противоположном порядку их запоминания при последовательном входе во вложенные подпрограммы.

Таким местом, в котором удобно осуществлять запоминание адресов возврата, является стек.

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

Представляя собой запоминающую структуру с одной точкой входа — выхода, которой является вершина стека, стек позволяет естественным образом решить проблему последовательного запоминания путем засылки в стек заранее неопределенного количества адресов возврата при вызове вложенных друг в друга подпрограмм и последовательного, но строго в обратном порядке, извлечения (выталкивания) этих адресов из стека при выполнении возвратов из вложенных подпрограмм. Принцип работы стека — «последним пришел — первым вышел» — как нельзя лучше подходит для реализации механизма возврата из вложенных подпрограмм: при последовательном входе во вложенные подпрограммы адреса возврата последовательно засылаются в стек, а при выходе из подпрограмм выталкиваются из стека в порядке, противоположном их записи в стек.

В ЭВМ автоматизация этих действий при обращении к подпрограммам осуществляется с помощью пары команд, имеющейся в системе команд любой ЭВМ:

  • • команда ВЫЗОВ ПОДПРОГРАММЫ, которая в разных ЭВМ может иметь разную мнемонику, например CALL, JSR, JSB;
  • • и команда ВОЗВРАТ ИЗ ПОДПРОГРАММЫ (RETURN, RET, RTS, RSB).

Аргументом команды ВЫЗОВ ПОДПРОГРАММЫ служит адрес входа в подпрограмму (адрес первой команды подпрограммы), задаваемый с помощью любого приемлемого метода адресации.

На рис. 10.3 показано последовательное изменение состояния регистра — счетчика команд (СК), регистра — указателя стека (УС) и ячеек памяти стека при вложенных вызовах подпрограмм и возврате из них.

При выполнении команды ВЫЗОВ ПОДПРОГРАММЫ процессор осуществляет следующие действия:

• текущее содержимое регистра — счетчика команд процессора (адрес, на который необходимо вернуться из вызываемой подпрограммы) пересылается в стек;

  • • задаваемый в команде вызова подпрограммы адрес входа в подпрограмму помещается в регистр — счетчик команд;
  • • после этого, как обычно, из памяти считывается команда, адрес которой находится в регистре — счетчике команд, то есть первая команда подпрограммы, и затем начинается выполнение подпрограммы.

Командой ВОЗВРАТ ИЗ ПОДПРОГРАММЫ должна завершаться любая подпрограмма.

  • • Получив эту команду, процессор извлекает (выталкивает) из стека записанный туда ранее командой ВЫЗОВ ПОДПРОГРАММЫ адрес возврата и помещает его в свой регистр — счетчик команд.
  • • Тем самым управление передается команде, следующей за командой вызова подпрограммы.
Иллюстрация работы регистров процессора при вызовах подпрограмм и возврате из них

Рис. 10.3. Иллюстрация работы регистров процессора при вызовах подпрограмм и возврате из них

CALL — переход к подпрограмме по указанному в команде адресу RETURN — возврат из подпрограммы

Контрольные вопросы

  • 1. Что такое подпрограммы, для чего они нужны?
  • 2. Какие проблемы необходимо решить для обеспечения возможности работы с подпрограммами?
  • 3. Что такое вложенные подпрограммы?
  • 4. Какую роль при реализации механизма подпрограмм играет стек?
  • 5. Почему для перехода к подпрограмме не используют команды безусловного или условных переходов?
  • 6. Что происходит при выполнении процессором команды ВЫЗОВ ПОДПРОГРАММЫ?
  • 7. Что происходит при выполнении процессором команды ВОЗВРАТ ИЗ ПОДПРОГРАММЫ?
 
Посмотреть оригинал
< Пред   СОДЕРЖАНИЕ   ОРИГИНАЛ     След >