1.1 计算机系统基础知识 1.1.1 计算机系统硬件基本组成
计算机系统是由硬件和软件组成的,它们协同工作来运行程序。计算机的基本硬件系统由运算器、控制器、存储器、输入设备和输出设备5大部件组成。运算器、控制器等部件被集成在一起统称为中央处理单元(Central Processing Unit,CPU)。CPU是硬件系统的核心,用于数据的加工处理,能完成各种算术、逻辑运算及控制功能。存储器是计算机系统中的记忆设备,分为内部存储器和外部存储器。前者速度高、容量小,一般用于临时存放程序、数据及中间结果。而后者容量大、速度慢,可以长期保存程序和数据。输入设备和输出设备合称为外部设备(简称外设),输入设备用于输入原始数据及各种命令,而输出设备则用于输出计算机运行的结果。
1.1.2 中央处理单元
中央处理单元(CPU)是计算机系统的核心部件,它负责获取程序指令、对指令进行译码并加以执行。
1. CPU的功能
(1)程序控制。CPU通过执行指令来控制程序的执行顺序,这是CPU的重要功能。
(2)操作控制。一条指令功能的实现需要若干操作信号配合来完成,CPU产生每条指令的操作信号并将操作信号送往对应的部件,控制相应的部件按指令的功能要求进行操作。
(3)时间控制。CPU对各种操作进行时间上的控制,即指令执行过程中操作信号的出现时间、持续时间及出现的时间顺序都需要进行严格控制。
(4)数据处理。CPU通过对数据进行算术运算及逻辑运算等方式进行加工处理,数据加工处理的结果被人们所利用。所以,对数据的加工处理也是CPU**根本的任务。
此外,CPU还需要对系统内部和外部的中断(异常)做出响应,进行相应的处理。
2. CPU的组成
CPU主要由运算器、控制器、寄存器组和内部总线等部件组成,如下图所示。
1)运算器
运算器由算术逻辑单元(Arithmetic and Logic Unit,ALU)、累加寄存器、数据缓冲寄存器和状态条件寄存器等组成,它是数据加工处理部件,用于完成计算机的各种算术和逻辑运算。相对控制器而言,运算器接受控制器的命令而进行动作,即运算器所进行的全部操作都是由控制器发出的控制信号来指挥的,所以它是执行部件。运算器有如下两个主要功能。
(1)执行所有的算术运算,例如加、减、乘、除等基本运算及附加运算。
(2)执行所有的逻辑运算并进行逻辑测试,例如与、或、非、零值测试或两个值的比较等。
下面简要介绍运算器中各组成部件的功能。
(1)算术逻辑单元(ALU)。ALU是运算器的重要组成部件,负责处理数据,实现对数据的算术运算和逻辑运算。
(2)累加寄存器(AC)。AC通常简称为累加器,它是一个通用寄存器,其功能是当运算器的算术逻辑单元执行算术或逻辑运算时,为ALU提供一个工作区。例如,在执行一个减法运算前,先将被减数取出暂存在AC中,再从内存储器中取出减数,然后同AC的内容相减,将所得的结果送回AC中。运算的结果是放在累加器中的,运算器中至少要有一个累加寄存器。
(3)数据缓冲寄存器(DR)。在对内存储器进行读/写操作时,用DR暂时存放由内存储器读/写的一条指令或一个数据字,将不同时间段内读/写的数据隔离开来。DR的主要作用为作为CPU和内存、外部设备之间数据传送的中转站:作为CPU和内存、外围设备之间在操作速度上的缓冲。在单累加器结构的运算器中,数据缓冲寄存器还可兼作为操作数寄存器。
(4)状态条件寄存器(PSW)。PSW保存由算术指令和逻辑指令运行或测试的结果建立的各种条件码内容。主要分为状态标志和控制标志,例如运算结果进位标志(C)、运算结果溢出标志(V)、运算结果为0标志(Z)、运算结果为负标志(N)、中断标志(I)、方向标志(D)和单步标志等。这些标志通常分别由1位触发器保存,保存了当前指令执行完成之后的状态。通常,一个算术操作产生一个运算结果,而一个逻辑操作产生一个判决。
2)控制器
运算器只能完成运算,而控制器用于控制整个CPU的工作,它决定了计算机运行过程的自动化。它不**要**程序的正确执行,而且要能够处理异常事件。控制器一般包括指令控制逻辑、时序控制逻辑、总线控制逻辑和中断控制逻辑等几个部分。
指令控制逻辑要完成取指令、分析指令和执行指令的操作,其过程分为取指令、指令译码、按指令操作码执行、形成下一条指令地址等步骤:
(1)指令寄存器(IR)当CPU执行一条指令时,先把它从内存储器取到缓冲寄存器中,再送入IR暂存,指令译码器根据IR的内容产生各种微操作指令,控制其他的组成部件工作,完成所需的功能。
(2)程序计数器(PC)。PC具有寄存信息和计数两种功能,又称为指令计数器。程序的执行分两种情况,一是顺序执行,二是转移执行。在程序开始执行前,将程序的起始地址送入PC,该地址在程序加载到内存时确定,因此PC的内容即是程序**条指令的地址。执行指令时,CPU自动修改pc的内容,以便使其保持的总是将要执行的下一条指令的地址。由于大多数指令都是按顺序来执行的,所以修改的过程通常只是简单地对pc加1。当遇到转移指令时,后继指令的地址根据当前指令的地址加上一个向前或向后转移的位移量得到,或者根据转移指令给出的直接转移的地址得到。
(3)地址寄存器(AR)。AR保存当前CPU所访问的内存单元的地址。由于内存和CPU存在着操作速度上的差异,所以需要使用AR保持地址信息,直到内存的读/写操作完成为止。
(4)指令译码器(ID)。指令包含操作码和地址码两部分,为了能执行任何给定的指令,必须对操作码进行分析,以便识别所完成的操作。指令译码器就是对指令中的操作码字段进行分析解释,识别该指令规定的操作,向操作控制器发出具体的控制信号,控制各部件工作,成所需的功能。
时序控制逻辑要为每条指令按时间顺序提供应有的控制信号。总线逻辑是为多个功能部件服务的信息通路的控制电路。中断控制逻辑用于控制各种中断请求,并根据优先级的高低对中断请求进行排队,逐个交给CPU处理。
3)寄存器组
寄存器组可分为专用寄存器和通用寄存器。运算器和控制器中的寄存器是专用寄存器,其作用是固定的。通用寄存器用途广泛并可由程序员规定其用途,其数目因处理器不同有所差异。
3. 多核CPU
核心又称为内核,是CPU**重要的组成部分。CPU中心那块隆起的芯片就是核心,是由单晶硅以一定的生产工艺制造出来的,CPU所有的计算、接收/存储命令、处理数据都由核心执行。各种CPU核心都具有固定的逻辑结构,一级缓存、二级缓存、执行单元、指令级单元和总线接口等逻辑单元都会有合理的布局。
多核即在一个单芯片上面集成两个甚至更多个处理器内核,其中,每个内核都有自己的逻辑单元、控制单元、中断处理器、运算单元,一级Cache、二级Cache共享或独有,其部件的完整性和单核处理器内核相比完全一致。
CPU的主要厂商AMD和Intel的双核技术在物理结构上有所不同。AMD将两个内核做在一个Die(晶元)上,通过直连架构连接起来,集成度更高。Intel则是将放在不同核心上的两个内核封装在一起,因此将Intel的方案称为“双芯”,将AMD的方案称为“双核”。从用户端的角度来看,AMD的方案能够使双核CPU的管脚、功耗等指标跟单核CPU保持一致,从单核升级到双核,不需要更换电源、芯片组、散热系统和主板,只需要刷新BIOS软件即可。
多核CPU系统**的优点(也是开发的**主要目的)是可满足用户同时进行多任务处理的要求。
单核多线程CPU是交替地转换执行多个任务,只不过交替转换的时间很短,用户一般感觉不出来。如果同时执行的任务太多,就会感觉到“慢”或者“卡”。而多核在理论上则是在任何时间内每个核执行各自的任务,不存在交替问题。因此,单核多线程和多核(一般每个核也是多线程的)虽然都可以执行多任务,但多核的速度更快。
虽然采用了Intel超线程技术的单核可以视为是双核,4核可以视为是8核。然而,视为是8核一般比不上实际是8核的CPU性能。
要发挥CPU的多核性能,就需要操作系统能够及时、合理地给各个核分配任务和资源(如缓存、总线、内存等),也需要应用软件在运行时可以把并行的线程同时交付给多个核心分别处理。
1.1.3 数据表示
各种数值在计算机中表示的形式称为机器数,其特点是采用二进制计数制,数的符号用0和1表示,小数点则隐含,表示不占位置。机器数对应的实际数值称为数的真值。
机器数有无符号数和带符号数之分。无符号数表示正数,在机器数中没有符号位。对于无符号数,若约定小数点的位置在机器数的**位之后,则是纯整数:若约定小数点的位置在机器数的**位之前,则是纯小数。对于带符号数,机器数的**位是表示正、负的符号位,其余位则表示数值。
为了便于运算,带符号的机器数可采用原码、反码和补码等不同的编码方法,机器数的这些编码方法称为码制。
1. 原码、反码、补码和移码
1)原码表示法
数值X的原码记为 原 ,如果机器字长为n(即采用n个二进制位表示数据),则原码的定义如下:
若X是整数,则 原
若X是纯小数,则 原
在原码表示中,**位是符号位,0表示正号,1表示负号,其余的n - 1位表示数值的**值。数值0的原码表示有两种形式: 原原 。
2)反码表示法
数值X的反码记作 反 ,如果机器字长为n,则反码的定义如下:
若X是整数,则 反
若X是纯小数,则 反
在反码表示中,**位是符号位,0表示正号,1表示负号,正数的反码和原码相同,负数的反码则是其**值按位求反。数值0的原码表示有两种形式: 反反 。
3)补码表示法
数值X的补码记作 补 ,如果机器字长为n,则补码的定义如下:
若X是整数,则 补
若X是纯小数,则 补
在补码表示中,**位是符号位,0表示正号,1表示负号,正数的反码和其原码和反码相同,负数的补码则是其反码的末位加1。在补码表示中,数值0有**的编码: 补补 。
4)移码表示法
移码表示法是在数X上增加一个偏移量来定义的,常用于表示浮点数中的阶码。如果机器字长为n,规定偏移量为 ,则移码的定义如下:
若X是整数,则 移
若X是纯小数,则 移
2. 定点数和浮点数
1)定点数
所谓定点数,就是小数点的位置固定不变的数。小数点的位置约定方式:定点整数(整数,小数点在**有效数值位之后)和定点小数(纯小数,小数点在**有效数值位之前)。
设机器字长为n,各种码制下带符号数的范围如下表所示。
码值 定点整数 定点小数
原码
反码
补码
移码
2)浮点数
当机器字长为n时,定点数的补码和移码可表示 个数,而其原码和反码只能表示 个数(0的表示占用了两个编码),因此,定点数所能表示的数值范围比较小,在运算中很容易因结果超出范围而溢出。浮点数是小数点位置不固定的数,它能表示更大范围的数。
在十进制中,一个数可以写成多种表示形式。例如,83.125可写成 或 等。同样,一个二进制数也可以写成多种表示形式。例如,二进制数1011.10101可以写成 、 或 等。由此可知,一个二进制数N可以表示为更一般的形式 ,其中E称为阶码,F称为尾数。用阶码和尾数表示的数称为浮点数,这种表示数的方法称为浮点表示法。
在浮点表示法中,阶码为带符号的纯整数,尾数为带符号的纯小数。浮点数的表示格式如下:
阶符 阶码 数符 尾数
很明显,一个数的浮点表示不是**的。当小数点的位置改变时,阶码也随着相应改变,因此可以用多个浮点形式表示同一个数。
浮点数所能表示的数值范围主要由阶码决定,所表示数值的精度则由尾数决定。为了充分利用尾数来表示更多的有效数字,通常采用规格化浮点数。规格化就是将尾数的**值限定在区间[0.5, 1]。当尾数用补码表示时,需要注意如下问题。
①若尾数 ,则其规格化的尾数形式为M = 0.1xxx…x,其中,x可为0,也可为1,即将尾数限定在区间[0.5, 1]。
②若尾数M < 0,则其规格化的尾数形式为M = 1.0xxx…x,其中,x可为0,也可为1,即将尾数M的范围限定在区间[-1, -0.5]。
如果浮点数的阶码(包括1位阶符)用R位的移码表示,尾数(包括1位数符)用M位的补码表示,则这种浮点数所能表示的数值范围如下。
**的正数:
**小的负数:
(3)工业标准IEEE 754。IEEE 754是由IEEE制定的有关浮点数的工业标准,被广泛采用。该标准的表示形式如下:
其中, 为该浮点数的数符,当S为0时表示正数,S为1时表示负数;E为指数(阶码),用移码表示; ,其长度为P位,用原码表示。
目前,计算机中主要使用3种形式的IEEE 754浮点数,如下表所示。
参数 单精度浮点数 双精度浮点数 扩充精度浮点数
浮点数字长 32 64 80
尾数长度P 23 52 64
符号位S 1 1 1
指数长度E 8 11 15
**指数 +127 +1023 +16383
**小指数 -126 -1022 -16382
指数偏移量 +127 +1023 +16383
可表示的实数范围
根据IEEE 754标准,被编码的值分为3种不同的情况:规格化的值、非规格化的值和特殊值,规格化的值为**普遍的情形。
①规格化的值。
当阶码部分的二进制值不全为0也不全为1时,所表示的是规格化的值。例如,在单精度浮点格式下,阶码为10110011时,偏移量为+127(01111111),则其表示的真值为10110011 - 01111111 = 00110100,转换为十进制后为52。
对于尾数部分,由于约定小数点左边隐含有一位,通常这位数就是1,因此单精度浮点数尾数的有效位数为24位,即尾数为1.xx...x。也就是说,不溢出的情况下尾数M的值在 之中,这是一种获得一个额外精度位的表示技巧。
例如,单精度浮点数格式下, 时,其对应的尾数真值为 ,即尾数的真值为1.28724038600921630859375(在程序中以十进制方式输出时,由于精度的原因不能完全给出此值)。
【例1.5】利用IEEE 754标准将数176.0625表示为单精度浮点数。 故其指数部分为 ,尾数部分开头为 。
1.1.4 校验码
计算机系统运行时,为了确保数据在传送过程中正确无误,一是提高硬件电路的可靠性,二是提高代码的校验能力,包括查错和纠错。通常使用校验码的方法来检测传送的数据是否出错。其基本思想是把数据可能出现的编码分为两类:合法编码和错误编码。合法编码用于传送数据,错误编码是不允许在数据中出现的编码。合理地设计错误编码以及编码规则,使得数据在传送中出现某种错误时会变成错误编码,这样就可以检测出接收到的数据是否有错。
所谓码距,是指一个编码系统中任意两个合法编码之间至少有多少个二进制位不同。例如,4位8421码的码距为1,在传输过程中,该代码的一位或多位发生错误,都将变成另外一个合法的编码,因此这种代码无检错能力。下面简要介绍常用的3种校验码:奇偶校验码、海明码和循环冗余校验码。
1. 奇偶校验码
奇偶校验(Parity Codes)是一种简单有效的校验方法。这种方法通过在编码中增加一位校验位来使编码中1的个数为奇数(奇校验)或者为偶数(偶校验),从而使码距变为2。对于奇校验,它可以检测代码中奇数位出错的编码,但不能发现偶数位出错的情况,即当合法编码中的奇数位发生了错误时,即编码中的1变成0或0变成1,则该编码中1的个数的奇偶性就发生了变化,从而可以发现错误。
常用的奇偶校验码有3种:水平奇偶校验码、垂直奇偶校验码和水平垂直校验码。
2. 海明码
海明码(Hamming Code)是由贝尔实验室的Richard Hamming设计的,是一种利用奇偶性来检错和纠错的校验方法。海明码的构成方法是在数据位之间的特定位置上插入k个校验位,通过扩大码距来实现检错和纠错。
设数据位是n位,校验位是k位,则n和k必须满足以下关系:
海明码的编码规则如下:
设k个校验位为 , ,……, ,n个数据位为 , ,……, , ,对应的海明码为 , ,……, ,那么:
(1) 在海明码的第 位置,即 ,且 ,数据位则依序从低到高占据海明码中剩下的位置。
(2)海明码中的任何一位都是由若干个校验位来校验的。其对应关系如下;被校验的海明位的下标等于所有参与校验该位的校验位的下标之和,而校验位由自身校验。
对于8位的数据位,进行海明校验需要4个校验位( , )。令数据位为 , ,……, , ,校验位为 , , , ,形成的海明码为 , ,……, , ,则编码过程如下:
(1)确定D与P在海明码中的位置,如下所示:
(2)确定校验关系,如下表所示:
若采用奇校验,则将各校验位的偶校验值取反即可。
(3)检测错误。对使用海明编码的数据进行差错检测很简单,只需做以下计算:
若采用偶校验,则 全为0时表示接收到的数据无错误(奇校验应全为1)。当 不全为0时说明发生了差错,而且 的十进制值指出了发生错误的位置,例如 ,说明 ( )出错了,将其取反即可纠正错误。
3. 循环冗余校验码
循环冗余校验码(Cyclic Redundancy Check,CRC)广泛应用于数据通信领域和磁介质存储系统中。它利用生成多项式为k个数据位产生r个校验位来进行编码,其编码长度为k + r。CRC的代码格式为:
由此可知,循环冗余校验码是由两部分组成的,左边为信息码(数据),右边为校验码。若信息码占k位,则校验码就占n-k位。其中,n为CRC码的字长,所以又称为(n,k)码。校验码是由信息码产生的,校验码位数越多,该代码的校验能力就越强。在求CRC编码时,采用的是模2运算。模2加减运算的规则是按位运算,不发生借位和进位。