前面介绍了计算机中常用的进制表示方法和转换,现在读者知道了计算机存储的都是二进制的数据,那么接下来要讨论的是在计算机中数据存储的单位以及数据是如何存储在存储空间的。 1.2.1数据的宽度 数据的宽度是指数据在存储器中存储的尺寸。在计算机中,所有数据的基本存储单位都是字节(byte),每个字节占8个位(位是计算机存储的最小单位,而不是基本单位,因为在 存储数据时几乎没有按位进行存储的)。其他的存储单位还有字(word)、双字(dword)和
1.2.2数值的表示范围
在计算机中存储数值时,也是要依据前面介绍过的数据宽度进行存储的,那么在存储数据时由于存储数据的宽度限制,数值的表示也是有范围限制的。那么byte、word和dword能存储多少数据呢?我们先来计算一下,如果按位存储的话,能存储多少个数据,再分别来计
算以上三种单位能够存储的数值的范围。
计算机使用二进制进行数据存储时,一位二进制最多能表示几个数呢?因为是二进制数,只存在0和1两个数,所以一位二进制数最多能表示两个数,分别是0和1。那么,两位二进制最多能表示几个数呢?因为一位二进制数能表示两个数,所以两位二进制数则能表示2的2次方个数,即4个数,分别是0、1、10、11。进一步地,三位二进制数能表示的就
是2的3次方个数,即8个数,分别是0、1、10、11、100、101、110、111。
上面的过程可以整理成表1-3。
2 的 8 次方是 256,为什么数值只有 0~255 个呢?因为计算机计数是从 0 开始,从 0 到 255 同样是 256 个数,这里的 2 的 8 次方表示能够表示数值的个数,而不是能够表示数值的 最大的数。 这里只给出了无符号整数的表示范围,那么什么是无符号呢?数值分为有符号数和无符 号数,有符号数是分整数和负数的,而无符号数值有整数没有负数。负数在计算机中的表示 有符号数时借助了最高位来进行,如果最高位是 0,那么就是整数,如果最高位是 1 则是负 数。关于有符号数和无符号数不必过多地纠结,因为计算机表示数据是不区分有符号还是无 符号的,有符号还是无符号是人在进行区分。这里就不做过多地解释了。 1.2.3 字节序 字节序也称为字节顺序,在计算机中对数值的存储有一定的标准,而该标准随着系统架 构的不同而不同。了解字节存储顺序对于逆向工程是一项基础知识,在动态分析程序的时候, 往往需要观察内存数据的变化情况,这就需要我们在掌握数据的存储宽度、范围之后,进一 步了解字节顺序。 通常情况下,数值在内存中存储的方式有两种,一种是大尾方式,另一种是小尾方式。 关于字节序的知识,通过一个简单的例子就可以掌握。 比如有 0x01020304(C 语言中对十六进制数的表示方式)这样一个数值,如果用大尾方 式存储,其存储方式为 01 02 03 04,而用小尾方式进行存储则是 04 03 02 01,用更直观的方 式展示其区别,如表 1-5 所列 |
---|
从两个地址列可以看出,地址的值都是一定的,没有变化,而数据的存储顺序却是不相同的。从表中可以得到如下结论。
大尾存储方式:内存高位地址存放数据低位字节数据,内存低位地址存放数据高位字节数据;小尾存储方式:内存高位地址存放数据高位字节数据,内存低位地址存放数据低位字节数据。
通常情况下,Windows操作系统兼容的CPU为小尾存储方式,而Unix操作系统兼容的CPU多为大尾存储方式。在网络中传输的数据的字节顺序使用的是大尾存储方式。
1.2.4 ASCII码
计算机智能存储二进制数据,那么计算机是如何存储字符的呢?为了存储字符,计算机必须支持特定的字符集,字符集的作用是将字符映射为整数。早期字符集仅仅使用8个二进
制数据位进行存储,即ASCII码。后来,由于全世界语言的种类繁多,又产生了新的字符集
Unicode字符编码。
ASCII码是美国标准信息交换码的字母缩写,在ASCII字符集中,每个字符由唯一的7位整数表示。ASCII码仅使用了每个字节的低7位,最高位被不同计算机用来创建私有字符集。由于标准ASCII码仅使用7位,因此十进制表示范围是0~127共128个字符。
在编程与逆向中都会用到ASCII码,因此有必要记住常用的ASCII字符对应的十六进制和十进制数。常用的ASCII字符如表1-6所列。
表1-6是经常使用到的ASCII字符,这些字符是经常会见到和用到的,希望读者能将其保存,以便使用之时可以快速查阅。
Unicode编码是为了使字符编码更进一步符合国际化而进行的扩展,Unicode使用一个字(也就是两个字节,即16位)来表示一个字符。这里不做过多的介绍。