灯下 登录
计算机科学 / SICP / 5.1.1 A Language for Describing Register Machines

Exercise 5.2 · 习题

Exercise 5.2: Use the register-machine language
to describe the iterative factorial machine of Exercise 5.1.

Actions

Let us modify the GCD machine so that we can type in the numbers
whose GCD we want and get the answer printed at our terminal. We
will not discuss how to make a machine that can read and print, but will assume
(as we do when we use read and display in Scheme) that they are
available as primitive operations.

Read is like the operations we have been using in that it produces a
value that can be stored in a register. But read does not take inputs
from any registers; its value depends on something that happens outside the
parts of the machine we are designing. We will allow our machine’s operations
to have such behavior, and thus will draw and notate the use of read
just as we do any other operation that computes a value.

Print, on the other hand, differs from the operations we have been using
in a fundamental way: It does not produce an output value to be stored in a
register. Though it has an effect, this effect is not on a part of the machine
we are designing. We will refer to this kind of operation as an

action. We will represent an action in a data-path diagram just as
we represent an operation that computes a value—as a trapezoid that contains
the name of the action. Arrows point to the action box from any inputs
(registers or constants). We also associate a button with the action. Pushing
the button makes the action happen. To make a controller push an action button
we use a new kind of instruction called perform. Thus, the action of
printing the contents of register a is represented in a controller
sequence by the instruction

(perform (op print) (reg a))

Figure 5.4 shows the data paths and controller for the new GCD
machine. Instead of having the machine stop after printing the answer, we have
made it start over, so that it repeatedly reads a pair of numbers, computes
their GCD, and prints the result. This structure is like the driver
loops we used in the interpreters of Chapter 4.

SVG

Figure 5.4: A GCD machine that reads inputs and prints results.

练习 5.2:用寄存器机器语言描述练习 5.1 中的迭代型阶乘机器。

动作

让我们修改 GCD 机器,使其能够读入我们想求最大公约数的两个数,并在终端打印出结果。我们不讨论如何使机器具备读写能力,而是假设(正如在 Scheme 中使用 read 和 display 时一样)它们作为基本操作已经可用。

read 与我们此前使用的操作类似,它产生一个可以存入寄存器的值。但 read 不从任何寄存器获取输入;其值取决于发生在我们所设计机器之外的某件事情。我们将允许机器的操作具有这种行为,因此对 read 的使用方式与其他计算值的操作相同——用同样的方式绘图和标注。

而打印操作则在根本上不同于我们此前使用的操作:它不产生存入寄存器的输出值。尽管它有副作用,但这种副作用并不作用于我们所设计机器的任何部分。我们将这类操作称为动作 (action)。在数据通路图中,我们用与表示计算值的操作相同的方式来表示动作——用一个包含动作名称的梯形表示。箭头从任何输入(寄存器或常量)指向该动作框。同样,我们为动作关联一个按钮,按下按钮即触发动作。为使控制器按下动作按钮,我们使用一种新的指令 perform。因此,打印寄存器 a 内容的动作在控制器序列中表示为以下指令:

(perform (op print) (reg a))

图 5.4 展示了新 GCD 机器的数据通路和控制器。机器打印结果后不会停机,而是重新开始,反复读入一对数、计算其最大公约数并打印结果。这种结构类似于我们在第 4 章的解释器中使用的驱动循环。

SVG

图 5.4:一台读入输入并打印结果的 GCD 机器。

Racket #lang sicp
(perform (op print) (reg a))