计算机那点事儿~

软件和网站开发以及相关技术探讨
头像
ubuntu777
帖子: 249
注册时间: 2007-03-28 18:40

Re: 计算机那点事儿~

#46

帖子 ubuntu777 » 2015-07-12 21:21

今天要学习一个貌似很复杂。其实并不是特别难懂的东西:多路数据选择器(Multiplexer)。
这个东西可以用来从多个不同的输入值中选择想要的那一个值来做为输出值。
大家先来看一个图。16路到1路多路数据选择器。
用ABCD来选择D0-D15中的一个,做为Y端的输出值。
multiplexer_00.jpg
ABCD端是控制端。D0-D15共16个输入端。输出端只有一个,就是Y。其它电路符号都学过。非门电路、多路输入的与门电路,多路输入的或门电路。接Y端的就是有16个输入端的或门电路。

ABCD端,相当于4位的二进制数。从0000到1111共16个不同的值。通过这个值的变化来选择D0-D15其中的一个做为输出结果。具体怎么选择的,电路符号和接线方法已经画出来了,逻辑门电路的功能也学过。大家自己去分析一下。

多路数据选择器还可以通过选择数据的办法,根据控制端的数据得到需要的输出端的值。设计出满足特定真值表功能的电路。
比如想要下面这个真值表。看图。
multiplexer_01.jpg
multiplexer_01.jpg (13.94 KiB) 查看 13785 次
把这个16对1的多路数据选择器的输入端设置为以下值就可以。
看图:
multiplexer_02.jpg
multiplexer_02.jpg (9.21 KiB) 查看 13785 次
שְׁמַע יִשְׂרָאֵל יְהֹוָה אֱלֹהֵינוּ יְהֹוָה ׀ אֶחָֽד׃
וְאָהַבְתָּ אֵת יְהֹוָה אֱלֹהֶיךָ בְּכׇל־לְבָבְךָ וּבְכׇל־נַפְשְׁךָ וּבְכׇל־מְאֹדֶֽךָ׃
l10x
帖子: 447
注册时间: 2008-06-23 19:31
系统: debian+fedora+win10

Re: 计算机那点事儿~

#47

帖子 l10x » 2015-07-13 9:25

不错,收藏了。 :em38 :em38
头像
ubuntu777
帖子: 249
注册时间: 2007-03-28 18:40

Re: 计算机那点事儿~

#48

帖子 ubuntu777 » 2015-07-19 21:29

这是我们要用在组装的计算机里面的数据选择器multiplexer。看图。
multiplexer_03.jpg
输入端是两组4位数据。L3、L2、L1、L0代表左边四位二进制数据。R3、R2、R1、R0代表右边的四位二进制数据。输出端标有OUT。也是一个4位的二进制输出。标有RIGHT的是控制端。用来选择是把左边的一组数据做为输出,还是把右边的一组数据输出。如果RIGHT端是低电平,OUT端(也就是输出端)的值等于L3、L2、L1、L0。如果RIGHT是高电平,那么OUT端的值就和R3、R2、R1、R0端的值相等。
这个东西我们会用来控制内存的地址线。在读取内存中指令并执行时使用一组地址线,在需要给内存写入内容时切换到另一组地址线。具体内容会在讲内存工作细节的时候再讲。
图中用到的也是非门电路、与门电路、或门电路。不同的是有的在输出端前面加了一个小圆圈,有的是在输入端加了小圆圈。小圆圈代表一个非门电路功能。相当于把原有的值改变。1变0,0变1。改变之后,再输入门电路,或者是把电路原来的输出值改变之后做为输出结果。
שְׁמַע יִשְׂרָאֵל יְהֹוָה אֱלֹהֵינוּ יְהֹוָה ׀ אֶחָֽד׃
וְאָהַבְתָּ אֵת יְהֹוָה אֱלֹהֶיךָ בְּכׇל־לְבָבְךָ וּבְכׇל־נַפְשְׁךָ וּבְכׇל־מְאֹדֶֽךָ׃
头像
ubuntu777
帖子: 249
注册时间: 2007-03-28 18:40

Re: 计算机那点事儿~

#49

帖子 ubuntu777 » 2015-07-26 22:39

来讲一我们要实际用到的内存芯片74189。
看图:
mem_74189_00.jpg
mem_74189_00.jpg (13.28 KiB) 查看 13151 次
mem_74189_02.jpg
mem_74189_02.jpg (3.6 KiB) 查看 13151 次
就是这个东西。大家先回忆一下,或者翻到前面去看一下我们讲过的内存。有地址线,有读写控制线。有数据线。我们以前讲的内存中1位数据只有一个数据线。其实1位内存是由一个触发器构成。大家知道触发器其实是有两个输出端。一边是1值,另一边就是0值。在这个实际使用的内存中,保留了那一边的相反值输出端。

这是一个可以存储16个4位二进制数据的内存。
那就有16个地址。所以要4根地址线。2的4次方等于16。编号为1、15、14、13的A3、A2、A1、A0就是4根地址线的脚。即然存储的是4位二进制数。那也有4根数据线。编号为4、6、10、12的D3、D2、D1、D0就是4个数据线。另外还有4根取值这4根相反的数据线。编号为5、7、9、11的D3D2D1D0
编号为3的WE(Write Enable)是读写控制线。当它是低电平的时候,可以进行写操作。是高电平的时候,进行读操作。编号为2的CE(Chip Enable)是芯片选择线。是低电平的时候,代表允许这个内存工作,可以对它进读、写操作。高电平的时候,相当于芯片被断开,什么功能也没有。不会影响到其它线路。
编号16的VCC提供一个+5V的电压。编号8的是接地线。正电压和接地是让二极管门电路组成的芯片工作必须的。大家都了解。

现在来看一个复杂的大图。了解一下内存怎么工作。
mem_74189_01.jpg
这是把两个74189芯片连在一起。起到的作用是存储16个8位的二进制数据。大家看两个芯片的地址线连在一起了。1连1,15连15,14连14,13连13。相当于还是只用4根地址线。16个地址。但是两个芯片的数据端5、7、9、11。分别接到不同的线上。最右边标有W bus的8根是8位数据总线。
这样同一个地址。4位数据存左边,4位数据存右边。就相当于存了一个8位的二进制数据。
大家注意到有很多箭头的线。每一个箭头代表一个开关。箭头朝上,代表开关推上去状态。箭头朝下,代表开关是推下去的状态。
以最上面标有A3、A2、A1、A0的四个开关为例子。图中的状态4个都是推上去的。推上去就开关断开了。推下来开关就连通了。这个开关左边标的倒三角形的三根小短线,代表接地线。右边有一个+5V的高电平。还接了一段标有10KΩ的小折线,这个代表电阻。记得我们讲二极管门电路的时候讲过这种开关的作用。用水流作过比喻。接地端就表示低电平,好象开了一个口子放水。以A3开关为例子。如果不接通。那个接编号1的地址线上面就是和+5V差不多的高电压。等于1值。一但接通,相当于水放掉。编号1地址线上的压力就没有了。相当于和接地端同样压力的低电平。等于0值。这样就可以通过开关状态来控制地址线,选择往哪个地址里面写数据。比如图中状态就是地址1111。如果把所有开关推下去。就是0000。把上面三个推下去,下面一个推上去。就是0001地址。
同样标有D7、D6、D5、D4、D3、D2、D1、D0的8根数据线,也是同样的原理工作。来给内存写入数据。不同的是箭头朝下。开关推下去是断开的。
标有WRITE的READ的开关,接的是内存芯片的WE端。两个WE是接通的。来选择读或者写的操作。原理还是一样。如果开关推上去和接地端连通。就是低电平0,可以进写操作。如果推下来,就保持和+5V电源差不多的高电平。进行读操作。
右边还有一个标有RUN、PROG的开关。连的是CE端。注意这个开关没有+5V的高电平,就只有一个接地端PROG。开关另一边RUN连的是标有ER的线。要对内存进行编程的时候。把开关推下去。接地。代表内存被选择。可以往里面写数据。写好了之后,推到RUN那一端。运行程序。运行程序的过程中由ER线来控制什么时候要用内存,什么时候禁用内存。
怎么往内存中写入数据?先把RUN、PROG这个开关推下来。然后,把WRITE、READ开关推上去。然后,把内存地址用地址线上的开关选择好。然后推数据线上的开关,把8位0、1值分别设置好。然后再推下一个地址。再推下一组数据。
开关相当于键盘对计算机的输入作用。不过是直接写0、1进内存。大家这次了解这个内存怎么写入数据就可以。以后还要介绍怎么对它进一步加工。
שְׁמַע יִשְׂרָאֵל יְהֹוָה אֱלֹהֵינוּ יְהֹוָה ׀ אֶחָֽד׃
וְאָהַבְתָּ אֵת יְהֹוָה אֱלֹהֶיךָ בְּכׇל־לְבָבְךָ וּבְכׇל־נַפְשְׁךָ וּבְכׇל־מְאֹדֶֽךָ׃
头像
ubuntu777
帖子: 249
注册时间: 2007-03-28 18:40

Re: 计算机那点事儿~

#50

帖子 ubuntu777 » 2015-08-02 21:52

这次讲control matrix(控制阵列)。我们在讲计算机架构的时候讲过。一个指令要完成。要经过几个时间阶段。在不同的时间段,把不同的寄存器控制端打开,或者是把数据送到数据总线上,由其它存储单元接收,或者完成计算工作,或者输出结果。要一步步完成工作。就需要一个能根据不同的指令,在不同的时间段,给相应组件的控制线上提供高电平的东西。control matrix就起这个作用。
看图:
control_matrix_00.jpg
最上面的一排标有T1-T6的六个输入端接的是一个我们讲过的环形计数器,来进行时间控制。首先T1为高电平,然后T2,然后T3。高电平按顺序移动。每次只有一个输入端是高电平。
左边标有LDA,ADD,SUB,OUT是计算机指令。分别是载入数据指令,加法指令,减法指令,输出指令。每次也只有一个是高电平。
输出端标有Cp,Ep,Lm,...一直到Lo,分别接到不同寄存器或者全加器,或者内存的控制端。来控制这些电路的不同功能的控制线在什么时间,根据什么指令,位于高电平或者低电平。也就是打开或者关闭。比如全加器,要在减法的时候,根据相应的时间信号,SUB控制线上要给一个高电平。这样输入端的减数变成补码,就可以完成减法指令要求的工作。
注意有几个控制端是多个指令都需要用到的。思考一下在同一个时间段内,一个指令要同时打开不同的控制端;或者同一个时间段,根据不同的指令,分别给不同的控制端高电平,是怎么来实现的。
回答下面几个问题:
1、在T1时间段内,哪几个输出端是高电平?
2、如果T4和LDA端是高电平,哪些输出端是高电平?
3、当T6和SUB端是高电平的时候,哪些输出端是高电平?
这个图貌似很复杂,但仔细研究一下就会发现规律。大家动脑。我就不详细解释了。要有动脑的能力。计算机的重要组件基本介绍完了。过不多久,就要进入更复杂的阶段。完成架构,设计指令,实际组成计算机。就要考虑所有细节,解决所有问题。所以一定要锻炼思考能力。
שְׁמַע יִשְׂרָאֵל יְהֹוָה אֱלֹהֵינוּ יְהֹוָה ׀ אֶחָֽד׃
וְאָהַבְתָּ אֵת יְהֹוָה אֱלֹהֶיךָ בְּכׇל־לְבָבְךָ וּבְכׇל־נַפְשְׁךָ וּבְכׇל־מְאֹדֶֽךָ׃
头像
ubuntu777
帖子: 249
注册时间: 2007-03-28 18:40

Re: 计算机那点事儿~

#51

帖子 ubuntu777 » 2015-08-10 12:18

组成计算机需要的重要元件基本都讲到了。这次讲一下算术逻辑单元(ALU)和指令寄存器与数据总线连接方式。然后,就可以进入下一阶段,讲怎么用这些元件组成计算机。
看图:
alu_to_bus_00.jpg
左边标有W bus的8根线就是数据总线。右边就是我们学过的算术逻辑单元。可以做加法和减法。
这个ALU有两个控制端,一个标有SU,来控制加法或者减法。另一个是EU。大家看就是一根控制输出端8根线上8个三态门电路的线。可以控制什么时候断开输出端与总线的连接,以免计算机在进行其它工作的时候影响数据总线上的结果;什么时候工作,把需要的结果送到数据总线上。
标有A7-A0的8根和标有B7-B0的8根线是参与加法或减法运算的两个数据。
A7-A0会接到一个累加器(ACUMMULATOR)。累加器其实就是一个缓冲寄存器。用来把总线上的计算输出结果缓存下来。然后做出输入值参与计算。因为输入值、输出值不能同时占用数据总线。没有缓冲寄存器。会引起冲突。
因为同样的原因。另一组数据输入端B7-B0也是接到一个8位的缓冲寄存器上,叫B寄存器。编号为B的寄存器。

下面看指令寄存器(instruction register)。看图:
instruction_register_00.jpg
指令寄存器也是一个缓冲寄存器。用74LS173组成。这个专门用来缓存指令代码。输入端8根线接到8位数据总线上。注意看输出端。右边4根输出端接到数据总线上。左边标有I7-I4的4根线。会接到指令译码器上。这一组4位数据会被转变,变成一根指令线(LDA、ADD、SUB、OUT)上的高电平。这4根线,我们在讲控制阵列(control matrix)的时候讲过。每一个指令,会配合环形计器器,在几个时间段内,分别控制不同的元件上的控制端。通过几个时间的相应元件不同动作,用来完成一个指令的操作。

这次的内容讲完了。在进入下一个阶段之前,希望大家回顾一下以前学过的内容。了解各个组件的工作、控制原理和方式。如果懂了,也可以自己提前想想,怎么组合它们,让它们完成计算,并输出结果到输出寄存器的8个灯。复习的过程中大家可能会发现,刚开始觉得很难的内容,现在回头看就简单了。这就说明大家在学习的过程中,能力不知不觉地提高了。如果有什么问题的话。希望大家能提问。一是我讲得的过程中可能会有错误。应该说肯定会有错误。二是还有遗漏,没有讲清楚的地方。一个人的问题,也代表很多人的问题。即帮助自己了解清楚,也帮助他人明白。也帮助我修正错误。
下一次没有新内容。专门回答问题。如果没有问题。就休息一次。在进入真正复杂的阶段之前,放松一下。
שְׁמַע יִשְׂרָאֵל יְהֹוָה אֱלֹהֵינוּ יְהֹוָה ׀ אֶחָֽד׃
וְאָהַבְתָּ אֵת יְהֹוָה אֱלֹהֶיךָ בְּכׇל־לְבָבְךָ וּבְכׇל־נַפְשְׁךָ וּבְכׇל־מְאֹדֶֽךָ׃
头像
冲浪板
论坛版主
帖子: 7513
注册时间: 2007-05-06 8:19

Re: 计算机那点事儿~

#52

帖子 冲浪板 » 2015-08-10 12:38

CPU上面有很多脚~~~~
这个值得商榷,
有次客户把很多的脚线弄弯了,咱就说过,要是平的就好了,针脚在板子上....
后来还真的改成扎样了......
头像
ubuntu777
帖子: 249
注册时间: 2007-03-28 18:40

Re: 计算机那点事儿~

#53

帖子 ubuntu777 » 2015-08-17 9:25

冲浪板 写了:CPU上面有很多脚~~~~
这个值得商榷,
有次客户把很多的脚线弄弯了,咱就说过,要是平的就好了,针脚在板子上....
后来还真的改成扎样了......
谢谢指正!前面相关部份中已经改了。
שְׁמַע יִשְׂרָאֵל יְהֹוָה אֱלֹהֵינוּ יְהֹוָה ׀ אֶחָֽד׃
וְאָהַבְתָּ אֵת יְהֹוָה אֱלֹהֶיךָ בְּכׇל־לְבָבְךָ וּבְכׇל־נַפְשְׁךָ וּבְכׇל־מְאֹדֶֽךָ׃
头像
ubuntu777
帖子: 249
注册时间: 2007-03-28 18:40

Re: 计算机那点事儿~

#54

帖子 ubuntu777 » 2015-08-23 21:42

看到贴子的点击量达到好几百。看来很多人做了复习。现在就会用到。

来看计算机的架构。看图:
architecture_00.jpg
出于不同目的考虑。或为了加快运行速度,或者为完成更多的、更大量的复杂计算工作等等。可以用多种不同的方式组我们学过的这些元件。以前我们讲指令周期时用的ARM处理器的架构,数据总线和地址总线是分开的两条。现在我们这个架构的目的是尽可能的简单,方便大家学习。大家学会原理之后,可以动脑筋重组来实现更多目的。这就是架构设计。
这是一个单总线的架构。大家看中间一条W bus就是数据总线。上面标的8。代表是8条线。

先来看左边的几个方块。
最上面方块标有Program counter的是程序计数器。方块左边是它的4个控制端,分别标有Cp、CLKCLR、Ep。方块右边一个标有4的箭头代表4根线输出到数据总线。
第二个方块标有Input and MAR是一个我们讲过的用来选择内存地址的4位开关,和一个内存地址缓冲寄存器。这个方块从数据总线接受4根线,输入数据到内存地址缓冲寄存器。分别有4根线输出到下面的方块标有16*8RAM的内存。
第三个方块内存。里面有一个2选一的多路数据选择器。我们讲过的。用一个开关控制。用来选择接收4位开关的地址来把内存里面直接写数据,还是选择接内存地址缓冲寄存器里面的地址来运行相关内存地址中的程序代码。多路数据选择器后面接的就是内存。一起构成这个方块的内容。内存还有8根线输出到8位数据总线上面。
第四个方块标有Instruction register。就是指令寄存器。方块左侧是这个寄存器的几个控制端。右侧有8根线的输入端,从数据总线上面接收8位的数据做为指令代码。右侧还有4根线做为输出,可以把数据放到数据总线上。另外还有4根向下的输出线。输出数据到下面的方块Controller/sequencer(控制阵列和时序部件)。
第五个方块控制阵列和时序部件。看右边的几个箭头,由时序部件给其它需要方块提供CLK和CLK时钟脉冲,还有CLR和CLR,提供数据清零功能。再看下面标有12根输出线,分别对应接到其它各个方块标有同样字母标识的控制端。由控制阵列根据指令寄存器提供来的指令,解码后,统一控制其余的各个组件的控制端。协调各个方块的动作。完成指令要求的工作。

再来看右边。
最上面的方块标有Accumulator是累加器。左侧共有16根线。8根线接到数据总线,作为输入端。还有8根线接到数据总线做为输出端。下面8根线,做为输出端,输送数据给下面的方块Adder/subtractor(全加器和减法器)方块。右侧是控制端。几根线接到Controller/sequencer(控制阵列和时序部件)方块上标有相同字母输出端。
第二个方块标有Adder/substractor(全加器和减法器)。左侧8根线,输出计算结果到数据总线。上、下各8根线。分别从上面的累加器和下面的B寄存器接收数据做为输入数据。右侧和控制端也是接到Controller/sequencer(控制阵列和时序部件)方块上标有相同字母输出端。
第三个方块B register(B寄存器)。左侧8根线是从数据总线接收数据的输入端。上面是提供给Adder/subtractor(全加器和减法器)数据的8根线的8位数据输出端。右侧也是控制端,接到Controller/sequencer(控制阵列和时序部件)方块上标有相同字母输出端。
第四个方法Output register(输出寄存器)。左侧8根线接到数据总线上,接收数据。往下的8根线输出到Binary display(二进制显示器)。右侧也是控制端。接到Controller/sequencer(控制阵列和时序部件)方块上标有相同字母输出端。
第五个方块Binary display就是上面那个输出寄存器的8根上分别接8个灯。高电平就亮,代表1。低电平不亮。代表0。通过这个8位的二进制。就可以看到计算结果。

下面是各个方块中的详细内容和线路连接方式。里面的各种元件,大部份都讲过。比如74LS107、74LS173等等。有几个没有讲过的。都是简单。门电路符号都标出来了。比如74LS126。就是一组4个的三态门电路。大家通过它们电路符号,也可以知道它的功能。

大家仔细研究一下。各个元件的控制端口的连线没有画出来,大家可以根据字母对应到控制阵列的输出端口。剩下来的电源端口,CLR、CLK端还有HLT端。只提供稳定的功能,不参与计算。怎么构成,我们在把计算的功能怎么实现讲完之后。最后再讲。

第一图是左边的几个方块。不包括控制阵列。
architecture_01.jpg
第二图是控制阵列。
architecture_03.jpg
第三图是右边的几个方块。
architecture_02.jpg
שְׁמַע יִשְׂרָאֵל יְהֹוָה אֱלֹהֵינוּ יְהֹוָה ׀ אֶחָֽד׃
וְאָהַבְתָּ אֵת יְהֹוָה אֱלֹהֶיךָ בְּכׇל־לְבָבְךָ וּבְכׇל־נַפְשְׁךָ וּבְכׇל־מְאֹדֶֽךָ׃
头像
ubuntu777
帖子: 249
注册时间: 2007-03-28 18:40

Re: 计算机那点事儿~

#55

帖子 ubuntu777 » 2015-08-30 22:29

在大家熟悉了这个计算架构的图之后。先简要讲一下各个方块在这个架构中的功能。以后详细介绍。

程序计数器(Program Counter)

程序存在内存里面。由一条条的指令组成。第一条指令在内存地址0000。第二条指令在0001,第三条
0010。一条跟一条。地址每次加1。程序计数器。我们讲过。4位输出线。从0000变化到1111。在需要的时候。EP端要把一组三态门打开。地址数据放到数据总线上。由内存地址寄存器读取。它起到作用就是把内存中的指令按内存地址顺序一条一条调出来。
每次程序运行的之前。CLR把它清零,变成0000。当这个计算机开始运行的时候。先调0000这个地址到数据总线(EP端打开三态门),写进内存地址寄存器。用完之后。CP端,也就是COUNT端。来一个高电平。把它的值加1。成为0001。然后。各部件按第一条指令的要求动作。执行第一条指令。当第一条指令的执行结束。再取它的0001值,调第二条指令。然后它的值再加1,变0010。等到第二条指令的一系列执行动作完毕。这个程序计数器就是这个作用。它里面存的值就是下一条指令的内存地址。
这个程序计数器也叫pointer(指针)。指向一个指令(instrction)的内存地址。

输入和内存地址寄存器(Input and MAR)

输入就是用开关把需要的值放到内存里面。我们以前详细讲过怎么做。
这里还有2to1的MULTIPLEXER(二选一的多路数据选择器)。由一个标有S2的开关控制。多路数据选择器的功能我们讲过。这里可以用S2控制。程序运行的时候,把开关S2推上去到RUN。MAR的4个输入端和内存的地址端就连通了。要往内存中输入程序的时候。开关S2推下去到PROG。开关组S1的4个开关线和内存的地址端就连通了。可以通过推A0-A3四个开关,来选择内存地址。然后,把内存的S4开关推到WRITE(写入)状态。就可以通过开关组S3。把需要的值写入内存。
MAR(memory address register)内存地址寄存器。作用就是缓存程序计数器中的地址数据。我们这个架构只有一条数据总线。当程序计数器中的地址数据放到总线上的时候。如果没有缓冲。直接接内存的地址线。内存中的数据也会直接输出到数据总线上。这样就会造成冲突。先把地址数据缓冲到MAR。就可以断开程序计数器,空出数据总线后。再放内存地址中的数据到数据总线,由指定的单元来读取。

内存(RAM)

16X8的内存。16个地址。每个地址可以存一个8位二进制数据。
可以通过多路数据选择器的控制接受两个4位地址输入端。通过开关组S1的地址线的输入来写程序,或者接受MAR中的地址数据,把内存中相应地址的指令放到数据总线上。供读取。

指令寄存器(Instruction Register)

内存中的指令数据放到数据线上的同时,它来读取。在地址总线空出来之后,才由它输出指令到控制阵列。
注意指令寄存器接受8位指令数据。一分为二。有4根输出到控制阵列,有4根输出到数据总线。

控制阵列和时序单元(Controller-Sequencer)

计算机运行时候,用CLR清零程序计数器,CLR端清零指令寄存器。提供CLK时钟脉冲到所有需要的寄存器。让各部件能同步运作。还有一个CLK到程序计数器。
12位控制线由控制阵列输出。叫做控制总线(control bus)。
控制总线的数据格式如下:
control_word_format_00.jpg
control_word_format_00.jpg (5.4 KiB) 查看 11698 次
通过这个数据。可以确定各个寄存器在下一个时钟脉冲(CLK)上升沿如何动作。比如:EP端是高电平同时LM端是低电平。就表示程序计数器中的数据会在下一个时钟脉冲上升沿被送到内存地址寄存器(MAR)。如果CE端是低电平,LA端是低电平。就表示内存被选定的地址中的数据会在下一个时钟脉冲上升沿被送到累加器(accumulator)。后面我们会用波形图来详细解释数据根据时钟脉冲传送的过程。

左边这几个方块讲完了。下周讲右边的。
שְׁמַע יִשְׂרָאֵל יְהֹוָה אֱלֹהֵינוּ יְהֹוָה ׀ אֶחָֽד׃
וְאָהַבְתָּ אֵת יְהֹוָה אֱלֹהֶיךָ בְּכׇל־לְבָבְךָ וּבְכׇל־נַפְשְׁךָ וּבְכׇל־מְאֹדֶֽךָ׃
头像
ubuntu777
帖子: 249
注册时间: 2007-03-28 18:40

Re: 计算机那点事儿~

#56

帖子 ubuntu777 » 2015-09-07 10:47

累加器(Accumulator)
累加器也是一个缓冲寄存器。用来缓冲计算结果。图上可以看出累加器有两个8位数据输出。一个是通过三态门开关接到数据总线(W-bus)。三态门的作用是可以断开数据和总线的连接。在不使用的时候,断开和总线的连接。把数据总线空出来可做其它的事情。另一个8位数据输出直接连到加减器上(Adder/subtractor)。总是作为加减器的一个输入端使用。

加减器(Adder-Subtractor)
全加器利用补码进行减法运算的加减器。我们讲过。
控制端SU低电平的时候,进行加法运算。
SU高电平的时候。连接B寄存器输出端的数据会变成补码后进全加器。计算的结果就是减法。
注意这个加减器没有CLK端的接入。就是说它不受时钟脉冲的控制。只要输入端的值发生改变,输出端马上就变成它们相加或相减的结果。如果控制端EU(就是控制三态门电路的开关)是高电平。这个结果就马上出现在数据总线(W bus)上。如果是有CLK端时钟脉冲控制的电路。输入端的影响不会马上呈现。通常是在下一个时钟脉冲的上升沿才产生作用。让电路在不同时间动作。就可以让计算机的各部件的动作按步骤完成。不会发生混乱冲突。

B寄存器(B Register)
B寄存器也是一个缓冲寄存器。在算术运算的时候缓冲加减器的一个输入端数据。当LB端是低电平,时钟脉冲是上升沿时,数据总线(W bus)上的数据会进入B寄存器。这个数据做为加减器的一个输入端接入。参与加法运算,或者做为被减数参与减法运算。

输出寄存器(Output Register)
当计算完成之后,累加器中存有计算结果。这些电路已经发生了相应的变化。但是结果我们看不见。这个时候就需要把结果传给外界。输出寄存器就是为了这个目的。当EA(累加器的输出端三态门控制端)是高电平,LO是低电平的时候。当下一个时钟脉冲上升沿的时候,累加器中的数据就会被送入输出寄存器。输出寄存器也叫做输出端口(output port)。port是港口是意思。港口的作用就是用来存储、堆放最后的成品。等待发往目的地。表示经计算机处理后数据最后就堆放在这个寄存器,准备发送到计算机以外去了。

电脑的输出端口(output ports)和接口电路(interface circuits)相连。接口电路用来驱动各种外围设备。打印机、显示器、网卡等等。接口电路为这些设备提供基础数据。

二进制显示器
这个二进制显示器就是一排共8个LED灯。每个LED灯接在输出寄存器的一根输出脚上。这样我们就可以通过灯的亮和灭来知道输出寄存器每一个脚上的1值或者是0值。从而知道输出寄存器里面存储的数据。

总结一下。
这个计算机的控制单元由程序计数器、指令寄存器、控制阵列(用来产生控制总线数据、发出清零信号、产生时钟脉冲)组成。
算术逻辑单元(ALU-Arithmetic Logical Unit)由累加器、加减器、B寄存器组成。
内存单元由内存地址寄存器(MAR-Memeory address register)、16*8 RAM(可存16个8位数据的内存)组成。
输出输出单元(I/O unit)由一组编程用的开关做为输入设备,和输出寄存器、二进制显示器组成的输出单元组成。

回想我们最初通过开关电灯,连接一个电路,自动得到加法结果的设想。到最高级的电脑。其实也是开关,中间计算处理的电路,和作为最后输出的电灯。只是开关变成了键盘。按下去打开一个。电路变得非常复杂,由上亿的二级管组成。电灯数量变成数量庞大。比如分辨率1920*1080,其实就是由1920*1080=2073600。二百多万个小灯组成的巨大方阵。起初不会有多少人觉得拨动开关,看这些电灯亮来亮去有什么意思。但现在很多人玩电脑游戏的实质也就是拨动开关,观看巨大灯阵的变化。甚至发展到有严格的法律来限制人们按喜好拨动自己电脑开关,观察这些灯阵的自由。说什么侵犯隐私了。知道得太多了。入侵别人的电脑了。这究竟有什么意义?以我从最初的观念来看。无非就是调整开关看灯而己。只是人心的恶念,让人不得自由,彼此伤害。
שְׁמַע יִשְׂרָאֵל יְהֹוָה אֱלֹהֵינוּ יְהֹוָה ׀ אֶחָֽד׃
וְאָהַבְתָּ אֵת יְהֹוָה אֱלֹהֶיךָ בְּכׇל־לְבָבְךָ וּבְכׇל־נַפְשְׁךָ וּבְכׇל־מְאֹדֶֽךָ׃
头像
ubuntu777
帖子: 249
注册时间: 2007-03-28 18:40

Re: 计算机那点事儿~

#57

帖子 ubuntu777 » 2015-09-14 15:53

指令集(instruction set)

CPU的硬件已经连好。下面要知道怎么设置软件让它能运作起来。CPU需要指令才能运作。指令就是装在内存里面,按顺序一条一条调出来,解码后可以控制计算工作的东西。一种CPU能接受的各种指令的集合,就是指令集。我们这个CPU的几个指令如下:

LDA

用来把内存中的内容装入累加器。就是把累加器里面的二进制数据变得和某个内存地址中的一样。累加器可以存一个8位的二进制数据。内存每个地址中也可以存一个8位的二进制数据。一共有16个地址。可以存16个二进制数据。如果想把某一个地址中的数据送入累加器。就用这个命令。
内存有4根地址线,内存地址1000(换成十六进制等于8),里面有一个8位的数据1111 0000。
执行LDA 8H这个指令之后的结果就是累加器里面数据也变成1111 0000。

简单讲一下十六进制。十进制每一位上有0-9共十个数字。数完了就进一位。二进制每一位只有二个数字0和1。数完了也进一位。十六进制每一位上有十六个数字。0、1、2、3、4、5、6、7、8、9、A、B、C、D、E、F。十六个数字数完了。才进一位。
比如十进制0数到9。9之后呢?就是10,进一位后。十位数上是1。个位数上是0。组成10。代表十。
十六进制的话,数到9之后还有A。A就代表十。不用进位。A之后还有B,代表十一。可以一直用F代表十五。十五之后,没有了。就要进一位。变10。十六进制的10就代表十六。为了和十进制的数字区别。十六进制的数字后面加一个H(英文hexadecimal的头一个字母)。看到10H。就知道是个十六进制数,代表十六。就和代表十的十进制10区别开了。

ADD

ADD是另一个指令。用来做加法运算。ADD 9H 这条指令的作用就是把内存地址9H里面的数字和累加器里面原有数字相加。用相加之后的结果替代累加器里面原有的数据。

比如累加器里面的8位二进制数据是 A = 0000 0010。就是十进制的2。
内存地址9H里面的8位二进制数据是 R9 = 0000 0011。就是十进制的3。
执行ADD 9H这条指令
第一步,首先B寄存器的内容要变成 B = 0000 0011。要变成内存9H地址里面的数据一样,参与运算。我们的加减器(adder-subtracter)的输出端会马上得出B寄存器和累加器里面的数据相加的结果 0000 0101。
第二步,然后再把输出端的值送入累加器,累加器里面的值变成 A = 0000 0101。取代原有值。

SUB

另一个指令。做减法运算。SUB CH 这条指令就是用累加器里面数据减去内存地址CH(这是十六进制数字,换成十进制数字是12,二进制是1100)。
比如累加器 A = 0000 0111
内存地址CH里面的数据 RC = 0000 0011

指令SUB CH执行
首先把B寄存器内容变成和内存地址CH里面的数据一样,B = 0000 0011。然后,按我们加减器的工作连线方式,大家知道输出端会马上变成 0000 0100。
第二步, 两数之差送入累加器 A = 0000 0100。

OUT

另一个指令。让计算机把累加器的值送到输出寄存器。在OUT指令执行之后,你就可以通过灯的亮和灭,看到计算结果的二进制数据。注意前面几条指令后面要跟一个内存地址。这个OUT指令没有。这个指令和内存里面数据没有关系。

HLT

这个指令是停止运算的功能。告诉计算停止处理数据。这个指令代表程序结束。我们知道程序计数器在指令执行完之后,会自动指向内存下一地址,把下一内存中的指令载入指令寄存器。这条指令会中止这个自动过程。避免程序完成之后,内存中无意义的内容进入指令寄存器后导致计算机错误。

这条指令后面也没有内存地址。因为不需要内存数据参与运算。

LDA,ADD,SUB指令称为内存相关指令。因为它们在执行过程中要用到内存中存储的数据。OUT,HLT指令称为内存无关指令。因为不需要内存中的数据参与。

LDA,ADD,SUB,OUT,HLT就是这个计算机要用到的指令。这几个词是指令功能的简写。也称为助记符(mnemonics)

指令集说明表

助记符000000000000操作

LDA0000000000000把内存中的数据载入累加器
ADD0000000000000把内存中的数据和累加器中的数据相加,相加结果取存入累加器中,取代原有值。
SUB0000000000000累加器中的值减去内存中数据的值,相减结果存入累加器,取代原有值。
OUT0000000000000输出累加器中的数据
HLT0000000000000中止程序

下面来用这些指令编一个程序。

内存地址00000000助记符

0H0000000000000LDA 9H
1H0000000000000ADD AH
2H0000000000000ADD BH
3H0000000000000SUB CH
4H0000000000000OUT
5H0000000000000HLT

下面是内存中的数据区

内存地址00000000数据

6H0000000000000FFH
7H0000000000000FFH
8H0000000000000FFH
9H000000000000001H
AH000000000000002H
BH000000000000003H
CH000000000000004H
DH0000000000000FFH
EH0000000000000FFH
FH0000000000000FFH

注意后面有H就代表是十六进制数。内存地址就代表我们计算机的内存地址。由低到高,0、1、2、3...按顺序排的。我们要把每条助记符转成相应的二进制机器码,就是8位的二进制数字。用拨动开关的方式,存入内存地址之中。数据也是一样,存入相应的内存地址中。计算机运行的时候。就会按顺序从低地址到高地址,把指令载入一条接一条地执行。

程序段保存在内存的低地址区0H到5H。数据段存在内存地址6H到FH区域。
指令在执行的过程中。会调用内存中数据。执行到HLT时,HLT指令会让计算机停止。
大家思考一下,这一段程序要完成什么功能?答案下期揭晓。
שְׁמַע יִשְׂרָאֵל יְהֹוָה אֱלֹהֵינוּ יְהֹוָה ׀ אֶחָֽד׃
וְאָהַבְתָּ אֵת יְהֹוָה אֱלֹהֶיךָ בְּכׇל־לְבָבְךָ וּבְכׇל־נַפְשְׁךָ וּבְכׇל־מְאֹדֶֽךָ׃
l10x
帖子: 447
注册时间: 2008-06-23 19:31
系统: debian+fedora+win10

Re: 计算机那点事儿~

#58

帖子 l10x » 2015-09-14 21:11

:em50 :em11
头像
ubuntu777
帖子: 249
注册时间: 2007-03-28 18:40

Re: 计算机那点事儿~

#59

帖子 ubuntu777 » 2015-09-20 22:22

公布上期编的程序的运行结果。程序在内存0H到5H。一共是六条指令。
第一条指令LDA 9H把内存地址9H的数据载入累加器(Acummulator)
累加器里面的内存就变成得地址9H中存储的数据一样
A=01H
第二条指令是ADD AH。把内存地址AH中存储的数据和累加器中的数据相加。相加之后的结果变成累加器的新值。内存地址AH中的数据是什么?02H
A = 01H + 02H = 03H
第三条指令是ADD BH。再把内存地址BH中的数据和现在累加器中的数据相加。内存地址BH中存的是03H。执行之后累加器中的值变为。
A = 03H + 03H = 06H
第四条指令SUB CH。累加器中的数据减去内存地址CH中存储的数。结果送入累加器。CH中是04H。
执行之后累加器中的值是
A = 06H - 04H = 02H
第五条指令是OUT。要把累加器中的这个最终结果02H送到输出端口。由8个灯组成的二进制显示器显示的结果是
0000 0010
除了右数第二个灯亮。其它灯是灭的。通过这个灯。我们可以观察到电路计算完成之后里面的电线的带电状况。
最后一个HLT指令结束数据的处理。

要完成这个程序。我们计算机内存里面存的必须是让电路能完成相应功能的机器码。也称为操作码(operation code 简称 op code)

对应指令助记符的操作码表

助记符0000000000操作码
LDA00000000000000000
ADD00000000000000001
SUB00000000000000010
OUT00000000000001110
HLT00000000000001111

程序写好了。可以按这个表查到助记符对应的机器码。比如LDA 9H这条指令。先查到LDA对应是0000。后面的9H叫操作数(operand)。十六进制数9H对应的二进制数是1001。
操作码是一个4位二进制数,操作数是一个4位二进制数。组合起来就是一个8位二进制数。操作码排在前面,操作数排在后面。最终的结果就是0000 1001。刚好我们计算机的一个内存地址可以存一个8位的二进制数。0000 1001这个机器码代表最终会让计算机执行相应的操作。
下面把一个程序翻译成机器码,并用拨动开关的方式把机器码存入内存。
程序如下

地址000000000指令
0H0000000000LDA FH
1H0000000000ADD EH
2H0000000000HLT

首先把每条指令按上面讲的方法转成机器码

LDA FH = 0000 1111
ADD EH = 0001 1110
HLT000= 1111 XXXX

XXXX代表是什么值都无所谓。因为HLT指令不会用到操作数。HLT的操作码只有4位,一个内存地址有8位,只要前面4位是1111,剩余的后面4位是什么都可以。

机器码转好了。下面来拨开关。通过开关往内存里面存数据的方法我们以前也讲过。
D(Down)表示开关拨下去,U(Up)表示开关拨上去。

内存地址开关0000000数据开关
DDDD0000000000000DDDD UUUU
DDDU0000000000000DDDU UUUD
DDUD0000000000000UUUU XXXX

一共是三组。每一组开关拨到位之后。拨动Write(写)开关打开。内存中相应地址中的内容就会发生改变。然后,把写开关拨回去关掉。把下一组开关拨好。再打开写开关。地址开关有4个。数据开关有8个。
D产生0值,U产生1值。
这三组地址开关和数据开关对应的地址值和内存中的数据内容如下:
内存地址000000000内存中的数据
000000000000000000000 1111
000100000000000000001 1110
001000000000000001111 XXXX

所谓的汇编语言就是利用助记符编出来的程序。所谓的机器码就是这些0和1组成的字串。把用助记符写好的程序转化翻译为机器码就叫编译。我们刚才通过查表人工完成编译工作。现在程序写好,都是用电脑编译软件来编译。电脑发明之初也是由程序员人工完成把写好程序编译成机器码的工作。为什么要人工?因为人工便宜。当时使用电脑的费用要几十万美元。程序员的工资一个月几千就很高了。给几千块让他们去忙一个月翻译机器码,把电脑闲出来更划算。下周中秋节。休息一期。预祝大家中秋节快乐!月圆人团圆!
שְׁמַע יִשְׂרָאֵל יְהֹוָה אֱלֹהֵינוּ יְהֹוָה ׀ אֶחָֽד׃
וְאָהַבְתָּ אֵת יְהֹוָה אֱלֹהֶיךָ בְּכׇל־לְבָבְךָ וּבְכׇל־נַפְשְׁךָ וּבְכׇל־מְאֹדֶֽךָ׃
l10x
帖子: 447
注册时间: 2008-06-23 19:31
系统: debian+fedora+win10

Re: 计算机那点事儿~

#60

帖子 l10x » 2015-09-21 15:26

出书,计算机设计原理 :em09
回复