Восстановление значения в другом регистре
Когда мы в разделе 5.1.4 определяли
save
и
restore
, мы не указали, что произойдет, если попытаться восстановить значение не в том регистре, который был сохранен последним, как в последовательности команд
(save y)
(save x)
(restore y)
Есть несколько разумных вариантов значения
restore
:
а.
(restore y)
переносит в
y
последнее значение, сохраненное на стеке, независимо от того, откуда это значение взялось. Так работает наш имитатор. Покажите, как с помощью такого поведения убрать одну команду из машины Фибоначчи (раздел 5.1.4, рисунок 5.12).
б.
(restore y)
переносит в
y
последнее значение, сохраненное на стеке, но только в том случае, когда это значение происходит из регистра
y
; иначе возникает сообщение об ошибке. Модифицируйте имитатор и заставьте его вести себя таким образом. Придется изменить
save
так, чтобы он сохранял имя регистра вместе со значением.
в.
(restore y)
переносит в
y
последнее значение, сохраненное из
y
, независимо от того, какие другие регистры были сохранены и не восстановлены после
y
. Модифицируйте имитатор так, чтобы он вел себя таким образом. С каждым регистром придется связать свой собственный стек. Операция
initialize-stack
должна инициализировать стеки всех регистров.
(controller
(assign continue (label fib-done))
fib-loop
(test (op <) (reg n) (const 2))
(branch (label immediate-answer))
;; set up to compute Fib(n - 1)
(save continue)
(assign continue (label afterfib-n-1))
(save n) ; save old value of n
(assign n (op -) (reg n) (const 1)); clobber n to n - 1
(goto (label fib-loop)) ; perform recursive call
afterfib-n-1 ; upon return, val contains Fib(n - 1)
(restore n)
(restore continue)
;; set up to compute Fib(n - 2)
(assign n (op -) (reg n) (const 2))
(save continue)
(assign continue (label afterfib-n-2))
(save val) ; save Fib(n - 1)
(goto (label fib-loop))
afterfib-n-2 ; upon return, val contains Fib(n - 2)
(assign n (reg val)) ; n now contains Fib(n - 2)
(restore val) ; val now contains Fib(n - 1)
(restore continue)
(assign val ; Fib(n - 1) + Fib(n - 2)
(op +) (reg val) (reg n))
(goto (reg continue)) ; return to caller, answer is in val
immediate-answer
(assign val (reg n)) ; base case: Fib(n) = n
(goto (reg continue))
fib-done)
Рис. 5.12. Контроллер машины для вычисления чисел Фибоначчи
Комментарии отсутствуют.