多么痛的领悟——计算机组成原理第一讲
前言
大家好,我是泰斗贤若如,我又开始更新文章了,本次更新的内容是计算机组成原理,是大学计算机相关专业必须学的,我是大三上学期学的,刚开始学的时候感觉很难,get不到重点,直到学了一遍,被期末考试逼了一遍,我才有所领悟,多么痛的领悟啊。我打算自己把整本书中的重点总结一遍,第一是自己过一遍,第二是给新手赠予玫瑰,希望你们学的时候花最少的时间学更多的知识,别再在考试前病急乱投医了(偷笑表情)
一、计算机系统
1、计算机的硬件
计算机系统由“硬件”和“软件”两大部分组成。
主板是整个计算机的“交通枢纽”,各种器件都要连接到主板上,才能正常工作。
*处理器是计算机的“大脑”,它是计算机的运算核心和控制核心。
硬盘是计算机的“笔记本”,上面记录了各种数据,需要的时候,就会从这里读取或往这里写入。
内存是计算机的“稿纸”,一般来说,同一个处理器能利用的内存越大,运算速度也就越快。
2、计算机的软件
所谓“软件”,它看不见摸不着,由人们事先编制的具有各类特殊功能的程序组成。 通常把这些程序寄寓于各类媒体(如RAM、ROM、磁带、磁盘、光盘、甚至纸带等),它们通常存放在计算机的主存或辅存内。 由于“软件”的发展不仅可以充分发挥机器的“硬件”功能,提高机器的工作效率,而且已经发展到能局部模拟人类的思维活动,因此在整个计算机系统内,“软件”的地位和作用已经成为评价计算机系统性能好坏的重要标志。
计算机的软件通常分为两大类:系统软件和应用软件。
系统软件保证计算机系统高效、正确运行的基础软件。
应用软件为解决某个应用领域中的问题而编制的程序。
综上所述,再通俗点说“什么是软件呢”?
软件其实是我们生活中常用的一些应用,比如聊天类的QQ、微信;购物类的淘宝、京东;游戏类的吃鸡、英雄联盟等等吧,这些我想大家都再熟悉不过了,这些都可以称作为软件。软件是个抽象的名词,所以你也不用在这钻牛角尖,你可以把软件进行分类,比如说可以分成系统软件、应用软件等。先说系统软件吧,我想就算你是个小白,你至少也应该知道你现在用的电脑上装的是windows系统吧,那这个windows系统就是一个系统软件,系统软件是负责管理计算机系统中各种独立的硬件,使得它们可以协调工作。系统软件使得计算机使用者和其他软件将计算机当作一个整体而不需要顾及到底层每个硬件是如何工作的。
像这样的系统软件还有很多,先暂时了解windows这一个系统软件就可以了。知道了系统软件,再说应用软件,它是为了某种特定的用途而被开发的软件,它可以完成各种具体任务,比如游戏、办公、存储数据等等,没有应用程序的计算机,基本上什么功能都没有,值得一提的是,应用程序必须在操作系统的支持下才能运行。
熟悉智能手机的同学都知道,应用分为“安卓版”、“ios版”等几种,如果安装的时候选错了类型,是不能安装的,更不要提正常运行了。
再说简单点,其实软件就是我们所说的“程序”或“应用”,软件由人类编写而成,具有各种各样的功能,在上面说了硬件,其实硬件就是服务员,只会“按图索骥”,软件怎么说,硬件就怎么做。换句话说,没有安装软件的计算机,什么都不会做,软件有许多种,操作系统是其中非常重要的一种,顾名思义,人们只有通过操作系统才能让计算机执行各种指令,电脑的“Windows”系统,手机的“安卓”系统、“iOS”系统等都属于操作系统,我想看到这你应该明白了不少吧,要是还没明白,就再多看几遍,看图理解也行,至少你现在要明白没有安装软件的计算机就是一堆废铜烂铁,应用程序必须再操作系统的支持下才能运行。
3、计算机的解题过程及编程语言的前世今生
现代计算机的解题过程如下:
通常由用户用高级语言编写程序(称为源程序),然后将它和数据一起送入计算机内,再由计算机将其翻译成机器能识别的机器语言程序(称为目标程序),机器自动运行该机器语言程序,并将计算结果输出。
在上面我已经详细描述了“软件”,那现在出现了一个问题是人类是如何编写软件的呢?我就开门见山了,软件是由“编程语言”编写而成的。
编程语言的前世今生
编程语言
编程语言,看到这几个字后不要急着看官方定义,首先顾名思义,自己先理解,我来说说我对编程语言的理解吧:一眼扫过去,你看到的是“语言”二字,对语言大家都不陌生,语言是人类最重要的交际工具,是人们进行沟通的主要表达方式,像汉语、英语、法语、俄语等都是世界上的主流语言。既然语言是用来沟通交流的,那“编程语言”也不例外,区别在于像汉语、英语等这些语言是人与人进行交流的语言,而“编程语言”是人与计算机进行交流的语言,只是沟通对象不同。那再说计算机,它其实本质上就是电流加一堆硬件,如果没有电流,计算机就像桌子椅子一样,它不是“活”的东西,有了电流,它才能“活”起来。那这电流是怎么让这一堆硬件“活”起来的呢?比如展现出我们现在所看到的丰富多彩的文字、图片,那它是如何做到的呢?其实当时这个涉及计算机的这些先贤们也遇到过这个问题,他们考虑我怎么能让这些硬件动起来,怎么让我的电流给它驱动起来?也是他们进行思考,最后终于思考出来了,电流其实可以表示两种状态,高电压和低电压两种状态,而现在电流有很多条,也就是说有很多的高电压和低电压,那我把这个高电压低电压的这种实际的物理现象用人类所能理解的数字关联起来,叫数字关联,高电压是1,低电压是0,这样有个强制规定的话,就可以跟我们人类的语言有了一定的关联关系,而这两种1,0的状态也能被计算机所识别,计算机本质上其实就是像1010这样的一堆组合干各种事情,那到此为止,我们可以说能用1010这样不同的状态跟计算机进行沟通了,具体怎么沟通听我在这瞎掰也没有任何意义,所以一定要制定规则,比如所1011010这一堆数据表示打开音乐,1111000101这一堆数据表示打开文件,等等吧,这是我瞎说的,主要体会精神,这就代表你把无序的0101状态给规则化了,研发一种语言你必须定义规则,就像研发英语要定义主谓宾语法一样的道理,那现在我们把0101组合成不同的序列定义相应的规则,这样有了这些规则后我告诉你,最古老的计算机语言就出现了,有了规则它就能称之为语言了,这个最古老的语言就叫机器语言。
机器语言
其实看了上面的这些,你大概明白其实机器语言说白了就是一堆0101的组合,然后把0101的组合规则直接给你通过在芯片烧制的时候,也就是把这些规则直接刻在芯片上了,那电流这么走,十个灯一块亮,就代表要播放声音了,另外几个灯要是一起亮,就代表要打开文件了,这就是机器语言。机器语言作用是直接跟硬件打交道,所以计算机能够很好的理解,因为这就是它的天生语言。但是计算机能很好的理解,但人却不能很好的理解,像0101这样的组合有很多,人理解起来很费劲,要是来个复杂点的动作,五十、一百个0101组合在一块,你就头疼了,而且你还有可能写错,一写错就导致整个就完蛋了,你要是想排错,就得数哪个1是不是排错位置了啥的,这就让人头大了。说到这你明白,机器语言的出现虽然能让计算机干事情了,但是人与计算机的这种沟通效率是极低的,你可能在草稿上写一个月终于写出来计算机能理解的五句话,打开一个文件,播放一个音乐,然后关了,你写这些耗时不说还怕写错,所以效率是特别低下的。科技要发展,所以人们就要进步,要想办法让人与计算机之间的沟通效率更高,就把语言提升了,像之间那种0101的组合程序员不需要死记硬背了,把那难记的一堆0101组合变成一个对应的人能理解的英文,比如说,我们运算时需要加减乘除,如果用机器语言描述加号,要表示成1010001111就如说就这些吧,是不是很难记,那现在把这一串机器语言变成人能理解的英文单词ADD,就是把这个0101组合变成了英文,你只要在键盘上敲出了相对应的英文,它就自动给你翻译成0101这样的机器语言,然后让计算机去执行,这个东西就叫做汇编语言。
汇编语言
对人来讲,像用字母表示或者用数字、符号表示这样的一些符号语言简单直接、便于记忆,比0101组合表示的机器语言简单方便了很多,但其实开发效率还是很低,你看下面的图片,就是用汇编语言写的,仅仅是在屏幕上打印输出一句helloworld居然要写这么多代码,可见这个效率实在是不怎么高,你比如所现在开发一个APP三天就能上线了,你要是用汇编语言的话,估计你得写半年还不一定写的完(这是我猜的,不要在意真实性,就当是虚构吧),所以人们还要进步,继续为提高效率而努力。不过人类不愧是高级动物,聪明才智,最后研发出一种语言叫高级语言,这种语言更容易让人去理解,能使不熟悉具体计算机的人也能很方便的使用计算机,跟计算机更好的沟通交流,比如说之前说的用机器语言表示加号需要1010001111这样一堆代码,然后有了汇编语言后只需要记住ADD就可以,但现在有了高级语言后,加号就直接用数学中我们常用的“+”去表示就可以了,这个大家肯定都能明白。
高级语言
汇编语言的一个问题在于需要你自己去调用硬件的各种指令,比如你想播放声音,播放声音也是由芯片来控制的,芯片里面已经烧制了各种指令,你要想播放声音,就要调各种相应的指令,汇编语言的问题在于它要亲自去调,自己去写代码去调这种指令,这其实非常复杂,你要想调音卡,就是播放声音,你还要学习音箱的这个硬件的各种操作指令,你要想显示屏幕,你还要看显卡上也就是显示屏幕上的操作芯片的各种指令,还是蛮复杂的,做这样的程序员我觉得很痛苦,可能那个时候的程序员都是秃头(猜的),现在的程序员秃头的应该没以前多了,不过掉头发另说啊,因为他们学了高级语言,这个高级语言的好处就是让程序员对底层硬件的各种指令做了封装,封装的意思就相当于把那些复杂的东西都给你处理掉了,暴露给你的东西都是非常简单的,真正实现了你想播放音乐,你就直接写playMusic("夜空中最亮的星");我偶像张杰的一首好听的音乐就能播放了,这就牛逼了,就算你没学过编程的人,看了这个指令也知道这是在播放音乐,其实你的这行指令在底层可能给你解析出来了好几十条汇编的指令,然后又把汇编的指令转化成0101这种机器指令,但是这些复杂的东西都不需要你来管因为计算机已经帮你封装好了,你只需要调用一下就OK。有了这样的高级语言,人类的开发效率才提高起来,然后才能说我想写一个软件,然后一周就上线了,就能卖钱了···这些就是编程语言的一个演化过程,从最早的机器语言到汇编语言再到现在的高级语言,那我们现在听到的C、C++、JAVA、Python等主流的这些语言都是高级语言
4、冯·诺依曼结构计算机
提到冯诺依曼计算机,有必要提一下“计算机之父”——冯·诺依曼,冯·诺依曼是美籍匈牙利人,他的精髓贡献有两点:二进制思想与程序内存思想。
再详细点,冯诺依曼理论的要点是:
- 数字计算机的数制采用二进制;
- 计算机应该按照程序顺序执行;
根据冯诺依曼理论构成的计算机,有如下功能:
- 把需要的程序和数据送至计算机中。
- 必须具有长期记忆程序、数据、中间结果及最终运算结果的能力。
- 能够完成各种算术、逻辑运算和数据传送等数据加工处理的能力。
- 能够根据需要控制程序走向,并能根据指令控制机器的各部件协调操作。
- 能够按照要求将处理结果输出给用户。
根据上述对应的功能,计算机具有五大基本组件,分别如下:
- 输入数据和程序的输入设备;
- 记忆程序和数据的存储器;
- 完成数据加工处理的运算器;
- 控制程序执行的控制器;
- 输出处理结果的输出设备。
5、计算机如何执行你的程序
- 把程序和数据装入到主存储器中
- 从程序的起始地址运行程序
- CPU的工作非常简单,它从内存中获取一个指令并执行该指令,然后从内存中获取下一个指令并执行。CPU能以惊人的速度从事枯燥的工作。
- 每条指令都要经过取指、译码、执行。
6、计算机的性能指标
机器字长
进行一次运算所能处理的二进制数据的位数。
主存容量
指主存所能存储的最大容量。
运算速度
衡量性能的一个重要指标。CPU时钟周期、主频、MIPS等。
数据通路带宽
数据总线一次并行传递数据的位数。
7、进制的世界
进制码与不同进制数之间的转换
十进制、二进制、八进制、十六进制
1、基本数码
- 0 1 2 3 4 5 6 7 8 9
- 0 1
- 0 1 2 3 4 5 6 7 8 9 A B C D E F
2、逢P进1,借1当P
3、进制间的转换
十进制转换为P进制
- 整数部分:除P倒取余
- 小数部分:乘P正取整
例:6.325转换成二进制
P进制转换为十进制
- 将各位数码和其权值相乘后求和,即可转换成十进制
例:10110转换成十进制
8、计算机的运算方法
带符号数的表示及运算
1、无符号数和有符号数
在计算机中参与运算的数有两大类:无符号数和有符号数。
计算机中的数均存放在寄存器中,通常称寄存器的位数为机器字长。所谓无符号数,即没有符号的数,在寄存器中的每一位均可用来存放数值。当存放有符号数时,则需留出位置存放符号。因此,在机器字长相同时,无符号数与有符号数所对应的数值范围是不同的。
对有符号数而言,符号的“正”、“负”机器是无法识别的,但由于“正”、“负”恰好是两种截然不同的状态,如果用“0”表示“正”,用“1”表示“负”,这样符号也被数字化了,并且规定将它放在有效数字的前面,即组成了有符号数。
把符号“数字化”的数称为机器数,而把带“+”或“-”符号的数称为真值。一旦符号数字化后,符号和数值就形成了一种新的编码。在运算过程中,符号位能否和数值部分一起参加运算?如果参加运算,符号位又需作哪些处理?这些问题都与符号位和数值位所构成的编码有关,这些编码就是原码、补码、反码和移码。在这些编码中,补码的应用居多,原因是补码可以带符号运算,而且可以变减为加。
2、原码、反码、补码、移码表示法
1、真值为整数
例:
当x=+1110(x为真值)时,
x原码=0,1110(用逗号将符号位和数值部分隔开)
x反码=0,1110
x补码=0,1110
x移码=1,1110
当x=-1110(x为真值)时,
x原码=1,1110
x反码=1,0001
x补码=1,0010
x移码=0,0010
2、真值为小数
例:
当x=+0.1101(x为真值)时,
x原码=0.1101(用逗号将符号位和数值部分隔开)
x反码=0.1101
x补码=0.1101
x移码=1.1101
当x=-0.1101(x为真值)时,
x原码=1.1101
x反码=1.0010
x补码=1.0011
x移码=0.0011
表示规则:
原码:原码就是符号位加上真值的绝对值,即用第一位表示符号,其余位表示值。
反码:反码有两种情况:
- 当原码为正数时,其反码就等于正数的原码
- 当原码为负数时,其反码就等于正数的原码按位取反,但是最高位的符号位不变。
补码:补码有两种情况:
- 当原码为正数时,其补码就等于正数的原码
- 当原码为负数时,其补码就等于正数的原码按位取反,符号位不变,最后再在末尾加1(即在反码的末尾加1)
移码:移码(又叫增码)是符号位取反的补码。
3、移位运算
例:设机器数字长为8位(含1位符号位)
当A=+11010时,
移位前: A原码=A反码=A补码=0,0011010
左移一位: A原码=A反码=A补码=0,0110100
右移一位: A原码=A反码=A补码=0,0001101
当A=-11010时,
移位前:
A原码=1,0011010
A反码=1,1100101
A补码=1,1100110
左移一位:
A原码=1,0110100
A反码=1,1001011
A补码=1,1001100
右移一位:
A原码=1,0001101
A反码=1,1110010
A补码=1,1110011
算数移位规则
- 1.机器数为正时,不论是左移还是右移,添补代码均为0
- 2.由于负数的原码数值部分与真值相同,故在移位时只要使符号位不变,其空位均添0
- 3.由于负数的反码各位除符号位外与负数的原码正好相反,故移位后所添的代码应与原码相反,即全部添1
- 4.分析任意负数的补码可发现,当对其由低位向高位找到第一个“1”时,在此“1”左边的各位均与对应的反码相同,而在此“1”右边的各位(包括此“1”在内)均与对应的原码相同。故负数的补码左移时,因空位出现在低位,则添补的代码与原码相同,即添0;右移时因空位出现在高位,则添补的代码应与反码相同,即添1
逻辑移位规则
- 逻辑左移时,高位移丢,低位添0
- 逻辑右移时,低位移丢,高位添0
加法和减法运算
加减法运算是计算机中最基本的运算,因减法运算可看做被减数加上一个减数的负值,即A-B=A+(-B),故在此将机器中的减法运算和加法运算合在一起讨论。现代计算机中都采用补码作加减法运算。
[-B]补由**[B]补连同符号**在内,每位取反,末位加1而得
溢出判断
在计算机中,超出机器字长的现象叫溢出。
补码定点加减运算判断溢出有两种方法:
1.用一位符号位判断溢出
- 对于加法,只有在正数加正数和负数加负数两种情况下才可能出现溢出,符号不同的两个数相加是不会溢出的。
- 对于减法,只有在正数减负数或负数减正数两种情况下才可能出现溢出,符号相同的两个数相减是不会溢出的。
2.用两位符号位判断溢出
在用变形补码作加法时,2位符号位要连同数值部分一起参加运算,而且高位符号位产生的进位自动丢失,便可得正确结果。
变形补码判断溢出的原则是:当2位符号位不同时,表示溢出,否则,无溢出。不论是否发生溢出,高位(第1位)符号位永远代表真正的符号。