Одна из интересных возможностей системы команд PDP-11 - эффективная реализация сопрограммного перехода.
Сопрограммный (coroutine) переход - это операция передачи управления, совмещающая в себе вызов подпрограммы и возврат из подпрограммы. Как такое может быть? Вот как:
Вызов подпрограммы | Сопрограммный переход | Возврат из подпрограммы | |||
---|---|---|---|---|---|
Удаляет вершину стека | |||||
Cохраняет адрес возврата в стеке | |||||
Переходит по адресу | |||||
указанному в аргументе | на бывшей вершине стека | ||||
Примечание для пуристов: вершина стека с точки зрения этих операций вовсе не обязана быть в памяти; она с тем же успехом может быть в регистре; таким образом операции типа JSR R5, addr / RTS R5 тоже описываются этой таблицей. Ответ на вопрос, что нужно сделать для сопрограммного перехода, если адрес возврата хранится в R5, оставляется в качестве самостоятельного упражнения. |
Как же совместить все четыре операции в среднем столбце в одной машинной команде? Нужно сделать так, чтобы вершина стека была аргументом и удалялась до того, как в стеке будет сохранён адрес возврата. Как это ни парадоксально, команда
JSR PC, @(SP)+делает ровно то, что нужно.
Такой способ организации управления особенно удобен для подпрограмм, находящихся в отношении производитель-обработчик-потребитель, в тех случаях, когда первоначально управление принадлежит не обработчику, и обработчик может хотеть производить или потреблять произвольное количество данных зараз. Традиционной реализацией будут конечные автоматы внутри процедур, а сопрограммный переход позволяет сделать эти конечные автоматы неявными.