5.1 设计寄存器机器

5.1 设计寄存器机器
为了设计一个寄存器机器,我们必须设计它的数据路径(寄存器和操作)
和序列化这些操作的控制器。为了演示一个简单的寄存器机器的设计,
让我们看一看欧拉的算法,就是用于计算两个整数的最大公约数的。
正如我们在1.2.5部分看到的那样,欧拉算法能被用一个迭代的流程执行。
如下面的程序:

(define (gcd a b)
   (if (= b 0)
     a
    (gcd b (remainder a b))))

一个机器执行这个算法,必须有A和B这两个输入值,所以让我们假定这些数存储于有这些名称的
寄存器中。基本的操作有检测寄存器B的值是否是0,和计算 寄存器A的值除以寄存器B的值得到
的余数。计算余数的操作是一个复杂的流程,但是暂时假定我们有一个原生的设备用于计算余数。
在求最大公约数的每一轮计算中,寄存器A的内容必须被替换成寄存器B的内容,寄存器B的内容
必须被替换成寄存器A的旧的内容除以寄存器B的旧的内容的余数。如果这些替换能同时进行,
就方便了,在我们的寄存器机器的模型中,我们假定在一个步骤中,仅有一个寄存器被允许赋一个
新值 。为了完成替换的操作 ,我们的机器使用了第三个寄存器,我们称为T的临时寄存器。(首先,
余数被放在T,然后,B的内容放在了A,最后,放在T中的余数被放在了B。

通过使用在图5.1中显示的数据路径图,我们能够演示这个机器需要的寄存器和操作。
在这个图中,寄存器A,B,T 用矩形表示。每一次向一个寄存器赋一个值时都被显示成一个箭头
后面跟着一个X,从数据的源,指向寄存器。我们能够认为X是一个按钮,当它被按的时候,
允许数据值从它的源头流向设定好的寄存器。按钮旁边的标签是我们引用按钮时的名称。
这个名是随意的,并且能被写成有意义的值(例如,A<-B的含义是按了按钮后,把寄存器B的
内容赋给寄存器A)。对于寄存器的数据的源可能是另一个寄存器(在A<-B的赋值中),
也可能是一个操作的结果值(在T<-R的赋值中) 或者是一个常数(一个内嵌的值,不能被改变的值,
在数据路径图中被表示为一个三角形包含着一个常数)。

从常数与寄存器的内容来计算值的操作在数据路径图中,被表示为一个包含着操作的名称的梯形。
例如,在图5.1中,一个标识为REM的盒子表示的是一个操作,用来计算寄存器A,B的值的余数。
没有按钮的箭头从输入的寄存器和常数指向这个盒子,并且用箭头把操作的输出值指向了目标寄存器。
一个测试被表示成一个包含着测试名称的圆圈。例如,我们的求最大公约数的机器,有一个测试寄存器
B的内容是否是零的操作。一个测试也有从输入寄存器和常数来的箭头,但它没有输出的箭头,
它的值能被控制器使用,而不是数据路径。总之,数据路径图显示了机器所需要的寄存器和操作和
它们必须被如何地连接起来。如果我们把箭头视作电线,X按钮视作开关,那么数据路径图就
非常像能用电子元件组装起来的机器的电路图。

为了数据路径能够实际地计算最大公约数,所有的按钮必须被按照正确的顺序依次按下。
用图5.2中的控制器图来描述这种序列。控制器图的元素显示出数据路径的组件应该被如何地操作。
在控制器图中的矩形框标识着数据路径中的按钮被按下,箭头描述了从一个步骤到下一个步骤的序列。
在控制器图中的菱形框则表示一个判断条件。最终执行这两个序列箭头中的哪一个,取决于
在菱形框中标识的数据路径的测试的值。我们能够用物理上的类似现象对控制器进行解释:
可以把控制器的图想象成一个有弹子在游荡的迷宫。当弹子滚入一个盒子,它就按到了按钮上。
当弹子滚到一个条件结点时,它离开结点的路径取决于测试条件的结果。把数据路径与控制器图结合起来
就完整地描述了计算最大公约数的机器。我们启动控制器(滚动起来的弹子)在标识为开始的地方,
然后把数据放在寄存器A和B中。 当控制器到达了终点时,我们将在寄存器A中找到最大公约数的值。

练习5.1  设计一个寄存器机器,来计算斐波那些数,使用由如下的程序指定的迭代的算法,
并且为这个机器 ,画出数据路径图和控制图。

(define (factorial n)
    (define (fact-iter product counter )
     (if (> counter   n)
               product
 (fact-iter  (* counter product)
            (+ counter 1)
   )
     )
   )
   (fact-iter 1 1))

猜你喜欢

转载自blog.csdn.net/gggwfn1982/article/details/82984650
5.1