计算机系统原理(五) 信息的存储与值的计算2014-08-22上一章(1.1-1.4)LZ和各位简单的探讨了一下计算机系统中的一些基本概念,本次我们将进入一个崭新的世界。在1.1那一章当中,我们已经简单的提及了信息的概念,本次我们会逐渐深入的讨论信息的相关内容。
引言
我们很难想象,1和0这两个再简单不过的数字,给计算机科学带来了彻底的改变。对于无法与人脑相比的计算机来说,简单的1和0就是最适合它们的数字。不过1个1或者1个0往往代表不了任何意义,它们必须被赋予上下文,才能有具体的含义。比如,如果我们知道1和0是代表的布尔类型的值,那么我们就知道1是true,0是false。对于二进制所表示的数字来说,主要有三种,即无符号、补码以及浮点数。由于计算机对于固定类型的二进制数字往往都是有位数限制的,比如int类型使用四个字节(32位二进制)来表示,因此在计算的时候,会发生溢出的情况,最简单的我们使用无符号整数0xFFFFFFFF与无符号整数0xFFFFFFFF相乘,则会产生溢出。在产生溢出的时候,得出的结果往往会令人大跌眼镜。比如两个正数相乘可能得到负值,两个正数相加也可能得到负值。而对于不同的计算机来说,由于数值范围可能有所不同,因此掌握信息相关的内容对于写出跨平台的程序来讲也是很有帮助的。
信息的存储
大多数计算机使用8位的块,或者说字节,来作为最小的可寻址的存储器单位,而不是在存储器中访问单独的位。换句话说,我们在访问存储器的内容时,最小的访问单位一般是字节。在我们编程的时候,往往会把虚拟存储器(virtual memory)抽象为一个字节数组,而每一个数组内的元素或者说字节都有唯一的地址(address),这些地址的集合就被称作虚拟地址空间。虚拟地址空间是为了给机器级的程序一个概念上的映像,实际上为了提供这个映像,内部的实现是非常复杂的。
十六进制表示法
对于机器来说,可能比较喜欢0和1,但是对于人类这种高级生物来说,1和0就有点不够看了。因此通常情况下,为了便于阅读,我们会使用十六进制去表示二进制。1位十六进制的数字可以表示4位二进制数字,因此一个字节就可以表示为0x00---0xFF。有关十六进制、二进制以及十进制的转换,LZ这里就直接略过了,相信大部分人应该都对这个转换并不陌生。字每台计算机都有一个字长(word size),用于指明整数和指针数据的标准大小(nominal size)。而由于虚拟地址空间中的地址就是使用一个字来表示的,因此操作系统中的字长就决定了虚拟地址空间的大小。比如32位操作系统下,最大内存就是232 = 4 * 210 * 210 * 210 B = 4GB,而在64位操作系统下,LZ还专门问了问群里的猿友,最终得到的结果是234GB。
数据大小
由于计算机位数的不同,会造成在数据类型的存储上,采用的位数略有不同,下表是在32位和64位机器下,C语言当中的数字数据类型需要的位数。

可以看出,对于长整形以及字符指针类型来说,在32位和64位系统下的字节数是不同的。特别的,对于指针类型来说,所有指针类型在32位下都是4位,而在64位下都是8位,这是由虚拟地址空间的地址位数或者说字长所决定的。
寻址和字节顺序
对于跨越多个字节的程序对象(程序对象指指令、数据或者控制信息等,是程序当中对象的统称)来说,我们需要制定两个规则,才能唯一确定一个程序对象的值。比如对于int类型的值0xFF来说,如果我们要根据虚拟内存地址去获取这个整数值,那么首先我们需要知道它的起始虚拟内存地址是多少。另外,我们还需要知道,对于表示int类型的四个字节来说,这四个字节的排列顺序。对于第一个问题,由于大部分计算机都采用连续的内存地址去存储一个程序对象,因此我们称内存地址中最小的那个就是该程序对象的起始地址,也是该程序对象的地址。对于第二个问题,一般有两种方式,即大端法和小端法。对于一个整数0x000000FF来说,我们假设它的起始地址为0x1,那么对于使用大端法规则的系统来说,0x1-0x4的虚拟内存所存储的值依次为0x00、0x00、0x00、0xFF,相反对于采用小端法规则的系统来说,0x1-0x4的虚拟内存所存储的值依次为0xFF、0x00、0x00、0x00。