第2章 信息的表示和处理

现代计算机存储和处理的信息以二值信号表示。

信息存储

大多数计算机使用8位的块, 或者字节(byte), 作为做小的可寻址的存储器单位。机器级程序将存储器视为一个非常大的字节数组,称为虚拟存储器(virtual memory)。存储器的每个字节都由一个唯一的数字标识, 称它为地址(address),所有可能地址的集合称为虚拟地址空间(virtual address space)

  1. 十六进制表示法
  • 用十六进制(hex)书写, 一个字节的值域为00-FF
  • 二进制与十六进制的转换比较直接, 可以一次执行一个十六进制数字的转换(二进制每4位组, 对应一个十六进制数值)
  • 在C语言中, 以0x或0X开头的数字常量被认为是十六进制的值
  • 每台计算机都有一个字长(word size), 指明整数和指针数据的标称大小(nominal size)。因为虚拟地址是以这样的一个字来编码的, 所以字长决定的最重要的系统参数就是虚拟地址空间的最大大小。
  1. 数据大小
  • 计算机和编译器都支持多种不同方式编码的数字格式, 如2字节,4字节,8字节整数和4字节和8字节浮点数。
  1. 寻址和字节顺序
  • 对于跨越多字节的程序对象,必须建立两个规则:这个对象的地址是什么, 以及在存储器中如何排列这些字节

  • 几乎所有的机器上, 多字节对象都被存储为连续的字节序列, 对象的地址为所使用字节中最小的地址。

  • 最低有效字节在最前面的方式称为小端法(little endian);最高有效字节在最前面的方式称为大端法(big endian)。对于大多数应用程序员来说, 他们机器所使用的字节顺序是完全不可见的。不过有些时候,字节顺序会成为问题:

    1. 网络应用程序的代码编写必须遵守建立的关于字节顺序的规定, 以确保发送方机器将它的内部表示转换成网络标准, 而接受方机器则将网络标准转换为它的内部表示。

    2. 当阅读表示整数数据的字节序列时字节顺序也很重要。通常在检查机器级程序时会出现这种情况。如:反汇编(disassembler)。

    3. 当编写规避正常的类型系统的程序时。在C语言中,可以使用强制类型转换(cast)来允许以一种数据类型引用一个对象,而这种数据类型与创建这个对象时定义的数据类型不同。

  1. 表示字符串
  • C语言中字符串被编码为一个以null(其值为0)字符结尾的字符数组。每个字符都由某个标准编码来表示,最常见的是ASCII字符码。
  1. 表示代码
  • 不同类型的机器使用不同的且不兼容的指令和编码方式, 因此二进制代码是不兼容的。
  1. 布尔代数(Bool algebra)简介
  • 将逻辑值TRUEFALSE编码为1和0, 设计出一种代数
  • 将4个布尔运算扩展到位向量, 位向量就是有固定长度为w, 由0和1组成的串
  1. C语言中的位级运算
  • | OR, & AND, ~ NOT, ^ EXCLUSIVE-OR
  1. C语言中的逻辑运算
  • || && !,逻辑运算认为所有非零参数都表示为TRUE,而参数0表示FALSE
  1. C语言中的移位运算
  • 机器支持两种形式的右移:算术右移和逻辑右移,逻辑右移在左边补k个0, 算术右移是在左端补k个最高有效位的值

整数表示

用位来编码整数的两种不同方式:一种只能表示非负数,而另一种能够表示负数,零和正数

  1. 整数数据类型
  • C语言支持多种整数数据类型——表示有限范围的整数。
  • 一个与机器相关的取值范围是大小指示符 long, 大多数64位机器使用8个字节表示, 32位机器上使用4个字节表示
  • 负数范围比整数的范围大1
  1. 无符号整数的编码
  • 我们用一个函数B2U(Binary bo Unsigned,长度为w, 向量为{x},如:[1011])来表示 $ B2U_w(\vec{a}) = \sum^{w-1}_{i=0}x_i2^i $
  • $ B2U_w(\vec{a}) = \sum^{w-1}_{i=0}x_i2^i $

  • 最小值0, 最大值:
  1. 补码编码
  • 有符号数最常表示方式就是补码(two’s-complement), 用函数B2T(Binary to two’s-complement)表示:
  • 最小值是位向量[10…0]的值:
  • 最大值是位向量[010…0]的值:
  • 反码(Ones’ Complement): 除了最高有效位的权, 和补码一样:
  • 原码(Sign-Magnitude): 最高有效位是符号位, 用来确定负权还是正权:
  1. 有符号数和无符号数之间的转换
  • 数值可能会改变,但是位模式不变。
  • B2U和B2T都是双射, 就有明确的逆映射。
  • 函数U2T描述了从无符号数到补码的转换, 而T2U描述的是补码到无符号的转换
  • ,如果令
  • , 得到:
  • 推导一个无符号树u和与之对应的有符号数U2T(u)之间的关联。设
  • , 得到:
  1. C语言中的有符号数与无符号数
  • C语言支持所有整形数据类型的有符号和无符号运算, 转换的规则是底层的位表示不变
  • 有符号数和无符号数运算时, C语言隐式地将有符号数强制转换为无符号数
  1. 扩展一个数字的位表示
  • 在不同字长的整数之间转换, 同时又保持数值不变
  • 将一个无符号数转换为一个更大的数据类型, 只需简单地在表示的开头添加0, 这种运算称为零扩展(zero extension)
  • 将一个补码数字转换为一个更大的数据类型, 在表示中添加最高有效位的值的副本, 称为符号扩展(sign extension)
  1. 截断数字
  2. 关于有符号数与无符号数的建议
  • 有符号数到无符号数的隐式强制类型转换导致了某些非直观的行为,避免这类错误的一种方法就是绝不使用无符号数

Tags: ,

Updated: