2.1 信息存储
机器级的程序将存储器视为一个字节数组,称为虚拟存储器(virtual memory)。存储器的每个字节都由一个唯一数字标识,称为该字节的地址(address),所有地址的集合称为虚拟地址空间(virtual address space)。
2.1.1 字
每台计算机都有一个字长(word size),指明整数和指针数据的标称大小(norminal size)。虚拟地址就是这么编码的,对于32位字长的计算机,限制了他的虚拟地址空间位232-1位4GB,对于64位字长的计算机,内存最大支持128G。
2.1.2 寻址和字节顺序
一个对象存储有大端法和小端法,最低有效位在最前面的方式被称为小端法,另一种称为大端法。许多芯片在加电启动时确定字节顺序规则。假设有一个0x1234567在地址范围0x100~0x103存储,顺序如下
大端法 | 0x100 | 0x101 | 0x102 | 0x103 | |
... | 01 | 23 | 45 | 67 | ... |
小端法 | 0x100 | 0x101 | 0x102 | 0x103 | |
... | 67 | 45 | 23 | 01 | ... |
2.1.3 布尔代数和环
"~":逻辑运算NOT
"&":逻辑运算AND
" | ":逻辑运算OR
" ^ ":异或运算EXCLUSIVE-OR,PQ为真但不全为真时成立
~ | & | 0 | 1 | | | 0 | 1 | ^ | 0 | 1 | ||||
0 | 1 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 1 | |||
1 | 0 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 |
2.1.4 位级运算
C的表达式 | 二进制表达式 | 二进制结果 | C的结果 |
~0x41 | ~[01000001] | [10111110] | 0xBE |
~0x00 | ~[00000000] | [11111111] | 0xFF |
0x69&0x55 | [01101001]&[01010101] | [0100001] | 0x41 |
0x69 | 0x55 | [01101001] | [01010101] | [01111101] | 0x7D |
x << k | 将x向左移动k位,丢掉k个最高位,右端补k个0 |
2.2 整数表示
一个整数数据类型有 w 位,可以写成[xw-1, xw-2, ..., x0],可以得到无符号数的二进制表示形式(式1)
在计算机中希望使用二进制补码形式表现有符号数(负数),其中最高位解释为负权或符号位,正数的原码、反码、补码都相等,负数的反码是除符号位外取反,补码等于反码加1(式2)
数字 | 原码 | 反码 | 补码 | 直接计算 |
-10 | 10001010 | 11110101 | 11110110 | -1*27+26+25+24+22+21=-10 |
10 | 00001010 | 00001010 | 00001010 | 23+21=10 |
从这里理解有符号数和无符号数的映射,有符号数的正数部分对应了无符号数相同大小的正数部分,而有符号数负数的部分对应了更大的无符号数部分,反过来无符号数较大的部分会对应有符号数的负数
对于数字的截断,如果将一个32位整数截断到16位,会截断32位前面的16位,保留后面的16位
2.3 整数运算
2.3.1 无符号加法
无符号运算可以被视为一种模的运算。例如考虑一个四位数表示,x=9和y=12,[1001]和[1100]。它们的和是21,五位表示为[10101],但如果截断最高位会得到[0101],也就是5,这和 21 mod 16 = 5一致
2.3.2 二进制补码加法
二进制补码运算中存在移除情况,根据式2可以很好理解,0111 1111是正数最大值,而1000 0000是负数最小值,所以正数向上溢出后会是最小的负数,而负数向下溢出后是最大的正数