《深入理解计算机系统》读书笔记2---关于存储的思考

来源:互联网 发布:如何做好商务工作 知乎 编辑:程序博客网 时间:2024/05/08 01:36

1.源代码

源代码是文本形式存在的bytes,是一种字符编码。

对于每一个字符进行编码,可能是ASCII,可能是GB2312,可能是UTF-8。

然后存储在硬盘的某个地方。


2.程序运行时

这里我暂时不考虑运行时分配的东西,也不考虑类似于C++中的中的vector,还有Python中的list这种可以随时改变元素个数,甚至元素类型的结构。

只考虑C语言中的那些基本结构。

那么在程序运行时,程序加载到内存中,也有存储方式。


(1)变量数据

里面主要包括:①整数 ②浮点数 ③字符串 ④指针

①整数

根据不同的类型,确定不同的位长度。

符号数按照补码编码。

无符号数按照正常的二进制编码。

注:无符号数不是按照原码编码的,原码仍然是一种有符号的编码方式。

②浮点数

还没有看到那里,反正是某种编码方式。

③字符串

实际就是一个字符数组,里面的每一个数组元素都是一个字符,字符就按照字符编码。

具体的编码方式就有很多种了。

④指针

指针变量存储的是地址,这里它由于没有必要表示负数,因为内存空间以byte为寻址单位,范围从0-xGB

我这里还没弄清楚什么编码方式,猜想用直接的二进制编码即可。


注:由于整数和浮点数存在需要多个字节来表示一个完整的个体的情况(比如4bytes才能表示1个int),所以存在大端小端序不同。

而在每一个byte之中,其实大端小端都是一样的。

所以对于文本形式的字符串,它的每一个独立的个体即字符的表达是不会存在大小端的困扰的,那么字符串也就不会存在这个困扰了。

所以如果都用来表示数字的话,字符串移植性更强但是缺点是表示同样大小的数字耗费空间更多。


(2)函数/程序代码

运行的时候,在内存中,函数代码一开始就会分配空间进行存放。

既然已经在内存中了,所以本来的代码是已经被编译为二进制加载进去的了。

我的想法是,函数的调用也像用指针指向变量一样,是有一个指针指向函数所在的代码的,代码在内存中有固定分配的地方存储,

然后再加载到CPU里执行。


2015/10/2补充。

深入理解计算机系统(图在P554,图9-26),告诉我,一般用户空间有栈,共享库,堆,代码段(包括.bss .data .text),但是今天看到说其实数据库就类似于一个struct数组,然后有一段这样的程序。

#include <stdio.h>
#include <stdlib.h>


int main()
{
    typedef struct{
        char* name;
        int id;
    } student;


    student a[2];

    a[0].name = "John";
    a[0].id = 1;
    a[1].name = "Sam";
    a[1].id = 2;


    printf("the content of a[0] is %s and %d\n", a[0].name, a[0].id);
    printf("the content of a[1] is %s and %d\n", a[1].name, a[1].id);


    return 0;
}


程序是完全能跑通的,在分析这段程序的时候,发现其他的都好理解,a[2]是局部变量,在栈中,然而,srutct中的name指针,指向的数据,比如“John”是放在哪里的呢?

后来我查了资料,才知道来还有一个地方就做.rodata的地方,是用来存放const以及字符串常量这样的。

这在CSAPP里面倒是没有提到。

注:①.rodata是用来存放const以及立即数这种的,但是const以及立即数并不一定在这里,可能在.text里面有可能。

②.rodata存在的地方,由于是多进程共享的空间,所以CSAPP以进程为概念来讲解虚拟地址空间时,没有提到.rodata也许也有作者自己的考虑。

0 0
原创粉丝点击