计算机组成原理


一、计算机基础知识

1、进制

(1)其他转二

其他进制数除2取余法,以下以十进制数为例。

(2)二转其他

把二进制数按权展开、相加即得其他进制数。以下以十进制为例。

(3)二与十六互转

将二进制数的每4位看成一位十六进制数。

以下二进制数1000 0001转化为十六进制数即为81。十六进制转化为二进制,即将每个十六进制分解成4位二进制数。

1000 0001
8 1

(4)java进制

进制 前缀 举例
二进制 0b 0b1001
八进制 0 01001
十进制 没有前缀默认为十进制 1001
十六进制 0x 0x1001

2、原码、补码、反码

机器数

  一个数在计算机中的二进制表示形式,叫做这个数的机器数。机器数是带符号的,在计算机用一个数的最高位存放符号,正数为0,负数为1。比如,十进制中整数+3,若计算机字长为8位,转换为二进制数为 0000 0000 0000 0000 0000 0000 0000 0011;如果是-3,就是1000 0000 0000 0000 0000 0000 0000 0011。

在计算机中负数以补码的形式存储

真值

因为第一位是符号位,所以机器数的形式值就不等于真正的数值。

例如:有符号数的真值如下

1000 0000 0000 0000 0000 0000 0000 0011的真值 = -000 0000 0000 0000 0000 0000 0000 0011 = -3

0000 0000 0000 0000 0000 0000 0000 0011的真值 = +000 0000 0000 0000 0000 0000 0000 0011 = +3

机器字长

数据表示需要二进制位的数量,如果机器字长为 n

(1)原码

具有符号位的二进制数

(2)反码

正数的反码是其本身

负数的反码是在其原码的基础上,符号位不变,其余各个位取反

(3)补码

正数的补码就是其本身

负数的补码是在其原码的基础上,符号位不变,其余各位取反,最后+1(即在反码的基础上+1)

对于补码,零的表示唯一

 -3 
原码 1000 0000 0000 0000 0000 0000 0000 0011
反码 1111 1111 1111 1111 1111 1111 1111 1100
补码 1111 1111 1111 1111 1111 1111 1111 1101

+3 
原码 0000 0000 0000 0000 0000 0000 0000 0011
反码 0000 0000 0000 0000 0000 0000 0000 0011
补码 0000 0000 0000 0000 0000 0000 0000 0011

其实对于计算机来说,并不存在原码和反码,计算机存储的二进制数据都是以补码的形式存放的,自然对数据的运算也是直接用补码来运算(计算机中只有加法器没有减法器)

先来看个例子1:

十进制整数 二进制原码 二进制补码
7 0111 0111
-5 1101 1011

所以我们当计算机要计算7-5=?,实际上计算机直接认为是7+(-5)=?, 所以计算机把存储的7和-5对应的补码拿过来直接相加 0111+1011=0001 0010 ,我们看到数据溢出了,不过只要看后四位就行!我们要清楚计算所得的0010是直接存储在计算机中的!所以0010本质上来说是最终计算结果所对应二进制的补码(补码+补码=补码)。也就说我们要将0010这个补码逆推回所需要的原码,后四位0010的高位为0,显然是正数,那么0010这个补码对应的原码依然是0010!0010转换为十进制是2,7-5=2成立!

再来看个例子2:

十进制整数 二进制原码 二进制补码
7 0000 0111 0000 0111
-8 1000 1000 1111 1000

7-8=7+(-8)=? —> 0000 0111 + 1111 1000=1111 1111 ,这次我们发现得到1111 1111 这个补码的高位是1,这就表明该补码对应的原码是一个负数。

对于负整数来说:补码=(原码)取反+1,那么原码=(补码-1)取反,注意取反时符号位不变!

1111 1111 -0000 0001=1111 1110 —>取反—> 1000 0001,很显然这个原码表示十进制的-1 ,7-8=-1成立!

(4)小数的码

-1.25 = 原码[1001.0100] = 反码[1110.1011]=补码[1110.1100]
3.75 = 原码[0011.1100] = 反码[0011.1100] = 补码[0011.1100]

(5)byte范围为(-128 ~ 127) 是为啥

我们知道byte整型使用一个字节,也就是8位(bit)来表示二进制数据,那么直观的看应该是这样:

正数范围: 0000 0000 ~0111 1111

负数范围: 1000 0000 ~1111 1111

那么很显然 :

 0000 0000 表示+0 

 0111 1111  表示+127

那么 1000 0000难道表示 -0 ,1111 1111表示-127 ??? 那我们在取值范围看到的-128是哪来的???当然不是!!

首先我们来解释1000 0000为什么不能代表 -0, 准确的说是为什么不能有 -0的存在!

1000 0000不能表示 -0 的原因

在数学中我们知道0既不是正数也不是负数,但是在计算机中由于二进制数据的高位不是0就是1 ,也就是说不是正数就是负数,因此二进制只能把0归为正数或负数,而将0表示为0000 0000 是非常自然的!所以说规定0在二进制中其实是一个正数,也就是+0!那么当然就不允许有-0这种形式的出现了,计算机不可能将一个数据以两种形式存放,否则会导致混乱,那么为了让1000 0000 不被闲置,我们自然地想让它表示其余某一个数!那么表示什么数呢?这里我们先放一放

1111 1111不能表示-127的原因

这其实是初学者极其容易犯的毛病,之前讲过,对于计算机来说,并不存在原码和反码,计算机存储的二进制数据都是以补码的形式存放的,因此对于1111 1111这个二进制数据来说,如果我们要得到它的十进制数据是需要求其原码的,显然1111 1111的原码(补码-1后取反)是-1才对!也就是说对于计算机来说1111 1111代表的就是-1。因此我们也可以容易的得到1000 0001表示的才是-127。其实更广义的说,不只是1000 0000 ,只要是所有多字节二进制数中,最高位为1 其余位都为0的二进制数据都使用人为表示的1个数,这个数在十进制中就是-2^n (n表示除符号位以外的其余位位数)

例如2个字节的二进制数据1000 0000 0000 0000 表示-2^15=-32768 ;

注意 如1000 0000 0000其实是0000 1000 0000 0000,所以它不是以为的-2^11,而是2^11

综上所述

0000 0000 ~0111 1111 表示 +0 ~ +127

1111 1111 ~1000 0001 表示 -1 ~ -127

-128的表示

咦,我们好像漏了 1000 0000 这个二进制了,哈哈,到现在为止一切都解决了,其实我们人为规定 1000 0000表示十进制中的-128!当然我们不可能说通过 1000 0000这种二进制求其原码得到某一个数,因为非高位全是0,无法再借位减1了!

其实这种规定是很自然的,1000 0000 -0000 0001=0111 1111,而0111 1111 这个补码表示的是+127,我们可以将 1000 0000这个二进制作为正数和负数之间的一个分水岭(尽管1000 0000本身代表负数),1000 0000再进位就会进入负数范围,若借位就会进入正数范围,就好似1000 0000(-128)将 1000 0001(-127) ~0111 1111(+127)首尾连接了起来形成了一个闭环!!!

原码里面这个是负0,补码里面按照定义他就是-128

码长八位时,各码的范围如下。
原码:-127 ~ +127。
反码:-127 ~ +127。
补码:-128 ~ +127。

-128,没有原码反码,只有补码。

3、存储

单位 符号 备注
位(比特) bit (b) 计算机最小的存储单位
字节 byte (B) 数据表示的最小单位:1B = 8bit
千字节 KB 1KB = 1024B
兆字节 MB
吉字节 GB
太字节 TB

字节(Byte)是计算机信息技术用于计量存储容量的一种计量单位,也表示一些计算机编程语言中的数据类型和语言字符 。

一个字节存储8位无符号数,储存的数值范围为0-255。所以不能表示负数。

数据存储是以“字节”(Byte)为单位,数据传输大多是以“位”(bit,又名“比特”)为单位,一个位就代表一个0或1(即二进制),每8个位(bit,简写为b)组成一个字节(Byte,简写为B),是最小一级的信息单位。

java基本数据类型占用字节数

Java的基本数据类型的占用字节数是固定的,如下所示:

数据类型 占用字节数
byte 1
short 2
int 4
long 8
float 4
double 8
char 2
boolean 1

需要注意的是,这些占用字节数只是一般情况下的默认值,具体的实现可能会因平台和实现版本而有所不同。此外,Java还提供了包装类来对这些基本数据类型进行包装,使用时需要注意包装类的占用字节数可能会比基本数据类型更大。

4、字符集

在不同的字符集中,中文和标点的占用字节数是不同的。以下是各个字符集中文和标点占用字节数的列表:

  • ASCII码: ASCII码只包含128个字符,不支持中文和标点。美国标准信息交换码,用一个字节的7位可以表示。
  • GB2312: GB2312是中国境内最广泛使用的中文字符集,一个中文字符占用两个字节,一个英文字符占用一个字节,一个标点符号占用一个字节。
  • GBK:GBK是GB2312的扩展字符集,包括了更多的汉字。一个中文字符占用两个字节,一个英文字符占用一个字节,一个标点符号占用一个字节。
  • Unicode:Unicode是一种国际标准字符集,覆盖了各种语言的字符。在Unicode中,一个中文字符占用两个字节,一个英文字符占用两个字节,一个标点符号占用两个字节。
  • UTF-8:UTF-8是一种以字节为单位对Unicode进行编码的变长字符集。在UTF-8中,一个中文字符占用三个字节,一个英文字符占用一个字节,一个标点符号占用一个字节。
  • UTF-16:UTF-16是一种以字节为单位对Unicode进行编码的定长字符集。在UTF-16中,一个中文字符占用两个字节,一个英文字符占用两个字节,一个标点符号占用两个字节。

需要注意的是,以上仅是各个字符集中文和标点占用字节数的一般规则,具体情况可能因为具体的编码实现而有所不同。

编码 汉字占用字节数 字母占用字节数 英文标点 中文标点
ASCII 无汉字 1 1
UTF-8 3 1 1 3
UTF-16 2 2 2 2
UTF-32 4 4
GBK 2 1 1 2
Unicode 2 2

另外:
1、Unicode的落地实现是utf-8和utf-16

2、utf-8的优点是:传输效率高;utf-16的优点是:内存中存储效率高

5、校验码

(1)码距

码距:是指一个编码系统中任意两个合法编码之间至少有多少个二进制位不同。

码距是指两个不同的码组(或码字),它们对应码位上不同码元的数目。在更具体的语境下,对于两个同样长度(码元位数都为n)的码字,它们对应码位上不相同码元的数目被称为这两个码字之间的汉明码距,简称码距。把所有可能的码字对之间码距的最小值称为这个码字集合的最小距离,即最小码距。码距也被称为汉明距离。

码距在通信和编码理论中具有重要意义。在数据传输或存储过程中,由于各种原因可能会出现错误。通过计算接收到的码字与原始码字之间的码距,可以检测到这些错误,并在一定程度上进行纠正。特别是在纠错编码中,最小码距决定了编码方案能够检测和纠正错误的数量。较大的最小码距通常意味着更强的错误检测和纠正能力。

例如,在二进制编码中,如果两个码字分别为0011和0001,它们之间只有一位不同,因此这一组码字的码距为1。如果另一个码字为1111,则它与0011之间的码距为2,因为它们有两位不同。

总的来说,码距是编码理论中用于衡量码字之间差异的一个重要参数,对于错误检测和纠正具有重要意义

(2)奇偶校验码

可以检错,不能纠错

奇偶校验:奇偶校验是一种用于检测数据传输或存储中错误的方法。它通过在数据后面添加一个校验位,使得整个数据(包括校验位)中“1”的个数为奇数(奇校验)或偶数(偶校验)。接收方收到数据后,会检查“1”的个数是否符合预定的奇偶性,如果不符合,则说明数据传输过程中出现了错误。

通过在编码中增加一位校验位来使编码中1的个数为奇数(奇校验)或者为偶数(偶校验),从而使码距变为2。

(3)海明码

可以检错和纠错

海明码:海明码是奇偶校验的一种扩充。在数据位之间的特定位置上插入k个校验位,通过扩大码距来实现检错和纠错。

设数据位是n位,校验位是k位,则n和k必须满足:2^k- 1 ≥ n + k

(4)循环冗余校验

循环冗余校验:采用模二除法运算。CRC的编码方法是:在k位信息位之后拼接r位校验位。

二、计算机系统的基本硬件组成

计算机系统的基本硬件由输入设备、运算器、控制器、存储器、输出设备五大部件组成。

  • 中央处理器(CPU)硬件系统的核心
    • 运算器
    • 控制器
  • 存储器(记忆设备)
    • 内部存储器,高速内存,速度快,容量小:临时存放程序、数据、及中间结果
    • 外部存储器,硬盘,速度慢,容量大:长期保存的程序和数据
  • 外部设备
    • 输入设备:输入原始数据和命令
    • 输出设备:输出计算机运行结果

1、CPU

中央处理单元(CPU):计算机系统的核心部件,它负责获取程序指令,对指令进行译码并加以执行

(1)CPU的功能

  • 程序控制:通过执行指令来控制程序的执行顺序

  • 操作控制:一条指令功能的实现需要若干个操作信号配合来完成,CPU产生每条指令的操作信号并将操作信号送往对应的部件,控制相应的部件按指令的功能要求进行操作

  • 时间控制:CPU对各种操作进行时间上的控制,即在指令执行过程中操作信号的出现时间,持续时间及出现的 时间顺序都需要进行严格的控制

  • 数据处理:CPU通过对数据进行算术运算及逻辑运算等方式进行加工处理,数据加工处理的结果被人们所利 用。所以,对数据的加工处理也是CPU最根本的任务

  • CPU还需对系统内部和外部的中断(异常)做出响应,进行相应的处理

(2)CPU的组成

运算器

运算器(是数据加工处理部件,用于完成计算机的各种算术和逻辑运算):运算器所进行的全部操作都是由 控制器发出的控制信号来指挥的,所以它是执行部件

  • 功能
    • 执行所有算术运算,如加、减、乘、除等基本运算及附加运算。
    • 执行所有的逻辑运算并进行逻辑测试,如与、或、非、零值测试或两个值的比较等。
  • 组成
    • 算术逻辑单元(ALU):负责处理数据,实现对数据的算术运算和逻辑运算。
    • 累加寄存器(AC):简称累加器,是一个通用寄存器。暂存算术运算或逻辑运算的中间运算结果。
  • 数据缓冲寄存器(DR):暂存指令或数据字或操作数。
  • 状态条件寄存器(PSW):保存指令执行后的状态。

控制器

功能

  • 用于控制整个CPU的工作,决定了计算机运行过程的自动化。它不仅要保证程序的正确执行,而且能够 处理异常事件

组成

  • 指令控制逻辑:要完成取指令、分析指令和执行指令的操作,其过程分为取指令,指令译码按指令操作 码执行,形成下一条指令地址等步骤。
    • 指令寄存器(IR):存放的是从内存中取得指令,就像个中间站一样,不过是存放指令的中间站
    • 程序计数器(PC):存放的是指令的地址,还有计数的功能
    • 地址寄存器(AR):存放的是cpu访问内存单元的地址
    • 指令译码器(ID):是把操作码解析成对应的指令操作
  • 时序控制逻辑:要为每条指令按时间顺序提供应有的控制信号
  • 总线控制逻辑:是为多个功能部件服务的信息通路的控制电路
  • 中断控制逻辑:用于控制各种中断请求,并根据优先级的高低对中断请求进行排队,逐个交给CPU

寄存器组

分类:专用寄存器(运算器和控制器中的寄存器是专用寄存器)、通用寄存器

七、CPU

CPU主要由运算器、控制器、寄存器组和内部总线等部件组成。

  • 运算器:运算器由算术逻辑单元、累加寄存器、数据缓冲寄存器和状态条件寄存器组成。

  • 控制器:用于控制整个CPU的工作。

    • 指令寄存器(IR):存放即将执行的指令
    • 程序计数器(PC):存放下一条要执行的指令地址
    • 地址寄存器(AR):保存当前CPU所访问的内存单元地址
    • 指令译码器(ID):指令分为操作码和地址码两部分,为了能执行所有给定的指令,必须对操作码进行分析,以便识别所完成的操作。指令译码器可对指令中的操作码字段进行分析和解释,识别该指令规定的操作,向操作控制器发出具体的控制信号,控制各部件工作,从而完成所需的功能。
  • 存储器:存储器的层次结构:

img

由硬件自动完成 Cache与主存之间的地址映射

主存与Cache的地址映射方式:

  • 全相联映射:主存的任意一块都可以映射到Cache中的任意一行。
  • 直接映射:主存的每一个块都只能映射到Cache中的某一特定行。
  • 组相联映射:Cache被分成若干个组,每组包含若干行。主存的每一个块都可以映射到Cache中的某一个组的任意一行。

  目录