5.1.2 在机器设计中的抽象
我们将经常定义一个机器包含着原生的操作,这个原生的操作实际上可能是非常复杂的。
例如在5.4和5.5部分中,我们把SCHEME的环境操作当成上原生的操作。这种抽象是非常有价值的。
因为它允许我们忽略机器的部分的细节,为了能够集中精力于设计的其它方面。
事实是我们能够隐藏起很多的复杂度,然而这并不意味着机器的设计是非现实的。
我们总是能够用更简单的原生操作来实现这个复杂的原生操作。
考虑GCD机器。机器有一个指令计算寄存器A和B的内容的余数,并且把结果赋值给寄存器t.
如果我们要组装GCD机器没有使用一个原生的余数操作,我们必须指定如何用简单的操作来
计算余数,例如减法。的确,我们能够写一个scheme程序来以如下的方式找到余数:
(define (remainder n d)
(if (< n d)
n
(remainder (- n d) d))
)
在GCD机器的数据路径中我们能因此把求余数的操作替换成一个减法与一个比较测试的操作。
图5.5显示了这个更详尽的机器的数据路径和控制器。
指令 (assign t (op rem) (reg a) (reg b)) 在GCD的控制器定义被替换成包括了一个循环的指令
序列,如图5.6所示。
(controller
test-b
(test (op =) (reg b) (const 0))
(branch (label gcd-done))
(assign t (reg a))
rem-loop
(test (op <) (reg t) (reg b))
(branch (label rem-done))
(assign t (op -) (reg t) (reg b))
(goto (label rem-loop))
rem-done
(assign a (reg b))
(assign b (reg t))
(goto (label test-b))
gcd-done
)
图5.6 在图5.5中的GCD机器的控制器指令序列。
练习5.3 设计一个机器来使用牛顿法计算平方根,如1.1.7部分中的描述那样。
(define (sqrt x)
(define (sqrt-iter guess)
(if (good-enough? guess)
guess
(sqrt-iter (improve guess))
))
(define (good-enough? guess)
(< (abs (- (square guess) x)) 0.0001))
(define (improve guess)
(average guess (/ x guess)))
(sqrt-iter 1.0)
)
通过假定good-enough? 和improve操作是作为原生的操作可直接利用的。然后显示
如何用算术操作实现它们。描述sqrt机器设计的每个版本,通过画数据路径图和以寄存器
机器语言写出它的控制器定义。