现在我们就主要来介绍输入设备和输出设备。根据冯诺依曼结构的要求,计算机要执行的程序首先需要通过输入设备传送到存储器中,那么这个过程是如何完成的呢?就让我们来看一看冯诺依曼这个时代所用的计算机。当时编写程序并不像我们现在这样方便程序员需要在长长的纸带上打上小孔若干个小孔就代表一条指令,那么将这样穿孔的纸带送入计算机后计算机可以通过有孔或者没孔的区别转换成0和1的二进制信息。从而识别出程序员所表达的指令。经过运算以后计算机将通过电传打字机将输出的结果打印在纸带上。这样人们就可以通过观察,分析纸带上的穿孔情况来判断输出的结果。那这样的计算机的输入和输出与冯诺依曼结构又是如何对应呢?我们先来想,这个穿孔纸带应该对应着什么。是对应着输入设备吗?其实纸带上的信息还是要通过特定设备才能被识别。所以穿孔纸带应该是作为输入设备的来源。其实在冯诺依曼结构中,对此也进行了规定。除了输入设备I,输出设备O。冯诺依曼结构中还规定了外部的记录介质,称为R。实际上穿孔纸带就是这种外部记录介质。它可以静态的存储计算机所需的信息。不会因为计算机断电而丢失。
那好,刚才提到了电传打字机。有属于哪个类别呢?其实电传打字机应该属于输出设备的一种。电传打字机会将计算机的运行结果打印到纸带上,所以电传打印机输出的纸张也可以认为是外部记录介质R。除了纸张,还可以用带磁性的材料存储信息。类似于我们现在使用的硬盘。那么硬盘应该属于输入设备、输出设备还是外部记录介质?首先我们看硬盘是可读又可写的。所以我们至少应该是这么连接的,而硬盘中的信息在断电之后是不会丢失的所以硬盘也具有外部记录介质R的特性。所以严格说来,硬盘里记录信息的磁片才是真正的外部记录介质。而硬盘当中还会有其他的控制芯片可以认为是输入或者输出设备的一部分。在通常情况下我们没有必要划分的那么苛刻可以认为硬盘就是属于外部记录介质R这种类型。
那么现在的计算机当中很多设备都会既有输入的功能又有输出的功能。所以通常我们会这么来画这个结构图将输入设备和输出设备化成一个部件既有输入的功能又有输出的功能。现在,我们就来看如何在我们的模型机上添加这样一个输入输出设备。如果直接考虑硬盘这样的设备,就太过复杂了。我们希望现在模型机上添加一个简单的输入输出设备。说到简单的设备,我们先来看一个小故事。罗伯茨造出的计算机是牛郎星8800,它内部主要有两块集成电路。一是intel8080微处理器;第二是一块256字节的存储器。那么他在面板上提供了简单的输入输出靠手来上下拨动一些开关进行编程输入,计算机在经过运算之后,会将计算的结果通过这些小灯泡进行显示。很多电子计算机的爱好者和团体都争相采购牛郎星8800型计算机以进行分析研究。其中就有乔布斯和他的搭档沃兹尼亚克。他们一方面认真学习了这台计算机精巧的内部结构,另一方面,他们也对如此简陋的输入输出感到非常不满意。在这样的影响下,同一年,他们就很快设计完成了自己的产品。就是苹果I型个人计算机。这台计算机有键盘的输入并且可以连接电视机作为显示器输出。这也是苹果公司的第一个产品。
那好,我们回来看如何在模型机上添加输入输出设备。我们不需要那么复杂的输入输出。现在,我们只想添加一个类似于牛郎星8800型计算机的输入和输出也就是手动的开关和小灯泡的显示。我们可以设想有一个类似于存储器结构的输入输出芯片。它内部有两个单元,每个单元都有自己的地址。我们这里设定的是1110和1111这两个地址。他们和存储器里面的地址都不相同。因此可以相互区分。那这个输入输出如何与计算机的其他部分相连呢?我们知道CPU是通过控制总线,地址总线和数据总线与存储器相连的。现在我们就来对此做一个简单的改造。将控制总线分别连接到存储器和输入输出芯片的控制逻辑地址总线也同样分别连到这两个部件。数据总线也是如此。然后我们将输入输出设备中其中一个单元连接到手动的开关,这个单元中有8个比特每个比特连接一个开关。当开关比东到上方时,对应的位就会被设置为1。开关拨动倒下方时对应的位就会被设置为0。另外一个存储单元接到8个小灯泡,当这个单元中的比特为高电平时,对应的小灯泡就会亮起。如果这个比特是低电平时,对应的小灯泡就会熄灭。那现在我们就有一个非常简单的输入输出。
那这个输入输出在计算机上是如何工作的呢?我们通过一个简单的输入的场景来进行学习。我们假设这时候CPU和存储器已经开始工作了。其中一条指令就是要读取这8个手动开关的状态。假设现在8个手动开关的状态是前三个开关被拨到高位,后五个开关被拨到低位,那地址为1111这个单元中所保存的2进制信息就是这样的。那CPU如何能读取到这个输入信息呢?我们首先来看地址总线。CPU会将地址总线上,地址总线上所发的地址是1111,那么在总线上会有一些简单的电路进行地址的识别,可以发现这个地址应该发到输入输出部件,而不是存储器。与此同时,我们来看控制总线。CPU会发出读的信号,从而告知输入输出设备目前是要进行一个读操作,那输入输出设备的控制逻辑和地址译码器就会从地址为1111的单元中读出相关的信息,送到数据总线上。数据总线会将这个数据最终送回到CPU中,这样就完成了输入信息的读取工作。此后,CPU可以对这个输入的数据进行运算,或者根据这个数据调整后面的执行的行为,也可以把这个数暂时保存到存储器中以备后来的使用。那这样就是一个输入的简单场景。
然后我们再来看一个输出的简单场景。既然是输出,我们就要给出输出单元对应的地址,在这里是1110,与刚才一样,地址总线会将这个地址传送到输入输出设备,同时,控制总线上回给出写的控制信号,然后在数据总线上,会给出我们想输出的数据,这里设为11001100。然后输入输出设备就会根据来自总线的信息判断出要向地址为1110的单元写入数据11001100,此后就可以完成写入的操作。当写入操作完成后,对应的小灯泡就接收到了高低不同的电压,我们就会发现1所对应的灯泡亮起,0所对应的灯泡熄灭。这就是一个输出的简单场景。