Working on 5.11
parent
8a2ce473be
commit
5b7e799f2f
|
@ -210,10 +210,10 @@
|
||||||
(goto (label fib-loop)) ; perform recursive call
|
(goto (label fib-loop)) ; perform recursive call
|
||||||
afterfib-n-1 ; upon return, val contains Fib(n - 1)
|
afterfib-n-1 ; upon return, val contains Fib(n - 1)
|
||||||
(restore n)
|
(restore n)
|
||||||
;(restore continue)
|
;(restore continue) ; uneeded restore
|
||||||
;; set up to compute Fib(n - 2)
|
;; set up to compute Fib(n - 2)
|
||||||
(assign n (op -) (reg n) (const 2))
|
(assign n (op -) (reg n) (const 2))
|
||||||
;(save continue)
|
;(save continue) ; uneeded continue
|
||||||
(assign continue (label afterfib-n-2))
|
(assign continue (label afterfib-n-2))
|
||||||
(save val) ; save Fib(n - 1)
|
(save val) ; save Fib(n - 1)
|
||||||
(goto (label fib-loop))
|
(goto (label fib-loop))
|
||||||
|
|
|
@ -103,38 +103,84 @@
|
||||||
(start triple-inc-machine)
|
(start triple-inc-machine)
|
||||||
(assert (get-register-contents triple-inc-machine 'a) 11)
|
(assert (get-register-contents triple-inc-machine 'a) 11)
|
||||||
|
|
||||||
(display "\nex-5.11\n")
|
(display "\nex-5.11 - stack-behavior\n")
|
||||||
|
|
||||||
;Exercise 5.11. When we introduced save and restore in section 5.1.4, we
|
; a
|
||||||
;didn't specify what would happen if you tried to restore a register that was
|
(define fib-machine
|
||||||
;not the last one saved, as in the sequence
|
(make-machine
|
||||||
|
'(n val continue)
|
||||||
|
(list (list '< <) (list '- -) (list '= +) (list '+ +))
|
||||||
|
'(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)
|
||||||
|
;; set up to compute Fib(n - 2)
|
||||||
|
(assign n (op -) (reg n) (const 2))
|
||||||
|
(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 n) ; ex-5.11 - save one instruction
|
||||||
|
(assign val ; Fib(n - 1) + Fib(n - 2)
|
||||||
|
(op +) (reg val) (reg n))
|
||||||
|
(restore continue)
|
||||||
|
(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)))
|
||||||
|
|
||||||
;(save y)
|
; We can replace ((assign n (reg val)) (restore val)) with (restore n) because
|
||||||
;(save x)
|
; we add up n and val anyway. It does not matter which is in which register.
|
||||||
;(restore y)
|
|
||||||
|
|
||||||
;There are several reasonable possibilities for the meaning of restore:
|
(set-register-contents! fib-machine 'n 8)
|
||||||
|
(start fib-machine)
|
||||||
|
(display "a. ")
|
||||||
|
(assert (get-register-contents fib-machine 'val) 21)
|
||||||
|
|
||||||
;a. (restore y) puts into y the last value saved on the stack, regardless of
|
; b.
|
||||||
;what register that value came from. This is the way our simulator behaves.
|
(define stack-content car)
|
||||||
;Show how to take advantage of this behavior to eliminate one instruction from
|
(define stack-register cadr)
|
||||||
;the Fibonacci machine of section 5.1.4 (figure 5.12).
|
|
||||||
|
|
||||||
;b. (restore y) puts into y the last value saved on the stack, but only if
|
(define (make-save inst machine stack pc)
|
||||||
;that value was saved from y; otherwise, it signals an error. Modify the
|
(let ((reg (get-register machine
|
||||||
;simulator to behave this way. You will have to change save to put the register
|
(stack-inst-reg-name inst))))
|
||||||
;name on the stack along with the value.
|
(lambda ()
|
||||||
|
(push stack (list (get-contents reg) reg))
|
||||||
|
(advance-pc pc))))
|
||||||
|
|
||||||
|
(define (make-restore inst machine stack pc)
|
||||||
|
(let ((reg (get-register machine
|
||||||
|
(stack-inst-reg-name inst))))
|
||||||
|
(lambda ()
|
||||||
|
(let ((stack-element (pop stack)))
|
||||||
|
(if (not (eq? reg (stack-register stack-element)))
|
||||||
|
(error "restore from different reg -- MAKE-RESTORE"
|
||||||
|
(reg 'name?)
|
||||||
|
((stack-register stack-element) 'name?)))
|
||||||
|
(set-contents! reg (stack-content stack-element))
|
||||||
|
(advance-pc pc)))))
|
||||||
|
|
||||||
|
(display "b. [implemented]\n")
|
||||||
|
|
||||||
|
(display "c. ACTIVE!!!\n")
|
||||||
;c. (restore y) puts into y the last value saved from y regardless of what
|
;c. (restore y) puts into y the last value saved from y regardless of what
|
||||||
;other registers were saved after y and not restored. Modify the simulator to
|
;other registers were saved after y and not restored. Modify the simulator to
|
||||||
;behave this way. You will have to associate a separate stack with each
|
;behave this way. You will have to associate a separate stack with each
|
||||||
;register. You should make the initialize-stack operation initialize all the
|
;register. You should make the initialize-stack operation initialize all the
|
||||||
;register stacks.
|
;register stacks.
|
||||||
|
|
||||||
; Extend the message-passing interface to the machine to provide access to
|
|
||||||
; this new information. To test your analyzer, define the Fibonacci machine
|
|
||||||
; from figure 5.12 and examine the lists you constructed.
|
|
||||||
|
|
||||||
(display "\nex-5.12\n")
|
(display "\nex-5.12\n")
|
||||||
|
|
||||||
; (display "\nex-5.13\n")
|
; (display "\nex-5.13\n")
|
||||||
|
|
|
@ -29,6 +29,7 @@
|
||||||
(cond ((eq? message 'get) contents)
|
(cond ((eq? message 'get) contents)
|
||||||
((eq? message 'set)
|
((eq? message 'set)
|
||||||
(lambda (value) (set! contents value)))
|
(lambda (value) (set! contents value)))
|
||||||
|
((eq? message 'name?) name)
|
||||||
(else
|
(else
|
||||||
(error "Unknown request -- REGISTER" message))))
|
(error "Unknown request -- REGISTER" message))))
|
||||||
dispatch))
|
dispatch))
|
||||||
|
|
Loading…
Reference in New Issue