Средства разработки приложений



              

Сохранение адреса возврата в коде


Инструкция перехода на подпрограмму, предложенная Дэвидом Уилером (David John Wheeler), сохраняет значение счетчика команд, которое должно быть восстановлено при завершении подпрограммы. Проблема состоит в выборе места для сохранения этого значения. В нескольких компьютерах, в основном, в миникомпьютерах, но также и в мейнфрейме CDC 6000, инструкция такого перехода на ячейку с адресом d сохраняла адрес возврата в этой ячейке и продолжала выполнение с адреса d+1: mem[d] := PC+1; PC := d+1. Эта идея была плохой, по крайней мере, по двум причинам. Во-первых, это не давало возможности вызывать подпрограммы рекурсивно. В языке Algol была введена рекурсия, и это вызвало многочисленные споры по причине невозможности обрабатывать рекурсивные вызовы процедур таким простым образом, поскольку рекурсивный вызов затирал адрес возврата предыдущего вызова. Поэтому приходилось считывать адрес возврата из фиксированного места и помещать в место, уникальное для конкретного воплощения рекурсивной процедуры. Эти накладные расходы были неприемлемы для многих разработчиков и пользователей компьютеров, заставляя их объявлять рекурсию нежелательной, бесполезной и запретной. Они отказывались признать, что эти трудности порождались неадекватностью инструкции вызова.

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

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


Содержание  Назад  Вперед