[学习笔记]《CSAPP》深入理解计算机系统 - Chapter 2 信息的表示和处理

2.1 信息存储

  1. 8 位的块代表一个字节,作为最小的可寻址内存单位,而不是直接访问内存中单独的位。内存的每个字节都由唯一的一个数字来标识,成为它的地址,所有可能地址的集合被称为虚拟地址空间(virtual address space)
    理解:内存中是一位一位的块,且是2进制的,每八位代表一个字节块,而计算机中使用的就是这个块, 而每个块的起始由一个数字表示。
    在现代计算机中,以32位操作系统来举例,cpu只能寻址32位的话,那么表示能寻到的地址范围是
    0^0 ~ 0^32-1 那么最终的结果就是 0^32 / 1024 / 1024 = 4GB.

  2. C 语言中,一个指针的值都是某个存储块的第一个字节的 虚拟 虚拟 虚拟地址, C 编译器把每个指针和类型 信息联系起来,这样就可以根据指针值得类型,生成不通得机器级代码,来访问存储在指针所指向位置处得值。但生成得实际的机器码并 不包含 不包含 不包含关于数据类型的信息。

  • question: 指针本身是什么,存储在哪儿?
    • 指针的存储:指针本身作为一个变量,它的值(即它指向的地址)存储在内存中的某个位置。这个位置的地址是由操作系统的内存管理单元(MMU)和编译器在程序运行时动态分配的。
    • 地址的分配:当程序创建一个指针变量时,操作系统和编译器会决定这个指针变量的存储位置。这个过程涉及到内存分配算法,如堆分配、栈分配或全局/静态存储区分配。
  1. “32位”程序或“64位”程序取决于该程序是如何编译的,而不是其运行的机器类型。比如,使用 linux> gcc -m32 prog.c 编译的程序,可以同时在32位和64位机器上运行,反之,-m64 就只能在 64位机器上运行。

  2. 随着标准的变化,在C语言中,建议使用指定大小的类型,比如:int32_tint64_t来避免不同架构或机器上的位的差别。

  3. 在现代计算机的历史中,为什么说,一个声明为int类型的程序对象能被用来存储一个指针,这在大多数32位的机器上能够正常工作,但是在一台64位的机器上却会导致问题?

    • int 类型的对象在32位和64位大小一般都为 4 字节, 但 sizeof(pointer*)64 位机器上为 8 字节,用内存占据 4 字节的类型对保存 8 字节的指针信息,是不够的,会有内存溢出问题。

大小端

排列表示一个对象的字节有两个通用的规则。考虑一个 w 位的整数,其位表示为:
[X_w-1, X_w-2, ..., X_1, X_0], 其中,X_w-1是最高有效位,而X_0是最低有效位。假设w8的倍数,这些位就能被分组为字节,其中最高有效字节包含位[X_w-1, X_w-2, ..., X_w-8], 而最低有效字节包含[X_7, X_6, ..., X_0]
某些机器选择在内存中按照从最低有效字节到最高有效字节的顺序存储对象,这种是----小端存储
某些机器选择在内存中按照从最高有效字节到最低有效字节的顺序存储对象,这种是----大端存储

一个测大小端的 c 代码示例, 只有核心部分:

char *c = NULL;
int value = 0x12345678;
int i = 0;
for (i; i < 4; i++) {
    c = (char*)&value + i;
    printf("0x%.2x\n", *c);
}

补码/反码/原码

目前的理解,所谓的补码,源码,反码,就是对第一个也就是最高位的处理方式的不同
源码和反码我很少遇到过。
补码常用于做有符号数和无符号数的转换

其规则: 数值可能会改变,但是位模式不变

  • 补码,w 代表位数

B 2 T w = − X w − 1 ⋅ 2 w − 1 + ∑ i = 0 w − 2 x i 2 i B2T_w = -X_{w-1}·2^{w-1} + \sum_{i=0}^{w-2}x_i2^i B2Tw=Xw12w1+i=0w2xi2i

int a = -1;
gdb: p/t a
gdb: 11111111111111111111111111111111

在这里插入图片描述

  • 反码
    +0: [00…0]
    -0: [11…1]
    B 2 O w = − X w − 1 ⋅ ( 2 w − 1 − 1 ) + ∑ i = 0 w − 2 x i 2 i B2O_w = -X_{w-1}·(2^{w-1}-1) + \sum_{i=0}^{w-2}x_i2^i B2Ow=Xw12w11+i=0w2xi2i

  • 原码
    +0: [00…0]
    -0: [10…0]
    B 2 O w = ( − 1 ) x w − 1 ∑ i = 0 w − 2 x i 2 i B2O_w = (-1)^{x_{w-1}}\sum_{i=0}^{w-2}x_i2^i B2Ow=(1)xw1i=0w2xi2i

乘以常数

大多数机器上,乘法指令相当慢,需要 10 个或者更多的时钟周期,但其他的整数运算,如加法、减法、位级运算和移位只需要 1 个始终周期。
编译器会使用一些优化手段,试着用移位和加法运算的组合来代替乘以常数因子的乘法。

x ∗ 14 − − > 2 3 + 2 2 + 2 1   o r   ( x < < 4 ) − ( x < < 1 ) / / ( 14 = = 2 4 − 2 1 ) x * 14 --> 2^3 + 2^2 + 2^1 \ or \ (x << 4) - (x << 1) //(14 == 2^4 - 2^1) x14>23+22+21 or (x<<4)(x<<1)//(14==2421)

  • 无论是无符号还是有符号(补码)运算,乘以 2 的幂都有可能会导致溢出. (也就是左移操作)

浮点数,二进制小数

十进制: d = ∑ i = − n m 1 0 i × d i 十进制: d = \sum_{i=-n}^m10^i×d_i 十进制:d=i=nm10i×di
因此
12.3 4 10 = 1 ∗ 1 0 1 + 2 ∗ 1 0 0 + 3 ∗ 1 0 − 1 + 4 ∗ 1 0 − 2 = 12 ∗ 34 100 12.34_{10} = 1*10^1 + 2*10^0 + 3*10^{-1} + 4*10^{-2} = 12*\frac{34}{100} 12.3410=1101+2100+3101+4102=1210034

对于有限长度的编码,那么十进制表示法不能准备表达像
1 3 \frac{1}{3} 31 5 7 \frac{5}{7} 75这样的数。类似,小数的二进制表示法只能表示能够被写成
x ∗ 2 y x*2^y x2y的数。其他的值只能够被近似地表示

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Artintel

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值