在改进版文章的最后提到了一个缺点,代码存储和数据存储是同步的、顺序的,并且都是从0x0000开始寻址。代码存储器中的每一条指令对应数据存储器中相同地址的存储单元。
需要解决该问题,我们需要做一个极大的修改。每一个操作码都占用1个字节。现在除了Halt指令外,我希望每一个指令在存储器中占据3个字节空间,其中第一个字节是代码本身,另外两个字节用来存放1个16位存储单元地址。
对于Load指令,后两个字节用来指明数据RAM阵列的一个存储单元,该单元存放的是需要加载到累加器中的字节。
对于Store指令,后两个字节用来指明累加器中的内容将要保存到的存储单元的地址。
对于Add、Add with Carry指令来说,该地址指明的存储单元所保存的是要从累加器中加上的字节。
比如,改进版的加法器对两个数字求和,它的数据RAM和代码RAM需要设置如下:
而修改了指令为3个字节后,代码RAM需要设置为如下:
每一条指令(除了Halt)后两个字节,用来指明数据RAM阵列中16位的存储单元。这3个地址分别是0x0000,0x0001,0x0002,不过它们可以是任意地址。[这就和改进版的加法器很大的区别,改进版的加法器,代码RAM0x0000地址的指令它只能操作数据RAM0x0000的字节,代码RAM的0x0001地址只能操作数据RAM地址0x0001的字节...]
在前面改进版的文章中有提到计算0x76AB和0x232C的加法运算,必须把两个数的地位字节保存到0x0000和0x0001,把高位字节保存到0x0003和0x0004地址,而运算的结果分别保存到0x0002和0x0005。
通过改进,我们可以使用一种更合理的方式来保存着两个操作数以及它的运算结果,它的代码RAM和数据RAM设置为如下:
数据RAM保存的操作和运算结果,它不一定要连续在一起,可以是在任何位置的。可以看到,保存在地址0x4001和0x4003的两个低位字节数先执行加法,其结果保存在0x40005地址处。两个高字节数,保存在地址0x4000和0x4002通过Add with Carry指令相加,其结果保存在地址0x4004。
实现该设计的关键在于把代码RAM的数据输出到3个8位锁存器中,每个锁存器保存该3个字节中的一个。第一个锁存器保存指令代码本身,第二个锁存器保存地址的高字节,第三个锁存器保存地址的低字节。第二个和第三个锁存器的输出构成了数据RAM的16位地址。
注意观察你会发现,我们现在不必再使用2个RAM阵列了。前面介绍的加法器使用两种RAM阵列,一个用来存放指令码,另外一个用来存放操作数据,这种设计使得自动加法器的结构非常清晰和易于使用。但我们现在使用3个字节长的指令格式,第二个和第三个字节用来指明操作数的存储地址,因此就没有必要再使用两个独立的RAM阵列。操作码和操作数可以存放在同一个RAM阵列。
为了实现这个设计,我们需要一个2-1选择器来确定如何对RAM阵列寻址。通常,和前面的方式相同,我们用一个16位的计数器来计算地址。数据RAM的输出连接到3个锁存器,分别用来保存指令代码和其对应操作数的16位地址,该16位地址的输出是2-1选择器的第二种输入,地址被锁存后,可以通过选择器将其作为RAM阵列的地址输入。改进的后电路如下所示:
现在,我们的自动加法器更加智能了,通过扩展指令的长度,可以随意的操作RAM中的任意地址。
如果我们继续改进(比如增加减法,乘法等),可以使我们的加法器越来越强大,同时也会添加越来越多的指令。此时背下指令集合,或者直接使用指令码进行输入则会变得异常困难。因此产生了用借助符号来编写程序。如下面表格所示:
| 操作码 | 代码 | 助记符 |
| Load(加载) | 0x10 | LOD |
| Store(保存) | 0x11 | STO |
| Add(加法) | 0x20 | ADD |
| Add with Carry(进位加法) | 0x22 | ADC |
| Halt | 0xFF | HLT |
例如,对于这样一条语句“把0x1003地址处的字节加载到累加器”,我们可以通过下面的句子代替:
LDA A, [0x1003]
位于助记符右侧的A和[0x1003]称为参数,它们是这个Load指令的操作对象。参数由两部分组成,左边的操作数称为目标操作数(A代表累加器),右边的操作数称为源操作数。方括号[]表示要加载到累加器的不是0x10003,而是保存在0x1003地址的数值。
类似的,把"0x100E地址的字节加到累加器“,则可以简写为:
ADD A, [0x100E]
上面对两个数求和的例子,在可以简写成如下:
LOD A, [0x4001]
ADD A, [0x4003]
STO [0x4005], A
LOD A, [0x4000]
ADC A, [0x4002]
STO [0x4004], A
HLT
这就是一种计算机程序设计语言,称为为汇编语言。每一条汇编语言都对应着机器语言中的某些特定字节。在完成了汇编语言的编写后,将其转换成与之对应的机器语言,然后通过开关把这些机器码输入到RAM阵列中并运行该程序,也就是让累加器执行这些指令。