20241029-CSAPP课本阅读
第2章 信息的表示和处理
三种最重要的数字表示:无符号、补码、浮点数。
溢出:结果太大,无法表示。
2.1 信息存储
虚拟内存:机器级程序将内存视为一个非常大的字节数组;
地址:内存中的每个字节都由一个唯一的数字来标识,该数字为地址;
虚拟地址空间:所有可能地址的集合;
程序对象:程序数据、指令和控制信息。
2.1.1 十六进制表示法
十六进制:0-9,A-F;
C语言中,十六进制值前面加上0x;
2.1.2 字数据大小
字长:指明指针数据的标称大小;
相关C声明与字节数如下表:
有符号 | 无符号 | 32位 | 64位 |
---|---|---|---|
char | unsigned char | 1 | 1 |
short | unsigned short | 2 | 2 |
int | unsigned | 4 | 4 |
long | unsigned long | 4 | 8 |
int32_t | uint32_t | 4 | 4 |
int64_t | uint64_t | 8 | 8 |
char * | 4 | 8 | |
float | 4 | 4 | |
double | 8 | 8 |
2.1.3 寻址和字节顺序
排列表示一个对象的字节有两个通用的规则:
大端法,最高有效字节在最前面;小端法,最低有效字节在最前面。
使用不同方法产生的数据互通的时候,有相关标准;阅读表示整数数据的字节序列时字节顺序也很重要;编写规避正常类型系统的程序时字节顺序也很重要。
反汇编器:确定可执行程序文件所表示的指令序列的工具。
打印程序对象的字节表示,代码如下:
1 |
|
typedef来命名数据类型:
typedef int *int_pointer;
int_pointer ip;
也可以声明为:int *ip;
2.1.4 表示字符串
C语言中字符串被编码为一个以null字符结尾的字符数组,每个字符都由某个标准编码来表示,最常见的是ASCII字符码。
2.1.5 表示代码
对于同一个C函数,指令编码是不同的,在不同的操作系统上有不同的编码规则,因此二进制代码是不兼容的。
2.1.6 布尔代数简介
布尔代数:围绕数值0和1的数学知识体系,基本运算包括NOT(~)、AND(&)、OR(|)和EXCLUSIVE-OR(^)。
位向量:用以编码任何子集,集合中含有数字几,那么位向量从右往左第几位就为1。
2.1.7 C语言中的位级运算
利用布尔代数的性值进行运算即可。
位级运算的常见用法:掩码运算。
2.1.8 C语言中的逻辑运算
这部分对应为||、&&、!,对应于命题逻辑的OR、AND和NOT运算。
逻辑运算和位级运算的区别:
逻辑运算返回1或者0,位运算只有参数被限制为0或者1时,才和与其对应的逻辑运算有相同的行为;
对于第一个参数求值就能确定表达式的结果,那么逻辑运算符就不会对第二个参数求值(a&&5/a不会造成被零除,p&&*p++不会导致间接引用空指针)
2.1.9 C语言中的移位运算
移位计算:x<<k,向左移动k位,丢弃最高的k位,并在右端补k个0;对于右移,分为逻辑与算术右移,逻辑右移在左端补k个0,算术右移是在左端补k个最高有效位的值。
对于C语言,几乎所有的编译器/及其组合都会选择算术右移;对于java,>>是算术右移,>>>是逻辑右移。
如果移动k位,k非常大,大过操作数w,那么实际位移量为k mod w。
移位的优先级较低,加减法的操作符优先级高于移位。