《编码的奥秘》第十七章 自动操作

这是最精彩的一章。

 

先存再加

前面使用累加器来计算求和运算的电路为:

《编码的奥秘》第十七章 自动操作

使用这个设备时,必须首先按下清零开关使锁存器的存储内容清零,然后用开关来输入第一个数字。加法器简单地把这个数字与锁存器输出的零相加,因此其结果就是你刚输入的数字。按下相加开关可在锁存器中保存该数并且通过灯泡显示出来。现在从开关上输入第二个数,加法器把这个数与存储在锁存器中的数相加,再按下相加开关把总和存储在锁存器中并通过灯泡显示出来。通过这种方法,你可以加上一串数字并显示出运算总和。

上面这个加法机存在的最大问题已经相当明显:如果想把1 0 0个二进制数加起来,你就得坐在加法机前耐着性子输入每一个数字并累加起来。当你完成时,却发现有两个数字是错误的,你只好又重复全部的工作。

 

如果你向R A M阵列中输入1 0 0个二进制数字,而不是直接输入到加法机中,那么进行数据修改会容易得多。

解决思路:先把要计算的数保存到RAM里面。计算结果也要保存到RAM里面。

 

《编码的奥秘》第十七章 自动操作

先通过控制面板把数据输入到RAM中,再按clear清零,然后开启振荡器,进行自动加法计算。

坐着等结果吧。。。

 

但问题是,什么时候停呢?除了加法,还想干点别的呢?

 

指令

不是让自动加法器只做一件事情—在最初的加法器中,只是把R A M地址中的内容加到称为累加器的8位锁存器中—实际上是让它做四件不同的事。

要做加法,需先从存储器中传送一个字节到累加器中,这个操作叫作L o a d(装载)

第二项所要执行的操作是把存储器中的一个字节加( A d d )到累加器中。

第三项是从累加器中取出结果,保存( S t o r e )到存储器中。

最后,需要有一些方法使自动加法器停止( H a l t )工作。

 

目标:假设我们希望先把三个数字加在一起,然后把另两个数字加在一起,最后再把另外三个数加在一起。我们可能会将这些数字存储在从地址0 0 0 0 h开始的R A M阵列中,存储器的内容如下所示:

《编码的奥秘》第十七章 自动操作

详细说来,让自动加法器所做的工作如下所示:
• 把地址0 0 0 0 h中的数装载到累加器中
• 把地址0 0 0 1 h中的数加到累加器中
• 把地址0 0 0 2 h中的数加到累加器中
• 把累加器中的数保存到地址0 0 0 3 h中
• 把地址0 0 0 4 h中的数装载到累加器中
• 把地址0 0 0 5 h中的数加到累加器中
• 把累加器中的数保存到地址0 0 0 6 h中
• 把地址0 0 0 7 h中的数装载到累加器中
• 把地址0 0 0 8 h中的数加到累加器中
• 把地址0 0 0 9 h中的数加到累加器中
• 把累加器中的数保存到地址0 0 0 A h中
• 停止自动加法器的工作

 

改进:

数据和指令分开

使用两个RAM,分别存储数据和指令

《编码的奥秘》第十七章 自动操作

指令操作码为:

《编码的奥秘》第十七章 自动操作

指令和数据RAM里面的内容分别为:

《编码的奥秘》第十七章 自动操作    《编码的奥秘》第十七章 自动操作

电路为:

《编码的奥秘》第十七章 自动操作

 

指令扩展

还可以扩展其他指令,比如增加“减法”运算:

《编码的奥秘》第十七章 自动操作

要计算:0x56 + 0x2A - 0x38

《编码的奥秘》第十七章 自动操作

数据位数扩展

如何计算16位数的加法?把低8位和高8位分开存放,分别计算,并考虑进位。这时就是再增加一条指令:进位加。

比如,计算:0x76AB + 0x232C

《编码的奥秘》第十七章 自动操作

使用同样的办法,甚至可以计算32位数的加法,比如计算:0x7A892BCD + 0X65A872FF

《编码的奥秘》第十七章 自动操作

新的问题又出现了:

  • 存储数据不连续;
  • 代码RAM和数据RAM的空间必须一一对应,不能在随后的计算中重复利用计算结果;

 

再进一步改进:

操作码和操作数混合编排

除了“停止”代码外,现在希望每条指令在存储器中3个字节,其中第一个字节为代码本身,后两个字节存放一个1 6位的存储器单元地址。对于装载指令来说,其地址指明数据在数据R A M阵列中的存储单元,该存储单元存放要装载到累加器中的字节;对于加法、减法、进位加法和借位减法指令来说,地址指明要从累加器中加上或者减去的字节的存储单元;对于保存指令来说,地址指明累加器中的内容将要保存的存储单元。

 

比如计算:

更改前:0x4A + 0xB5:

《编码的奥秘》第十七章 自动操作

改进后:

《编码的奥秘》第十七章 自动操作

每条指令(除了“停止”)后跟2个字节,用来表示在数据R A M阵列中的1 6位地址。这三个地址碰巧为0 0 0 0 h、0 0 0 1 h和0 0 0 2 h,它们可以是任何其他地址

比如,4000H4002H位置的内容相加,保存到4004H处。

《编码的奥秘》第十七章 自动操作    《编码的奥秘》第十七章 自动操作

这里出现了“间接寻址”的概念了。

 

将指令和数据合并到同一个RAM中

经过上述改进,现在有条件可以把指令和数据输入到一个RAM中了。

比如,把两个8位数相加,再减去第三个数:

《编码的奥秘》第十七章 自动操作

需要增加“2-1选择器”来确定如何寻址RAM陈列:

《编码的奥秘》第十七章 自动操作

R A M数据输出仍然连接到用来锁存指令代码及其2字节地址的三个锁存器上,但它们的1 6位地址是2 - 1选择器的第二个输入。在地址被锁存后,选择器允许被锁存的地址作为R A M阵列的地址输入。

 

跳转指令

通常,自动加法器顺序寻址R A M阵列。转移指令改变其寻址模式,而从R A M阵列的某个特定地址开始寻址。这样的命令有时也叫分支( b r a n c h)指令或者g o t o指令,即“转到另外一个地方”的意思。

《编码的奥秘》第十七章 自动操作

更有用的是“条件跳转”:

《编码的奥秘》第十七章 自动操作

《编码的奥秘》第十七章 自动操作

有了条件判断和分支跳转,于是就有了“顺序”、“分支”和“循环”,于是就有了软件世界。。。

 

汇编语言

使用助记符来代替二进制代码:

《编码的奥秘》第十七章 自动操作

写出来的代码就是汇编程序:

《编码的奥秘》第十七章 自动操作        《编码的奥秘》第十七章 自动操作