【CSAPP】程序结构和执行

第二章 信息的表示和处理

2.1 信息存储

2.1.1 十六进制表示法

16进制和2进制相互转换

2.1.2 字数据大小

不同类型的变量在32位机器和64位机器上的变化、程序从32位机器迁移到64位机器可能引发错误。

image

2.1.3 寻址和字节顺序

大端(bit endian)、小端(little endian)

image


不同字节顺序的重要性体现在:

  • 网络传输中,发送和接受需要统一标准
  • 汇编代码表示的字节数据和日常阅读习惯不同
  • 指针类型强转后,编译器将指针指向的单元看作字节序列,字节序列在不同平台上使用不同的字节顺序存储

2.1.4 表示字符串

"123" 在机器中的存储用16进制表示为 31 32 33 00,字符串以0x00终止。

2.1.5 表示代码

不同操作系统编译出的二进制代码不同。二进制代码在不同环境下不兼容。

2.1.6 布尔代数简介

| & ~ ^ 运算

image

2.1.7 C语言中的位级运算

交换变量值的小技巧:

void inplace_swap(int *x, int *y) {
	*y = *x ^ *y;
	*x = *x ^ *y;
	*y = *x ^ *y;
}

2.1.8 C语言中的逻辑运算

|| && ! 不适用于位级运算

2.1.9 C语言中的位移运算

逻辑右移:补0

算数右移:补最高位的值,最高位是0补0,是1补1

C语言中,w位的值右移k位,k>=w:实际位移(k mod w)位

C语言中,>> << 的优先级小于 + -

2.2 整数表示

2.2.1 整形数据类型

2.2.2 无符号数的编码

2.2.3 补码编码

2.2.4 有符号数和无符号数之间的转换

无符号数和补码向量公式:

image
image

补码和无符号数的转换公式:x表示十进制数字

\[T2U_{w}(x) \doteq B2U_{w}\left (T2B_{w}(x) \right), TMin_{w} \leqslant x \leqslant TMax_{w} \]

\[U2T_{w}(x) \doteq B2T_{w}\left (U2B_{w}(x) \right), 0 \leqslant x \leqslant UMax_{w} \]

由以上公式可以推导出:

image
image


推导过程

首先定义:$$ \vec x = T2B_{w}(x) = U2B_{w}(x) $$

由公式2.1和2.3推到得出:

\[B2U_{w}( \vec x) - B2T_{w}( \vec x) \doteq x_{w-1}2^{w} \]

则可连续推导出:

\[T2U_{w}(x) \doteq B2U_{w}(T2B_{w}(x)) \doteq B2U_{w}(\vec x) \doteq x_{w-1}2^{w} + B2T_{w}(\vec x) = x_{w-1}2^{w} + B2T_{w}(T2B_{w}(x)) \doteq x_{w-1}2^{w} + x \]

通过第w-1位是0还是1的讨论即可得出公式2.5

类似的:

\[U2T_{w}(x) \doteq B2T_{w}(U2B_{w}(x)) \doteq B2T_{w}(\vec x) \doteq B2U_{w}(\vec x) - x_{w-1}2^{w} \doteq B2U_{w}(U2B_{w}(x)) - x_{w-1}2^{w} \doteq x - x_{w-1}2^{w} \]

通过第w-1位是0还是1的讨论即可得出公式2.7


总结来说

一串bit位,可以看做无符号数,也可看作有符号数。对于它本身,将其看作 无符号数 减 将其看作有符号数,结果有两种情况:

  • 等于0,即最高位是0,两个数大小一致
    比如0001 - 0001 = 0000

  • 等于2^w,即有符号数最高位是1
    比如1001 - 1001 = 9 - (-7) = 16 = 2^4

2.2.5 C语言中的有符号数和无符号数

%d %u %x 分别用于表示十进制、无符号十进制、十六进制

在补码和无符号数转换时(类型强转、隐式转换),底层执行T2U或U2T算数运算

当无符号数和有符号数 运算比较 时,会默认将有符号数当作无符号数对待,并进行计算;

2.2.6 扩展一个数字的位展示

posted @ 2022-06-13 16:47  moon_orange  阅读(34)  评论(0编辑  收藏  举报