计算机系统概论第二章.doc_第1页
计算机系统概论第二章.doc_第2页
计算机系统概论第二章.doc_第3页
计算机系统概论第二章.doc_第4页
计算机系统概论第二章.doc_第5页
已阅读5页,还剩13页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

第二章 比特,数据类型和运算2.1比特和数据类型2.1.1 信息的最小单位比特我们在第一章中提到,计算机是一个由多个层次组织起来的系统。在计算机中通过电子的流动,一个用自然语言描述的问题可以轻而易举的得到解决。在计算机的内部,数以亿计非常微小、快速的元件控制着电子的流动。这些元件对电路中电压的有无做出反应。事实上,它们可以对电压具体的数值做出反应,而不仅仅是对电压的有无做出反应。但是这样会使控制电路和探测电路变得非常复杂而没有多少实际用途,因此在实际的应用中往往是探测两点之间电压的有无而不是测量电压的具体值。要明白这些,先想一想家中的插座孔,你可以测量一下两孔间电压具体的值,比如,是120伏特呢,还是115伏特,或者是118.6伏特。但是电路系统只会探测电压是否存在,因为这样更简单。如果你想测量电压值,那么你还需要一组仪器,而如果想探测电压是否存在,把你的手指伸进去就足够了。我们把存在电压用“1”表示,而把不存在电压用“0”表示,我们称这一个个的“0”和“1”为比特(bit),或位,是“二进制位”(binary digit)的缩写。想想你从小就使用的0,1,2,3,4,5,6,7,8,9,它们是十进制数,用十个符号表示,而二进制只有两个表示数的符号:0和1。更精确的说,计算机并不是区分电压的绝对不存在(即0)和绝对存在(即1)。实际上,计算机的电路区分的是接近0的电压和远离0的电压。例如,如果计算机把2.9伏的电压表示为1,把0伏的电压表示为0,那么2.6伏的电压也会被视作1,而0.2伏的电压会被当作0。计算机要解决一个真正的问题,必须能唯一的识别出许多不同的数值,而不仅仅是0和1。一根线路上的电压只能唯一的表示两个数值中的一个,一个表示为0,另一个表示为1。这样,为了唯一的识别出多个数值,必须对多个位进行组合。例如,如果我们用8位(对应8根线路上的电压),我们就能用01001110表示某一个特定值,用11100111表示另一个值。事实上,如果我们使用8位,最多能区分出256(即28)个不同的值。一般说来,如果有k位,我们最多能区分出2k个不同的值。这些k位的每一种组合都是一个编码,对应着某个特定的值。2.1.2 数据类型对于表示同一个数值,存在许多种表示方法。例如,数字5可以被写为5。这是你习惯的标准的十进制计数法。它也可以被一个人用伸出的手指数来表示,这种方法写下来就是11111,这种计数法有个名字一元计数法。罗马字中还有另一种表示5的符号字符v。我们即将会看到5的第四种符号表示是二进制00000101。只是简单的表示这些数值还不够,我们还必须能对这些数值进行运算。如果在计算机上能对以某种表示法编码的信息进行运算,我们就把这种特殊的表示法称为数据类型。每种指令集结构都有它自己的数据类型集,和对那些数据类型进行运算的指令集。在本书中,我们主要使用两种数据类型:用来表示我们要进行算术运算的正负整数的二进制补码整数,和用来表示我们想输入计算机或显示在计算机显示器上的键盘上的字符的ASCII码。在后面就会解释这两种数据类型。事实上,在大多数计算机上还存在着多种数值表示方法。回忆在中学学习过的“科学计数法”,它要求你将十进制数621表示为6.21*102。在计算机中,也存在以这种形式表示的数字,并且也提供了对这种表示法的数值的运算。这种数据类型通常被称为浮点数。我们将在2.6节展示这种表示法。2.2 整数数据类型2.2.1 无符号整数我们即将看到的第一种信息的表示方法,或数据类型是无符号整数。无符号整数在计算机中有很多用途。如果我们想将某个任务执行有限次,可以使用无符号整数,表示该任务已经执行的次数。计算机中的存储单元的地址,就像房屋的地址一样,可以通过“某大街129号”和“某大街131号”来区分,也可以使用无符号整数来表示。首先回忆一下我们日常使用的十进制系统。在一个十进制数329中,尽管单独的3的绝对值只是9的1/3,但这里的3表示比9大得多的值。原因就在于这个3在329中的位置决定了它表示300(3*102),而9则表示9*100 。这就是位置计数法,或称为定位数制。在十进制系统里,10被称为数制中的基数或基。在计算机中,可以使用类似的采用位置计数法的一串二进制数来表示无符号型整数,不同的是基数为2,二进制数为0和1。例如:如果我们使用5位有效数字来表示我们需要的数值,则数字6可以表示为00110,即:0*24+0*23+1*22+1*21+0*20使用k位数,就可以表示从0到2k-1共2k个整数。使用5位数,可以表示十进制整数0到31。2.2.2 有符号整数然而在实际的计算中,还经常会使用负数,因此只有无符号整数是不够的。为了表示有符号整数,我们可以将k位的2k个不同的数字分为两半,一半表示正数,另一半表示负数。这样,使用5位码字就可以表示从+1到+15的正数,以及从-1到-15的负数。这样,就有30个整数被表示出来。因为25是32,那么,还有两个5位的码字没有被分配。其中一个是00000,如果将其分配给数值0,现在,就得到一个从-15到+15的完整的整数值系列。还留下最后一个数没有分配,对于如何对其进行分配的问题,首先需要考虑的是从+1到+15,从-1到-15,到底是哪些码字与其一一匹配的?首先,正数是按照位置计数法直接表示的。因为有k位,而且我们想要用2k个码字的一半来表示从0到2k-1-1的正数,所有的正数在它们的表示法中都会在最高位有一个0。在k5的情况下,最大的正数15使用01111来表示。注意在图2.1的三种数据类型中,0和所有正数都是以0开头。那么,负数是如何表示的呢(在k5的情况下,从-1到-15)?通常,第一个想法就是:如果最高位为0表示是正数,那么把该数字的最高位设为1就表示其对应的负数。这种表示法就是原码数据类型,见图2.1。第二个想法是(这种方法实际上曾经在某些早期的计算机上使用过,如数据控制公司6600):对正数“按位取反”,就表示与其绝对值大小相同、符号相反的负数,例如,+5是用00101来表示的,那么-5就被记作11010。这种表示法在计算机工程中被称为反码,见图2.1。计算机设计者可以用任意的位组合来表示任意整数。但是究竟采用哪种表示方法呢?实际上,原码和反码在设计加法逻辑电路时,都会使问题复杂化。原码和反码在进行加法运算时都会造成不必要的硬件需求,于是就出现了补码表示法,见图2.1。补码被运用于现在的每一台机器之中。2.3 二进制补码整数我们在图2.1中看到了从-16到+15的二进制补码表示法。为什么要采用这种表示法呢?首先,正整数使用直接的位置计数法来表示。对于5位而言,我们使用了25的一半的码字来表示整数0到+15。对负数表示法的选择是基于尽可能使逻辑电路最简单的想法,几乎所有的计算机都使用相同的基本结构来进行加法运算。它被称之为算术逻辑单元,也就是我们所知道的取首字母缩写的ALU。我们将在3、4章介绍ALU的真正结构。现在只需要了解:一个ALU有两个输入和一个输出。在它进行运算时,它将要相加的两个二进制位组合作为输入,求和产生的一个二进制位组合作为输出。例如,如果ALU能进行5位的输入组合的运算,两个输入值为00110和00101,结果(ALU的输出)是01011。加法过程如下: 00110 + 00101=01011两个二进制位组合的加法和两个十进制位组合的加法相同,从右向左,一列一列的运算。如果一列的加法有进位,进位立即加至它的左列。值的一提是二进制ALU并不知道(也不关心)所加的两个位组合表示什么。它只是简单的将二进制数相加。ALU只做加法而不考虑其他,这一点将对我们为整数分配码字十分有利。首先考虑,如何分配码字表示一个数(或字符)的若干位二进制代码。,使得两个绝对值相同符号相反的整数在ALU做加法的结果为0。也就是说,如果对ALU的输入是A与-A的表示,那么,ALU的输出应是00000。为了实现这个目的,补码数据类型定义了每一个负整数的表示,即:当ALU把它加上绝对值大小相同的正数,结果会是0的表示法。比如说,既然00101是+5的表示法,11011就被选作-5的表示法。此外,还必须考虑的重要一点是,分配码字应使ALU在对每个数值加00001后,应得到正确的结果。这样,所有的二进制数值就像十进制的-15到+15一样。我们可以使用数学语言来表示:表示(VALUE+1)=表示(VALUE)+表示(1)以上两点,就足以保证ALU正确地做加法运算(只要得到的结果不大于+15或小于-16)。特别的,注意-1和0的表示,分别为11111和00000。当我们对-1的表示加上00001,我们就得到00000,虽然有一个进位,但是该进位不影响结果。也就是说,把00001和-1的表示相加的正确结果是0,而不是100000。因此,进位可以被忽略。实际上,在做补码算术运算时,这个进位总是被忽略。一个计算-A的表示的简便方法:已知A的表示,对A按位取反,然后把A和A的反码相加;这个结果是11111。如果再加上00001,就得到结果为0。因此,-A的表示可以简单地通过把A的反码加1得到。例题2.1 -13的二进制补码表示是什么?1.如果A是+13,它表示为 011012. A的反码是 100103. 加1到10010得到10011,-13的二进制补码表示是10011我们可以通过对A和-A的表示作加法,来验证我们的结果: 01101 + 10011 00000你可能已经注意到01101和10011的加法,除了得到00000,还得到一个进位。也就是说,01101和10011的二进制加法实际上得到100000。然而,正如我们前面看到的,在使用二进制补码的情况下,这个进位可以被忽略。至此,使用5位,我们能够识别出15个正数,15个负数,和一个0。如果k=5,我们能够识别出32个不同的数,但是我们只说明了31(15+15+1)个。剩下的一个表示是10000,我们应该分配一个什么值给它?我们注意到-1是11111,-2是11110,-3是11101,等等。继续下去,-15是10001。正如正数的表示法一样,当我们从-1到-15按顺序后退时,ALU从每一个表示上减去00001。这样,将-16分配给10000是很便利的,那就是从10001减去00001得到的数值。在第5章,我们将说明一个被我们亲切的称为LC-3(小计算机3)的计算机。LC-3对16位的数值进行运算。因此,LC-3中的二进制补码类型整数是从-32768到32767的整数。2.4 二进制-十进制转换我们经常需要在二进制补码数据类型和日常生活中使用的十进制表示之间进行转换。2.4.1 二进制到十进制的转换我们按如下方法从二进制补码向十进制转换:为了举例说明,我们假设使用8位的二进制补码表示,相应的十进制数值从-128到127。一个8位的二进制补码数采取如下格式:a7 a6 a5 a4 a3 a2 a1 a0其中的每个ai要么是0要么是1。1. 检查最前面的a7。如果是0,该整数是正数,我们就可以直接计算其数值。如果是1,该整数是负数,我们必须首先取反加一。(当然,先取反再加一也一样)2. 通过简单的计算:a6*26+a5*25+a4*24+a3*23+a2*22+a1*21+a0*20得到该数值。我们只需将那些系数为1的2的幂次简单相加,就可以得到该数值。3. 最后,如果原数值是负数,我们在前面加一个负号前缀即可。例 2.2 将二进制补码整数11000111转换为十进制数值。1. 既然最前面的一位是1,则该数值是负数。我们首先必须得到与其绝对值相同的正数的二进制表示,为00111001。2该数值可以通过计算:0*26+1*25+1*24+1*23+0*22+0*21+1*20或32+16+8+1得到,为57。311000111对应的十进制数值是-57。(还有更简便的方法:11000111=-power(2,7)+75)2.4.2 十进制到二进制的转换把一个数从十进制转换成二进制复杂一些。这种方法最重要的依据是:如果一个正的二进制数的最右端的数字为1,则这个数为奇数;否则为偶数。再来看一个通用的八位二进制数的表示:a7*27+a6*26+a5*25+a4*24+a3*23+a2*22+a1*21+a0*20还是通过一个例子来具体说明这种转换:假设我们想把十进制数+105转化成二进制补码表示。我们注意到+105是正数。首先我们要找到表示105的ai的值。由于该数值为正数,则二进制补码表示的最高位a7为0。 第一步是找到满足下列等式的ai的值: 105=a6*26+a5*25+a4*24+a3*23+a2*22+a1*21+a0*20 由于105是奇数,可知a0=1,在等式两端同时减去1可得:104= a6*26+a5*25+a4*24+a3*23+a2*22+a1*21 下一步,在等式两端同时除以2,得:52=a6*25+a5*24+a4*23+a3*22+a2*21+a1*20 52为偶数,所以a1一定为0。 现在,我们重复这个过程:在等式两端同时减去最右端的数,在等式两端同时除以2,然后我们观察新得到的等号左端的十进制数是奇还是偶。再来看我们刚才的例子52=a6*25+a5*24+a4*23+a3*22+a2*21经过以上的步骤,结果为:26= a6*24+a5*23+a4*22+a3*21+a2*20所以,a2=0。13= a6*23+a5*22+a4*21+a3*20所以,a3=1。6= a6*22+a5*21+a4*20所以,a4=0。3= a6*21+a5*20所以,a5=1。1= a6*20所以,a6=1,我们得到了最后的结果:二进制表示为01101001。 我们总结解题过程如下:已知十进制数N,通过以下步骤可得其补码表示:1. 首先将N的绝对值的二进制码字用等式表示出来:N= a6*26+a5*25+a4*24+a3*23+a2*22+a1*21+a0*20重复以下步骤直至左边等式数字为0:a. 如果N为奇,则最右边一位数为1;如果N为偶,则最右边一位数为0;b. 两边同时减去1或0(若N为奇,则减去1;若N为偶,则减去0),然后两边同时除以2;每一次重复这一步可得到一个ai的值。2. 如果原来的十进制数为正,则在二进制数前加0,得到结果;3. 如果原来的十进制数为负,在二进制数前加0,然后再计算出这个补码的负数,得到结果。2.5 比特运算第一部分:算术运算2.5.1 加法和减法 二进制补码的算术运算与十进制运算十分相似。 加法运算依然是从右到左进行,每次一位。在每次运算后,产生一个和与一个进位,与以往在9之后产生一个进位不同,因为9是最大的十进制数,我们现在是在1的后面产生一个进位,因为1是最大的二进制数。例 2.3 用我们的五位二进制位组合表示,11+3的值是多少? 十进制数11可以表示为 01011十进制数3可以表示为 00011两数之和是 01110它的值是 14。 通过将减数变为它的负数就可以很容易地将减法转换为加法。也就是说,A-B用A+(-B)来实现。例题2.414-9等于多少?十进制数14表示为: 01110十进制数9表示为: 01001首先构造9的负数,也就是-9: 10111把14与-9相加,我们得到: 01110 10111结果是 00101当然它的十进制值是5再次注意进位被忽略了。例题2.5如果我们把一个数加上它的自身会怎样?(比如说,xx)让我们再次假设在这个例子中采用8位码字,这样我们就可以表示从128到127的整数。考虑若x为整数59(二进制码为00111011),加上自身后,我们得到01110110。注意到所有的码字向左移动了1位。这是偶然呢,还是会发生在所有xx的和上呢(假设有足够的位数用来表示数字)?采用位置计数法,59可以表示为:。5959的和是,同样地可以表示为:。上式也就是,即每位上的数字都向左移了一位。因此,一个数自加(假设有足够的位数来表示数字)等价于把该数字的二进制表示中每位上的数字向左移一位。2.5.2 符号扩展 我们经常会用比较少的位数来表示一个小的数。例如,我们常常只用六位(000101)而不是用十六位(0000000000000101)来表示5这个值。这一点不会引起混淆,因为我们都习惯于这样一个事实:在一个数前加零并不影响这个数的值。一张456.78元的支票和一张0000456.78元的支票价值是相同的。那么负数呢?通过对其相应的正数取反加一,我们就得到了负数的表示。这样,若5的表示为000101,那么-5就表示为111011。若5表示为0000 0000 0000 0101,那么-5就会相应的表示为1111 1111 1111 1011。正如开头的0对正数的实际值没有影响一样,开头的1也不会对负数的实际值产生影响。为了对两个具有不同长度的数值做加法,首先必须要做的就是将它们表示为相同的长度。比如说,假设我们要做13和-5的加法,其中13表示为0000 0000 0000 1101,-5表示为111011。如果我们没有将两个数表示成相同的长度,就有:0000000000001101 + 111011-当我们尝试去做加法运算时,我们要如何去处理-5表示中那些缺失的位呢?如果我们将空位以0填充,那么我们做的就不再是-5和13的加法,相反地,我们已经把-5的表示变成了0000 0000 0011 1011,即59。这样,当我们得到结果72时也就不会感到惊讶了。不过,如果我们能认识到6位的-5与16位的-5唯一的区别就在于开头的1的个数的话,我们就可以在做加法之前先将-5的值扩展为16位,这样,我们就得到:0000000000001101+1111111111111011-结果就是0000000000001000即是我们所期望的8。如果我们用0来扩展一个正数的左端,它的值不会改变。与此类似,如果用1来扩展一个负数的左端,其值亦不会改变。在这两种情况中扩展的都是符号位,我们将这种运算称为符号扩展,简称SEXT。符号扩展用于对不同长度的数值之间的运算,它并不会改变数值本身。2.5.3 溢出到现在为止,我们一直强调:两个整数的和总是足够小,可以用给定的位数来表示。但若不是这种情况又会怎样呢?让我们回到5位补码数据类型,它使我们能表示从-16到+15的整数。假设我们想要用9加11,算术过程如下:010010101110100计算结果为-12,为什么会出现错误?原因是9加11等于20,大于+15,即大于01111,而01111是我们用5位的补码数据类型能够表示的最大正数,因此20不能用5位的补码表示出来。此外,在二数相加时,产生了一个到第一位的进位,但是这个位置是被用来表示数值的正负的。因此,检测结果是否太大,就是一件很容易的事。由于我们加的是2个正数,结果应该是正的,ALU得出一个负数结果,表明计算出错。出错的原因就是2个正数的和太大,不能使用提供的位数来表示。我们称之为溢出,即计算结果超出了这种表示方法的容量。相反的,我们计算两个负数的和。举个例子,-12加-6。这种情况我们的运算如下:101001101001110这里的结果也出现溢出的情况,-12加-6等于-18,比最小的负数-16还要小。ALU得到一个正的结果。同样,既然两个负数的和不可能是正数,这也很容易监测。而一个负数和一个正数的和永远不会出现溢出,为什么? 2.6 比特运算第二部分:逻辑运算 在前面一部分,我们看到了对位组合做算术运算(比方说,加法,减法)。下面,介绍另一类位组合的运算,逻辑运算。 逻辑运算是对逻辑变量做运算。一个逻辑变量可以为两个值之一,0或1。“逻辑”这个名称来源于使用0和1表示逻辑值“假”和“真”,但是现在的逻辑运算已经与这个原始意义没有多大关系了。下面的一些基本的逻辑函数,是大部分ALU都能进行的逻辑运算。2.6.1 与函数(AND) 与是一个二元函数,表示它需要两个输入的数据。换句话说,与函数需要两个源操作数,每个源操作数都是一个逻辑变量,值为0或1。只有当两个源操作数都是1时输出才为1,否则为0。我们可以把它假想成ALL运算,那就是说,只有两个输入都(ALL)为1是输出才为1,否则为0。表示逻辑运算的一个方便的方法是使用真值表。一个真值表有n+1列和2n行。前面n列对应着n个源操作数。既然每个源操作数都是0或1中的一个,那么源操作数组合就有2n种可能。每组这样的值的组合(或称为输入组合)使用真值表的一行表示出来。真值表最后一列表示每种组合的输出。在两个输入的与函数例子中,真值表有两列源操作数和四个输入组合:ABAND000010100111 我们可以把逻辑运算扩展为两个m位的位组合的运算。这就涉及到要对两个源操作数中对应位上的数字按位做与运算。例如a,b是16位的位组合,c是a和b做与运算的结果。这个操作通常叫做按位与运算。例题2.6如果c是a和b做与运算的结果,此处a=0011101001101001,b=0101100100100001,则c是什么?我们通过对两个值进行按位与运算,得到a和b做与运算的结果。这意味着对每一对ai和bi分别进行与运算,得到ci。例如,既然a0=1,b0=1,那么c0是a0和b0进行与运算,结果为1。既然a6=1,b6=0,那么c6是a6和b6进行与运算,结果为0。对于c的解答为:a: 0011101001101001 b: 0101100100100001 c: 0001100000100001例题2.7 假设我们有一个8位的位组合,称为A,最右边的两位有特殊的重要性。根据存储在A中的最右边两位,计算机被要求处理4个任务之一。我们可以把这两位孤立出来吗?使用位屏蔽,就可以做到这一点。位屏蔽是能够使A的8位分隔为两部分二进制组合,这两部分分别是你关心的一部分、以及你想忽略的一部分。在这个例子中,位屏蔽为00000011,它和A做与运算,从7位到2位的位置上都为0,而0位和1位中的原来的值还在0和1的位置上。位屏蔽则屏蔽了7位到2位上的值,孤立出有重要性的0位和1位。如果A是01010110,A与位屏蔽00000011做与运算,得到00000010。如果A是11111100,A与位屏蔽00000011做与运算,得到00000000。也就是说,位屏蔽00000011和任何8位的组合做与运算,结果将是四种组合之一,这四种组合是00000000,00000001,00000010或00000011。和位屏蔽进行与运算的结果是使相应的两位突出出来。2.6.2 或函数(OR) 或也是一个二元函数。它需要两个操作数,这两个操作数都是逻辑变量。如果两个操作数中有一个为1,那么或函数的输出就为1。当且仅当两个操作数都为0时,或函数的输出为0。我们可以把或运算看作是ANY运算;即只要两个输入中有一个值(ANY)为1,那么结果就为1。 以下是一个两个输入的或函数的真值表。ABOR000011101111我们已对两个m位的位组合进行了逻辑与运算,那么用同样的方式,我们也可以对两个m位的位组合按位进行或运算。比如,如果a和b仍取以前的值,那么c就是a和b或运算的结果。例题2.8 如果c是a和b做或运算的结果,和前面一样,a=0011101001101001,b=0101100100100001,则c是什么?我们通过对两个值进行按位或运算,得到a和b做或运算的结果。这意味着对每一对ai和bi分别进行或运算,得到ci。例如,既然a0=1,b0=1,那么c0是a0和b0进行或运算,结果为1。既然a6=1,b6=0,那么c6是a6和b6进行或运算,结果也为1。对于c的解答为:a: 0011101001101001 b: 0101100100100001 c: 0111101101101001有时这种或运算也被称为包含或运算,这样做是为了将它区别于异或函数,我们将在后面讨论异或函数。2.6.3 非函数(NOT) 非函数是一个一元函数,表明它只作用于一个操作数。其输出结果是通过对输入进行补运算,即取反操作得到,也被称作补运算。当输入为1 时,输出为0;输入为0时,结果为1。 非函数的真值表表示如下。ANOT1001采用对两个m位的位组合进行逻辑与和或运算相同的方式,我们对一个m位的位组合按位进行非运算。如果a仍是以前的值,那么c就是对a进行非运算的结果。a: 0011101001101001 c: 11000101100101102.6.4 异或函数异或,通常简写成XOR,是一个二元函数。它也需要两个源操作数,这两个数都是逻辑变量。若两个源操作数不同则异或运算输出为1,否则为0。异或函数真值表如下: ABOR000011101110采用与m位的位组合的逻辑与运算相同的方法,我们也可以对m位的位组合做异或运算。例题2.9 假如a和b与前面例子相同,是16位的位组合,c是a和b的异或运算:a: 0011101001101001b: 0101100100100001c: 0110001101001000注意区别XOR真值表和OR真值表,在异或运算中,若两个源操作数都是1,那么结果为0,也就是说,当第一个数是1而第二个不是1,或者第二个数是1而第一个不是1时输出为1。用“异”这个字是因为只有当一个数是1而另一个不是1时输出才是1。另一方面,或运算是当两个数之一为1或两个数全为1时,输出为1,因此,或运算又称为“包含或”。 例题2.10 判断两个位组合是否相同。既然只有当相应的位上是相同的值时,XOR函数才得到0,那么如果异或函数的输出全为0,两个位组合就是相同的。2.7 其它表示法另外四种在我们的工作中有用的表示法分别是位向量、浮点数类型、ASCII码类型和十六进制类型。2.7.1 位向量 位向量用于描述一个由几个相互无关的处于忙或闲的单元组成的复杂的系统。此系统可能是一个其中的每个单元都是一台特定的机器的工厂,或者每个单元都是一辆计程车的计程车网络。在这样的系统中,确定了哪个单元处于繁忙状态,哪个处于空闲状态,就可以根据需要指派它们去做工作。 如果我们有n个单元,我们可以用一个被称为位向量的n位的位组合来跟踪这n位,如果某个单元空闲,我们就让这个单元的位为1,否则为0。例2.11 假设我们有8台机器,我们可以用一个8位的位向量(可命名为BUSINESS)来跟踪这8个单元的状态。如果某个单元空闲,我们就让这个单元的值为1,否则为0。这些单元被从右向左标记为0到7。BUSINESS位向量11000010对应的状态是只有7、6和1单元是空闲的,因此可以被分配工作。 如果要给单元7分配工作,我们需要对当前的位向量“11000010”和位屏蔽“01111111”做逻辑“与”运算,这样,就得到一个新的BUSINESS位向量。位屏蔽的目的是清空BUSINESS位向量的7单元,位向量的结果是“01000010”。 回忆我们在例2.7中的位屏蔽的概念。位屏蔽是为了区别对待二进制组合中的一些位和另一些被忽略的位。在本例中,位屏蔽将第7位清零,而将其它的位保持不变(被忽略)。 假设单元5完成了工作,处于空闲状态。我们可以通过对BUSINESS位向量和位屏蔽00100000做或运算得到新的结果,最后结果为01100010。2.7.2 浮点数类型在本书中的大多数运算使用的是整数。例如,LC-3使用的是16位补码,除了用1位表示值的正负,其余15位表示值的大小。使用这种方法,我们可以表示的数值的范围为-32768到+32767,即-215到+215-1。我们称数值的精度是15位,数值范围是215。有时我们需要表示很大的数,但我们却不需要精度有那么多位,例如大家所熟悉的数6.023*1023,要表示这个数所需的范围,要比16位补码的范围215大的多。另外,用15位的精度表示这个数也没有必要,我们只需足够的位数表示4个重要的数(6023)就可以了。所以我们面临着一个问题:我们有过多的位数表示精度,但却没有足够的位数表示范围。浮点数类型可以解决这一问题。它用一些位数来表示值的范围,用其余的位数(除了最左端的符号位)来表示值的精度,而不是将所有的位数(除最左端的符号位)全用来表示值的精度。如今的多数指令集结构都定义了不止一种浮点数类型。其中一种通常被称作float(单精度浮点数),它共包含32位,分配情况如下:1位表示符号(正或负)8位表示范围(指数域)23位表示精度(分数域)在当今生产的大多数计算机中,这些位按照图2.2的公式表示数字。这个公式是“IEEE”浮点数运算标准的一部分。这里所讲的浮点类型和科学记数法很相近。现在以6.023*1023为例,这个表示法包含三个部分:符号(这里是正号),有效数字6.023以及指数23。我们称有效数字部分为分数。注意,分数是规格化(标准化)的,也就是说,只有一位非零的十进制数出现在该小数的最左端。图2.2中的公式和数据类型也包括这三个部分。分数部分不是4位十进制小数(有效数字),而是23位二进制数。注意到该分数也是规格化的,也就是说,只有唯一一位非零的二进制数出现在二进制小数点的左端。因为这个非零数只能是1,所以不需要分配一位将其明确表示出来。因此图2.2中的公式表示了24位的精度,包括数据类型的23 位和二进制小数点左端的没有必要明确表示出来的一位1。我们用8位二进制数而不是两位十进制数作指数,以2为底,而不是以10为底。用8位表示指数,就可以表示256个指数。注意,公式只给出了其中的254种。如果指数域为00000000(即0)或11111111(即255),此公式并未告诉我们怎样解释这两个数。我们将在后面讨论这两种情况。对于浮点类型数据指数域内的剩下的254个值,其解释如下:实际上被表示的指数是数据中的无符号整数减去127。例如,如果实际指数是+8,那么指数域上应该是10000111,也就是135,是由于135-127=8。如果实际指数是-125,指数域就是00000010,即无符号整数2,是因为2-127=-125。S指数exponent分数fraction8位23位1位N = (-1)S1.fraction2exponent-127,1 exponent 254图2.2 浮点数数据类型第三部分是符号位:0代表正数,1代表负数。该公式包含了这样一个因子(-1)s,当s=0时计算值为+1,当s=1时计算值为-1。例2.12 怎样用浮点数表示?首先,我们将用二进制数表示为:100.101,即-(1*22+1*21+0*20+1*2-1+0*2-2+1*2-3)然后将它规范地表示为-1.10101*22;符号位应为1,反映是个负数。指数部分为10000011,即无符号整数129,反映了指数为2(1291272)。分数部分是去掉开头的1后的23位精度,也就是说,分数部分是10101000000000000000000。用浮点数表示的结果就是:1 10000011 10101000000000000000000例2.13 浮点数001111011000000000000000000000000表示多少?最高位为0,表示该数是个正数。;跟着的8位代表无符号整数123,减去127,得到实际指数为4;最后23位都是0。因此这个数表示为+1.00000000000000000000000000*2-4,也就是116。注意:32位的指数部分里不包含0000000或1111111。IEEE的浮点数标准叙述了怎样来解释32位中的指数部分是0000000或1111111的情况。如果指数部分是0000000,那么它的指数就是126,得到的有效位以0开头,后面是二进制的23位的小数部分,形式如下:-1s*0.fraction*2-126例如,浮点数0 0000000 000010000000000000000000可以按照如下方法计算其值:第一个0表示它是正数,接下来的八位,是一个零指数,意味着它的指数是-126,后面的23位形成0.00001000000000000000000,即2-5。这个数就是2-5*2-126。这样就能表示很小的数。例2.14 下面四个例子是根据IEEE标准的规则表示的32位浮点数:0 10000011 0010100000000000000000是1.00101*24=18.5指数域包含一个无符号数131,由于131-127=4,所以指数为+4。将分数域的小数点左边加一个1形成1.00101。如果将小数点向右移动4位,我们得到10010.1,即18.5。1 10000010 0010100000000000000000是-1*1.00101*23=-9.25符号位为1,表示负数。指数是130,表示130-127,即指数为3。将分数域的小数点左边加一个1形成1.00101。如果将小数点向右移动3位,我们得到1001.01,即-9.25。0 11111110 1111111111111111111111约为2128符号为正。指数是254-127,即+127。将分数域的小数点左边加一个1形成1.11111111111111111111111,约等于2。因此,结果约为2128。1 00000000 0000000000000000000001是-2-149符号为负。指数域全为0,表示指数是-126。将分数域的小数点左边加一个0形成2-23。因此,结果为2-23*2-126,等于-2-149。关于IEEE浮点数的详细解释超出了本书的范围。事实上,我们还没有考虑当指数为11111111时,如何解释这32位浮点数。本节中的目标只是希望你了解除了补码外,在几乎所有的指令集结构中都存在另一种非常重要的数据类型,即浮点数据类型。它使得很大或很小的数能够以减少二进制精度位数为代价,被表示出来。2.7.3 ASCII码信息的另一种表现形式是几乎所有的计算机设备生产商都用于在主要的计算机处理单元和输入输出设备之间转换字符码的标准码。这种8位码被称为ASCII,代表美国标准信息交换码。它极大地简化了某公司生产的键盘、另一公司制造的计算机和第三个公司制造的显示器之间的接口。键盘上的每个键被一个唯一的ASCII码所识别,例如,数字3是被一个以开头的0扩展为8位的00110011,数字2是00110010,小写字母e是01100101,回车是00001101。8位ASCII码的全集被列于附录E的图E.2中。当你在键盘上敲击某个键时,相应的8位码被存储,提供给计算机。将在第8章讨论,这个8位码被存储到什么地方,以及如何被存进计算机。大多数的键与一个以上的码有关,例如,字母E的ASCII码是01000101,而字母e的ASCII码是01100101,二者都与一个键有关,尽管其中一种情况需要按下Shift键,而另一种情况则不需要。2.7.4 十六进制表示法我们已经看到信息可以被表示为二进制补码、位向量、浮点数格式、或ASCII码。还存在一些其他的表现形式,在我们结束本章之前,我们将向你介绍一种对于我们的使用而言,比被计算机支持的数据类型更方便的表示法,那就是十六进制表示法。正如我们即将看到的,它发展了二进制的位置计数法,对于无误的处理一长串的二进制数位很有用。它对于处理LC-3经常遇到的16位的二进制位组合是特别有用的。例如,一个二进制位组合为0011110101101110让我们做个试验,假如用一只手盖住这个0和1的16位的二进制位组合,试着通过记忆写下它。你做得怎么样?十六进制计数法就让你有可能无误的做到这一点。我们来看看怎么做。一般来说,一个16位的二进制位组合具有如下的格式:a15 a14 a13 a12 a11 a10 a9 a8 a7 a6 a5 a4 a3 a2 a1 a0其中,ai的每一位要么是0,要么是1。如果我们把这个二进制位组合作为无符号整数,它的值可以被计算如下:215*a15 +214*a14 +213*a13 +212*a12 +211*a11 +210*a10+29* a9 +28*a8+27* a7+26* a6+25* a5 +24*a4+23* a3 +22*a2+21* a1+20* a0我们可以从前四项中分解出因子212,从第二个四项中分解出28,从第三个四项中分解出24,从第四个四项中分解出20,得到212*23*a15 +22*a14 +21*a13 +20*a12 +28*23*a11 +22*a10+21* a9 +20*a8+ 24*23* a7+22* a6+21* a5 +20*a4+ 20*23* a3 +22*a2+21* a1+20* a0注意在中括号里的最大值为15,这是当四位的每一位都为1时的情况。如果我们用一个符号取代每个中括号中的值(从0到15),用等价的163代替212,用162代替28,161代替24,160代替20,我们就有163* h3 +162*h2+161*ha1+160*h 0这里的h3是个符号,表示23*a15 +22*a14 +21*a13 +20*a12既然这些符号必须表示从0到15的值,我们为这些值分配符号如下:0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F。也就是说,我们用符号0表示0000,用符号1表示0001,用9表示1001,用A表示1010,用B表示1011,用F表示1111。这种计数法就是十六进制或以16为基。那么,如果十六进制数E92F表示一个16位的二进制补码整数,这个整数的值是正数还是负数?我们如何得知?此外,这种十六进制表示法的好处是什么?它看起来好像只是另一种表示数字的方式,并未增加任何益处,让我们回到那个让你通过记忆写出一串数字的练习:0011110101101110如果我们首先将这个位组合按照每四位进行分割0011 1101 0110 1110然后将每四位转换为相等的十六进制数3 D 6 E当遮住这串数字时,记下3D6E应该是没有问题的。总之,十六进制计数法的采用方便了人们对数据的表达。它能表达:整数、浮点数或一串ASCII码、位向量。它通过将二进制数中每四位的组合用一位十六进制数(0,1,2,F)来表示,从而大大减少了数字的位数。同时也降低了人们因抄写过多的0或1而造成错误的机率。习题2.5 分别写出7和-7的二进制原码、反码和补码表示(使用5位二进制数位)。2.8 请回答如下问题:a. 对于8位二进制补码整数类型,能够表示的最大的正数是多少?请分别以二进制和十进制形式写出该结果;b. 对于8位二进制补码整数类型,能够表示的最小的负数是多少?请分别以二进制和十进制形式写出该结果;c. 对于n位二进制补码整数类型,能够表示的最大的正数是多少?d. 对于n位二进制补码整数类型,能够表示的最小的负数是多少?2.10 将下列二进制补码整数转化为十进制数:a. 1010b. 01011010c. 11111110d. 00111001110100112.11 将下列十进制数转化为8位二进制补码整数:a. 102b. 64c. 33d. -128e. 1272.12 如果二进制补码整数

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论