CSAPP学习记录:1、数据的表示

2017-04-25


在开始之前……

15123号称CMU第一镇校神课,其中所用的教材就是CSAPP(Computer System: A Programmer’s Perspective) 展示了从数据在机器中的表示,程序的机器级表示到web服务等等内容,蔚为大观。

很早就想要一点点把这本书啃下来,同时通过完成课后lab巩固知识。这个想法已经成形很久了,但由于大二以来 的种种奇葩事情和自己的懒惰导致一拖再拖……

最近听闻参加BAT春招的学长铩羽而归,主要还是基础不扎实的问题。即使之前拥有丰富的项目经验,数据结构、算法、 操作系统原理这些东西如果没有扎实的基础,也难以更上一层楼。希望在今年暑假结束之前能够通过15123的ppt和csapp、 课程对应的labs把之前遗漏的CS基础知识补上。


正文

相信每个稍有编程基础的人都会知道,计算机中使用不同的二进制来编码数值。本章以C中的数值表示为基础, 讨论现代计算机中的数值表示方法。

C效率高的原因之一就在于它直接采用了机器中数的表示方法来表示数据——通过一些巧妙的转换你可以观察到 机器中数字的表示方法。以int为例:

typedef unsigned char* byte_pointer;

void show_bytes(byte_pointer start, int len) {
    int i;
    for (i = 0; i < len; i++) {
        printf(" %.2x", start[i]);
    printf("\n");
}

void show_int(int x) {
    show_bytes((byte_pointer) &x, sizeof(int));
}

char类型的变量在内存中占一个字节,int类型占四个字节。将指向int变量的指针强制转换成char*类型, 并以16进制的形式打印,可以观察到整数在机器中的16进制形式。

CMU提供的关于本章的实验datalab中就直接提供了相关程序让你查看数的16进制形式:

~/CSAPP-Labs/datalab-handout$ ./ishow -1234
Hex = 0xfffffb2e,	Signed = -1234,	Unsigned = 4294966062

大端与小端

你可能会自然而然地认为,一个数字是按顺序存储的,最低有效字节在后,最高有效字节在前, 就像我们平常书写阿拉伯数字一样……然而机器中并不一定是这样子表示数的! 有的机器是按照最低有效字节在前,最高有效字节在前的顺序。前者被成为大端法(big endian), 后者则叫做小端法(little endian)。这个叫法来源于《格列佛游记》,csapp中对此给出了一些有趣的描述。


C中的布尔运算

C还有一个重要的特性就是支持按位布尔运算。如果你有学过离散数学和数字逻辑的话对此一定不会陌生 (突然想起来我再过两周就要考数字逻辑了QAQ)在写datalab时踩到过一些关于移位的坑。 C中移位分为逻辑移位和算术移位,无符号数的算数移位必须是逻辑的,而理论上,有符号数就不一定了—— 不过在大部分编译器中对有符号数实行算数移位。同时,在底层实现除法取模这些运算时,也可能会用到 移位运算。对于除以2的幂的运算,直接通过移位获得除法的结果可比其它方式实现快多啦。


整数,浮点数;有符号数,无符号数

这些部分在计算机组成原理中学过了不少……但远远想不到这些看似又理论又枯燥的东西部分在实际编程 中有很广泛的应用。