本系列文章为阅读《Code–隐匿在计算机软硬件背后的语言》后的阅读笔记,仅供参考。
存储器
1、1位锁存器
锁存器(触发器)保存一位数据。
2、8位锁存器
将8个一位锁存器连接成一个8位锁存器。写入命令使能以后,将输入写入锁存器中。
3、选择器控制输出
通过选择器选择是否输出数据,这里的选择器相当于地址。
4、选择器控制输入
通过选择器选择是否输入数据,这里的选择器相当于地址。
5、随机存储器
输入指定地址后,地址满足后,输入写入、输出命令进行存储器的写入、输出。
自动操作
1、手动输入加数
下面是一个8位加法器,通过开关输入数据到加法器中,相加开关闭合会将加法器和锁存器的内容相加。锁存器会将结果保存并通过灯泡显示出来,等待下一个数据通过开关输入进来与锁存器中的数据相加。
但是这样有个问题:如果连续输入100个数字计算其结果,需要不停的拨动开关,拨动错误一个数字就会造成数据计算错误。
2、加入RAM
我们可以将数据记录在RAM中,输入地址和数据,就可以将数据写入至RAM的指定地址中。
将RAM连接到累加器中,计数器控制RAM的寻址,将想要累加的数据放置在RAM的地址从0x0000H~0x0064H中,其它地址的数据都是0,这样就可以从第一个数据开始累加到第100个数据了,但是下图所示结构不会自己停止加法,计数器会一直增加到0xFFFFH,然后再回到0x0000H。相当于继续索引RAM到0xFFFFH,然后再索引到0x0000H。
3、加入操作码
上面的这种方式还是有些太局限了,我想要机器可以按照我的指示一步一步的动作。比如把我计算的数据放在指定位置,而且可以从任意我指定的位置开始计算。
想要仅仅通过将数据输入RAM后,机器按照你的想法运行是不可能的。你需要输入你的想法,将其拆解为执行逻辑。
我们将下图中的逻辑进行拆分:
• 把地址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,用于控制机器的执行操作。这些操作称为操作码。
上面的例子所需要的操作对应的操作码对应如下:
L o a d(装载): 1 0 h
Store (保存) :11 h
Add (加) :2 0 h
Halt ( 停止): F F h
最终构建的自动累加器:
4、操作码中引入地址
上面只引入操作码,还是存在一个问题,如果我想使用以前的计算结果,但是数据RAM和操作码RAM都是按照顺序进行的,所以需要知道以前的计算结果地址,才能对其进行操作。
这里将操作码定义为三个字节,第一个字节是操作码,第二、三个字节是操作的地址。这样可以把指定地址处的数据进行处理。
下图中,单个锁存器从上到下,第一个锁存器保存操作码,第二个锁存器保存高位地址部分,第三个锁存器保存低位地址部分。
5、加入转移指令
上面操作码加入地址后,实现了对已经计算结果的利用,但是在RAM中,程序和数据是混合在一起的,两个程序段之间可能会插入数据段,这时按照指令的顺序执行行不通,需要从程序段1跳转到程序段2执行。
这个跳转过程的硬件实现可以通过重新装载计数器来实现。具体连接如下图所示:
6、升级转移指令
有时候不想运行到转移指令就直接跳转,想要更加灵活的控制,希望满足一定的条件之后才跳转,衍生出以下几种跳转指令:
Jump If Zero (零转移) 3 1 h
Jump If Carry (进位转移) 3 2 h
Jump If Not Zero (非零转移) 3 3 h
Jump If Not Carry (无进位转移) 3 4 h