一、序:

1.1 参考书籍

《编码的奥秘》、《穿越计算机的迷雾》、《计算机系统要素》、《计算机原理教程/姜咏江版》

1.2 参考视频

《计算机科学速成课》、《benblue8位计算机》、《一个8位二进制CPU的设计和实现》

1.3 参考项目

Mhrd 、 Nand2tetris (都是简单的硬件描述语言通过门电路搭建,虚拟机运行)

1.4 辅助工具

Logisim、LogicCircuit 二者用于搭建逻辑电路,Logisim的优点是门电路库齐全,可根据真值表生成电路,LogicCircuit的优点:好看

本教程采用LogicCircuit 作为逻辑模拟工具,所有的相关电路均经过其实验。

1.5 关键词描述

在学习过程中,有一些经验心得值得重点提出,相关部分加黑作为关键字显示。

二、门电路:

2.1 二进制

为了保证信号的易识别性、稳定性等原因,计算机采用二进制作为数制,这样可以用高低电平轻松的区分,从而进行逻辑运算。

二进制的数学运算叫布尔代数,通过布尔代数可以解决逻辑问题,在历史的发展中有很多有意思的事,此处不叙。

2.2 半导体

很多生产制造CPU的公司名里都有半导体这几个字,其原因在于,在后续发展过程中,通过半导体(晶体管、集成电路)替代了继电器、真空管等实现开关,从而进行布尔代数运算,半导体的开关频率远远超过前二者,是一项革命性的发明。

对于半导体的介绍可查阅相关资料,大致为在半导体中掺杂不同的元素,通过量子效应,可以实现一侧导通另一侧不导通,以及通过控制端控制是否导通等(类似二极管、三极管),有了半导体,就可以形成逻辑门

2.3 逻辑门

说到逻辑门,一定要和真值表一起学习,有效的方便理解,最简单的1bit的几个逻辑门如下:

与门

(注:与门,输入都为1 输出为1 输入有1个为0 则输出为0)

或门

(注:或门,输入有一个为1 则输出为1 输入全部为0 则输出为0)

异或

(注:异或门,输入相同为0,不同为1)

其他同或门、或非、非门等介绍不再一一展开,需要时查找相关资料。这些门电路都可以通过半导体(晶体管)实现 ,这里引入第一个关键字概念-抽象

从半导体(晶体管)抽象到门电路,以后通过门电路可以封装成更多内容,抽象让我们能更形象、生动的进行理解、设计。实际上,异或门可以通过其他门电路实现而非半导体(晶体管),这个过程中就用到了抽象的做法(更易实现)

异或门

注:异或门,来源于视频《计算机科学速成课》。

2.4 真值表

简单的逻辑门电路,可以通过真值表自动生成,比如:

真值表

上图是logisim的一个功能,设定了三个输入,1个输出,然后在真值表里输入相关的数值,就可以自动生成电路。

当然,在真值表过多的时候,比如100个输入1个输出,全部输入为输出为1,否则为0,用真值表的形式太繁琐,如果用抽象封装的形式就相比便捷(多个与门),数电计算这块是否有便捷方法,尚未深入学习。

三、组合电路:

3.1 概述

门电路中,第一个大的分类就是组合电路,组合电路的理解需要和时序电路对比,时序电路后面描述。简单的理解,输入后立刻产生输出,和时间没有关系的电路可视为组合电路,比如上面的各种逻辑门以及其组合。

3.2 ALU

作为cpu的一个重要环节,需要有一个计算单元进行计算,这个计算单元叫做ALU,下面我们一步步建立一个简单的ALU(ALU也属于组合电路)

3.2.1 半加器

半加器

之所以叫半加器,是因为此电路中不包含进位,从电路中可知,这符合一个1bit的加法计算。

3.2.2 全加器

这里首次用到前面描述的抽象/封装概念,将半加器封装好后,设计一种新的电路-全加器:

全加器

全加器里包含了进位(进及出),通过全加器,可以形成一个加法器

3.2.3 8位加法器

加法器

8个1bit的全加器正确连接后,即可得到一个8位的加法器

一个好的ALU肯定包含了很多操作,不能只做加法,那么我们有几种方法,一种笨重的办法是分别做好加法、减法、乘法、除法,然后使用时进行选择,另外一种是利用数学的美妙巧妙的实现一种电路能进行多种计算。无论是哪一种,都需要一些配套的门电路进行选择、分配等,下面进行描述。

3.2.4 多路选择器

很多时候,输入有很多个,但输出我们只需要选择其中一个,那么我们需要有一个控制端来决定我们的选择,我们先搭建一个简单的两路、每路1bit的选择器。

1位复用器MUX

可以看出,通过选择端的控制,可以进行输出究竟是IN1还是IN2的选择,多路选择器的英文为MUX

3.2.5 解复用器

和多路选择器很相似,但正好相反,是通过控制端选择将输入输出到哪一端叫做解复用器,英文名叫DEMUX

1位解复用器DeMux

利用前面章节的抽象概念,可以利用当前的1bit 多路选择器/解复用器制作多位,我们分别制作8位的MUX及DeMux

8位MUX

(8位MUX)

8位DEMUX

(8位DEMUX,注:为了节约时间,利用了MUX的布线,翻转了1位demux。LogicCircuit不支持整体电路旋转)

3.2.5 ALU技巧

上文说过,一个好的ALU肯定包含了很多操作,不能只做加法,那么我们有几种方法,一种笨重的办法是分别做好加法、减法、乘法、除法,然后使用时进行选择,另外一种是利用数学的美妙巧妙的实现一种电路能进行多种计算。

我们来看巧妙的实现方案

ALU技巧1

(源自:计算机系统要素)

通过对输入的两组数据,在输入之前进行转换(取反、置零等),结合ALU里的加法器及8位与门,输出后再结合转换(取反等),可以实现图上的功能。下面一张图能更清晰的体现:

ALU技巧2

(源自:计算机系统要素)

可以看出,数学非常的美妙,简单的电路可以实现x-y,x+y,x&y,x|y等功能!

3.2.5 自己动手

我们自己写一个功能强大一点的ALU,其功能要求按照mhrd(一个编程游戏)的要求来

ALU-MHRD

按照以上的要求,结合目前已有门电路,可以按要求得出电路图如下:

ALU-02

可以看出,我们已经制作了一个具备一定功能的ALU!!

四、时序电路:

在以上的电路中,输出只和输入有关,和时间没有关系,但如果,将一个门电路的输入反馈到输入的话,其输出影响了输入,整个电路变得和时间有关!这就是时序电路!

4.1. 反馈或门

反馈或门

上面这个电路很神奇,当一个或门的输出反馈到一个输入时,如果输入曾经为1,那么输出的1反馈到或门的另一个输入,因为或门的特性,使得整个电路的输出会一直保持在1!

对于上面的电路,因为有了反馈,他是随着时间产生变化的,所以叫做时序电路。

通常,时序电路用于做存储器,下面我们逐渐从门电路做到内存。

4.2 RS锁存器

RS锁存器

反馈或门,一旦输入输入曾经为1,那么输出会一直保持1,不算是一个真正的存储,RS锁存器通过两个或非门以及反馈生成了一个可以存储数据的电路。

RS锁存器想实现锁存,其操作复杂,比如输出从0存储到1,需要重新回到0时,还需要操作R端reset,为了降低操作繁琐性,我们可以使用D锁存器

4.3 D锁存器

D锁存器

通过RS锁存器、与门、非门等,构成了D锁存器,当CP为1时,输出=D,当CP为0时 输出保持上一次状态。D锁存器相比RS锁存器简化了操作,但仍有缺陷:要想所存,就得精确控制CP在需要更新输出时保持在1,然后再回到0,有较高的时间要求。

4.4 D触发器

D触发器

利用两个D锁存器、非门,可以组成一个D触发器。从电路中可以看出,当CP为0时,D的输入进入到了第一个D锁存器,当CP变为1后,第一个D锁存器的输出进入了第二个D锁存器,此时整个D触发器的输出为D。CP从0到1的一瞬间,成功的将之前最后一刻的D输入给保存了起来,这就是上升沿触发器。

这里也正好能引入时钟的概念,整个时钟不断的给信号,即CP不断变化。

4.5 1位寄存器

寄存器(1位)

D触发器可以实现存储,但不能选择是否要存储,只要有时钟,那么D触发器的出口就是上升沿前的进口。我们存储数据肯定是希望减少干扰(多个寄存器公用数据总线),所以,在D触发器的基础上再次进行了反馈,这样就可以通过MUX进行选择,是存储反馈的原信息还是新内容。

同时,我们增加一个三态门,用来选择是否可以读出数据。三态门和三极管一样,用控制端来控制是否可以输出。这里用三态门而不用MUX/DeMUX的原因在于:三态门如果控制端为0,则输出相当于是断掉的,而MUX/DeMUX,没有选中的那一路数据位0,还是会影响其他存储器件。

4.6 8位寄存器

有了1位的寄存器,很容易得到8位寄存器

8位寄存器

4.7 RAM内存

当前行业内,通常都以一个8bit作为单元,如果将8位的寄存器组合起来,就可以形成内存。

因为内存里包含的寄存器很多,为了找到每个寄存器,需要给他们确定地址(具体选择哪个寄存器)。

如果按照常规寻址,可以按下图(源自《迷雾》):

内存

和我们之前的不同,这里的每个DB都是1bit,但不妨碍我们理解,这里是通过地址译码器确定该选择哪一行寄存器。

前述说过,我们通常以8个bit作为一个单位,往往不需要寻址到1bit的寄存器上,那样太繁琐,以8bit作为一个单位可以满足需求。所以,上图供参考理解。

实际上在很多个寄存器的组成中,通常采用矩阵的方式寻址,确定了行、列,就可以找到对应的寄存器。

因为内存里包含的寄存器太多,用软件绘制不现实,所以,逻辑电路软件里通常提供封装好的内存供使用。

这里说明:在本文档中,内存是由寄存器组成的,这样便于理解。实际上2021年的内存里用的存储方式尚未查资料,应该与本文的构成有较大出入,但不影响我们的学习以及实践思路。

对应RAM,还有ROM(可读不可写),此处不叙。

4.8. 其他组件

为了保证CPU的整体运行,我们还需要一些其他的组成部分,下面一一介绍

4.8.1 程序计数器(PC)

通常情况下,CPU内部会有一个程序计数器(PC),这个计数器里存放的是内存的地址,然后控制器会根据这个地址找到对应的内存,取出数据,这部分数据是指令。

在不跳转的情况下,CPU控制器会按照顺序执行,之后程序计数器+1,指向下一个地址。在本文的电路设计中,程序计数器拥有 重置、写入数据、加一、读出数据的功能,具体内容见下面的电路图。

PC

说明:

a、使用前应该复位避免杂乱数据

b、寄存器的能否写、能否读全设置成是,再重新对整个电路添加能否写、能否读

c、这个做好的PC具备 复位(置零)、写入指定数据、是否可读、是否+1的功能。

4.8.2 带控制RAM

Logicircuit中,自带的RAM不能控制是否写、读,这里进行调整

内存(带控制)

 

注:内存中的默认数据可以双击修改,但封装好后点击封装好的内存是无法修改的,需要在自建的内存电路中双击RAM进行修改。

4.8.3 带控制ROM

同上,修改内置ROM(因为ROM不能写,所以不需要写的使能)

ROM(带控制)

注意:在实际使用过程中,找到相应的RAM或ROM双击,修改成自己想要的数据

五、控制电路:

控制电路是CPU中最重要,最难理解,也是最神奇的部分,要学习控制电路,我们按照一步一步设计CPU的思路,循序渐进的进行。在此部分内容中,相比前几章会多很多理解上的描述。

5.1 部件组成

我们以已经下面的逻辑图作为分析

CPU01

5.2 部件分析

5.2.1 总线

5.2.1.1 数据总线

在CPU的组成中,有若干个存储单元,他们之间要交错、互相的传递数据,如果每个部件之间都互相连接,则布线很复杂,控制很艰难。所以,经常采用的办法是将所有存储单元的输入输出公用,通过控制每个单元是否可读写来实现从某个存储到另外一个存储。

5.2.1.2 地址总线

CPU中的寄存器数量少,每个寄存器可以单独控制,不存在地址的概念。但对于Rom及Ram来说,他们通过矩阵寻址确定位置,和寄存器不同,内存里的存储单元过多,无法像寄存器那样每个存储单元都单独连线,所以需要寻址。

在本文设计中,ROM和RAM公用地址总线,发射地址的部件包括程序计数器PC以及本章节要做的控制器

5.2.1.3 控制总线

和CPU之外的控制总线不同,CPU内部不存在控制总线,因为控制单元要做的事情就是控制每个部件的是否可读、是否可写、是否复位等,控制信号不能共享,否则无法分别进行控制。

5.2.2 寄存器

5.2.2.1 程序计数器PC

在本文的电路设计中,程序计数器拥有 重置、写入数据、加一、读出数据的功能,具体内容见下面的电路图。

PC

5.2.2.2 通用寄存器

有了内存为什么还需要寄存器?

从我的理解来说,很重要的原因在于:前述说过,内存采用矩阵寻址,所有的内存由地址、可读、可写进行控制,但是,我们不能在一片内存中同时操作两个地址(或者说两个8bit的空间),如果我们需要两个以及以上的数据操作时,如果没有寄存器作为中转缓冲,那么我们甚至实现不了。

5.2.3 ALU

5.2.3.1 ALU

ALU是运算部分,用于进行数值计算,我们设计的ALU只能做加减法等简单运算,如果需要做乘法能内容需要从软件角度去实现,当前主流CPU的ALU功能很强大,远不止加减法。但ALU有了加减法就可以软件角度实现乘除法,进而实现更多功能,但运行的时钟周期会长,效率低。

5.2.3.2 运算寄存器

如果要计算一个数A+另一个数B,按照总线概念,我们无法同时向ALU的输入端同时输出A和B(一个总线),所以我们设置一个输出直连ALU的寄存器以及一个输入直连ALU的寄存器,这样可以通过操作实现ALU计算。

5.3 重中之重

5.3.1 指令如何运行

如果你学过汇编,一定听说过类似 LDA ##,ADD ### 等指令,这是汇编语言,对应着机器码。正是这些机器码让CPU按照我们的思路进行工作。

前面的组合电路和时序电路很好理解,但控制单元要根据程序设定好的指令(机器码)依次执行。这些指令有的是存储、有的是计算,有的是中断,控制单元究竟是如何实现这些指令的?具体做了哪些操作?

5.3.2 最神奇的地方

我们先忘掉指令的具体内容,以功能化的形式来理解:

我们现在需要一个 数据从内存转往寄存器A的指令,那么我们需要:

a、内存的输出打开

b、寄存器的输入打开

换一条指令,我们需要计算两个数据(数据在内存中)的和,那么我们需要

a、内存A输出打开,寄存器A输入打开

b、内存B输出打开,寄存器B输入打开

c、寄存器通过ALU计算(注,不同连线控制明细不同,这里简化)

d、将ALU的输出打开,运算结果寄存器打开

e、运算结果寄存器输出打开,内存输入打开

可以看出,CPU控制器的工作,就是将指令转换成一步一步的微指令(控制其他部件),按照顺序(时间片)依次进行!

软件开发人员所能面对的最底层是汇编指令,但在CPU内部,还有更底层的微指令,通过控制各个部件实现面对开发人员的指令!

5.4 具体实现

5.4.1 单指令执行

我们先从一个简单的LDA ##指令开始:

分解步骤:

步骤一:程序计数器PC允许 输出打开,ROM地址允许输入打开,ROM允许输出打开,指令寄存器的允许输入打开,给一个上升沿信号

[注 释:程序计数器PC输出打开后,其数据立刻传送到了ROM,ROM的寻址读出不需要上升沿信号,所以此时其指令直接传送到了指令寄存器的进口,寄存器存储需要时钟信号,所以给完一个上升沿信号后,指令寄存器存储了第一条指令]

步骤二:以上全关闭,程序计数器PC 允许+1位打开,给一个上升沿信号

[注 释:设置好下一个指令的地址,在上升沿时存储到了程序计数器中,备用]

步骤三:以上全关闭,指令寄存器允许输出打开、ROM允许输入打开、ROM允许输出打开、寄存器A允许输入打开,给一个上升沿信号

LDA ##指令完成!我们现在对微指令的了解更清晰了!每个指令实际上就是分解成若干个微指令按照时间片运行,其控制的是相关部件的是否允许读写!

5.4.2 单指令自动

假设我们的指令系统只有LDA ##这一条指令,那么我们确定了微指令及时间片,我们如何能够自动执行替代手动操作?我们根据手动模拟的性质可以得出两个关键信息:

一、需要一步一步的根据脉冲,按照顺序执行

二、需要根据脉冲,分别产生不同的输出

所以,如果我们有一个能够根据脉冲,按照顺序,生成不同输入(通过组合电路产生不同输出)的组件,就可以达到这个要求。这个东西我们有一个现成的,计数器!

根据计数器的不同数值,通过译码电路根据时间片产生我们所需要的LDA##的输出,我们就实现了单步自动化!

译码电路根据真值表做即可:

单指令

特别注意:控制系统产生的信号要求在时钟的上升沿之前,控制系统本身的计数器变化应错开主系统的上升沿,采用一个非门,使得控制系统倒转脉冲,完美错开!

5.4.3 多指令执行

我们已经有了单指令的自动运行控制器,其原理是:控制器内的计数器 从0000开始根据脉冲增加时, 按照时间片执行了我们制定好的控制输出。

如果我们再加一个条件,当这个条件为A时执行一套流程输出A,为B时执行流程输出B,那么,我们所有的指令就可以根据这个条件自动选择了!我们拥有了多指令CPU控制程序!

这个新的条件我们已经拥有了,他就是指令寄存器!

实际上,这种不同指令,在时间片执行不同动作,仍然是一个真值表!

控制真值表2

5.4.4 执行的流程

无论任何指令,第一步都是使指令寄存器从内存获得指令,要获得指令,必须给定相应的微指令。微指令又是根据指令才有的,所以这里是一个循环。还好,我们有办法:

A、最开始的阶段,为了找到第一条指令,我们的PC里需要有一个地址,通常默认地址为0000(这个软件里,需要特别设置一下,否则数据是混乱的)

B、为了找到第一次控制的信号,我们的指令寄存器、控制单元里的计步器(控制单元计数器)这需要有一个地址,我们也默认为0000(通过默认值解决循环问题)

C、控制单元根据指令寄存器的默认值0000和控制单元计步器的默认值0000,通过设定好的组合电路,得到了第一组控制信号:PC输出打开,ROM输入打开(定义为程序存放在ROM里),ROM输出打开,IR输入打开。因为ROM不需要时钟脉冲就可以获取数据,所以此时的数据已经到了IR的前端,一个脉冲信号后,指令被存放到IR中

D、PC寄存器允许+1打开,并给一个脉冲

E、此时IR已经取到了程序里存放的第一条指令,控制器的计步器也到了0010(从0开始,每一个脉冲+1),此后因为获取了指令,也有计步器的步数,此后的控制动作根据这个指令对应的输出来确定(组合电路)

F、到了该指令的最后一个脉冲时,通过设置好的控制单元计数器(自动加到某一个数后置0),此时的控制单元输入为 IR 0000(指令及步数),设计指令时把每条指令的0000 0001都设计成取指令 +PC,这样,就又可以取到新的指令并运行

G、所以我们知道,尽管每个指令在设计时都是计步器从0000开始到一个设定好的数值后置0,但在实际运行过程中,每条指令的每个微指令都是从0010开始执行(此时才获取到指令),到设定值后又执行0000和0001(0000和0001是取指令和+PC,属于通用部分)载入了下一条指令并+PC。

H、好消息是,组合电路不管你的顺序,你输入是什么,输出就根据设定给什么,所以不影响控制单元运行。

所以,我们的控制单元只需要能够构建这个真值表即可。后续针对真值表对控制单元进行设计

5.5 微程序控制器

5.5.1 微程序是什么

前面我们知道,通过组合电路完全可以实现控制单元的设计,且其速度很快,之所以引入了微程序,是因为组合电路一旦设计好,无法修改,我们软件模拟也不希望碰到这样的情况,所以我们考虑用微程序。

我们需要的是一个能和组合电路实现同样功能的模块,给定不同的输入,根据设定产生不同的输入即可。所以,我们可以用一个ROM来实现。

不同的输入就是ROM的不同地址,不同的输出就是每个地址里存放的不同的内容,这样我们调整起来很方便,也省去了计算组合电路的时间。

同时,对于ROM的类组合电路设计可以通过程序写bin的方式再导入实现,更加方便了我们的设计(本文档中为了更明确原理不采用此种方法)

5.5.2 设计思路

5.5.2.1 简单办法

控制真值表2

从上面这张表可以看出,我们只需要做出对应的输入输出即可。

一个最简单的办法是完全按照真值表来做,比如根据上表,我们可以设计成这样:

0001 0000 是一个地址,地址里存放相应的输出端

0001 0001 是一个地址,地址里存放相应的输出端,以此类推

显然,这样可以实现需求,但有个明显的问题:空间浪费。

比如上表的设计中,采用了一个4位的计步器,但考虑设计中最大的指令步数,当超过12时置0,相当于8位的地址中有2^4*3 个地址是浪费的(高4位地址也应考虑进去,3为16-12-1,步数从0计).

同时,如果指令集不紧凑,不像表中这样从0001 一直加 而是随意分配,那浪费的空间更多。

5.5.2.2 方法升级

为了解决空间浪费的问题,我们很容易想到,通过一个译码电路,把不同的指令和计步器的数值映射到不同的地址即可,这些地址设置好是连续的,这样就能避免空间浪费。

同时,从上面的规律可以看出,计步器肯定是连续的,所以我们的每条指令对应的多个地址(每条指令多个微指令,每个微指令对应一个输出/地址)也是连续的,所以我们很容易想到,这个译码电路只需要对指令进行译码,之后把这个译码后的地址和计步器的地址相加得出最终地址,就能完美的解决问题。

至于这个译码器,为了简化设计,我们仍然采用1个ROM,不同的指令作为该ROM的地址,地址里存放的是CPU控制器ROM的地址,再对应设定好的输出信号。(译码器部分仍存在指令集不紧凑的话就浪费的问题,但这里为了简化设计就采用ROM而非组合电路)

5.5.3 具体设计

需要注意的是,下面的设计并非是最优的,只是采用了我最熟悉的一种方式

5.5.3.1 指令译码器

指令译码器

上图中,指令译码器是通过指令寄存器的输入IR来确定,电路左下角的设计涉及到后面的知识,暂时可以无视,我们看ROM中的内容

指令译码ROM

每个指令的微指令数量是不相同的,但指令共用一个计步器,所以为了迁就最大微指令长度,需要按照最多数量的微指令进行步数设计,本项目中共设计了从0到C合计13个长度。每个指令需要执行的步骤统一设定为13个,当某个指令无需这么多步骤时,剩余的步骤不动作即可。

所以我们可以得出,在本项目的CPU控制器里,采用ROM的形式,每个指令占用13个存储,所以我们的指令译码器分别给不同指令寻找空间时,保持13这个长度避免混淆或浪费,所以,在译码器的ROM里,可以看到:

指令寄存器默认值0000时,对应的地址是0000,表示初始从CPU控制器ROM的0000中找到位置,并合计有13个位置(13个微指令)。所以存储0001指令的地址为0D,并以此类推。

5.5.3.2 CPU控制器输入

指令译码器2

传递给CPU控制器ROM的地址是变化的,这样ROM根据不同地址按照设定好的微指令进行不同输出,这个变化是由指令译码器的输出和一个计数器共同生成,当计数器超过0C时自动置零。

5.5.3.3 CPU控制器存储

CPU控制器

在CPU控制器中,可以看出,0到0c是默认的微指令动作,从0D开始到19是第一条指令的微指令动作,并以此类推。

到这里,我们有了一个清晰的流程,指令根据一个ROM译码器翻译出微指令的首地址,并根据计步器进行偏移,之后通过一个ROM根据输入的不同地址产生了不同的输出信号执行了微指令。

上图中的数值比如00580002,是考虑到控制端要足够多,使用的是32位数据位宽的ROM,这个数据分别控制了寄存器、ROM等。这样,我们的指令设计就可以在这个ROM中进行,只需更改数据即可。

5.6 写一个程序

5.6.1 简单加法

我们设定一个程序做简单的加法,其步骤如下:

a、LDA 立即数05

b、LDB 地址数 0F

c、把A+B传给A

d、A寄存器打开输出

5.6.2 指令设计

根据需求,我们需要有 LDA立即数、LDB 地址数等指令,这些指令根据需求分别设计不同的微指令操作,每个指令都按照13次进行(无需要时置0).

lda

上图是我已经设计好的一些指令,这些数据最终存放在了CPU控制器的ROM中,每个指令的首地址根据译码器ROM确定(见5.5.3.1)。

5.6.2 写程序

根据我们设定好的指令及要求,我们的程序为:

程序

0205 为LDA 立即数05

05 00 0F 为LDB 地址0F中的内容(此例中为20)

04为A+B并存放到A,03为A寄存器打开输出。

运行后,我们发现A寄存器的结果为05+20=25

可以看到,每个指令的长度是不一样的,在指令设计中就已经确定(微指令不同)

5.7 其他

截至目前位置,我们已经做好了一个简单的CPU,但对于条件判断、中断等设计还没有加进来(尤其条件判断,是决定是否图灵的一个标准),后续有机会我们慢慢补充。