深入理解计算机系统(CSAPP)笔记

Posted by QingJun's Blog on January 20, 2021

第一章 计算机系统漫游

计算机系统是由硬件和系统软件组成的。

跟踪 hello 程序的生命周期开始对系统的学习

1
2
3
4
5
6
#include <stdio.h>

int main(){
    printf("hello world\n");
    return;
}

程序的每个字符根据 ASCII 标准转换为字节,hello.c 程序是以字节序列的方式储存在文件中

系统中的所有信息都是由一串比特表示的,区别不同数据对象的方法是读到数据对象时的上下文

GCC 编译驱动程序读取源程序文件 hello.c ,并把它翻译成一个可执行文件 hello。这个翻译过程可分为四个阶段。

  • 预处理阶段,预处理器(cpp)根据字符 # 开头的命令,修改原始的 C 程序,得到 .i 文件
  • 编译阶段,编译器(ccl)将 .i 文件翻译成 .s 文件,它包含一个汇编语言程序,该程序包含函数 main 的定义
  • 汇编阶段,汇编器(as)将 .s 文件翻译成机器语言指令,把这些指令打包成一种叫做可重定位目标程序的格式,并将结果保存在 .o 文件
  • 链接阶段,hello 程序调用了 printf 函数,它位于 printf.o 中,这个文件必须合并到 hello.o 中,连接器(ld)就负责处理这种合并。结果得到 hello 文件,是一个可执行文件,可以被加载到内存中,由系统执行。

虚拟内存,下面从低地址到高地址介绍

  • 程序代码和数据,进程开始运行时指定大小
  • 堆,运行时堆,用 malloc 和 free 可以动态扩展和收缩堆
  • 共享库,存放 C 标准库和数学库这样的共享库的代码和数据
  • 栈,编译器用栈来实现函数调用,可以动态扩展和收缩
  • 内核虚拟内存,为内核保留,不允许应用程序读写

操作系统内核是应用程序和硬件之间的媒介,它提供了三个抽象

  • 文件,对 I/O 设备的抽象
  • 虚拟内存,对程序存储器(主存、磁盘)的抽象
  • 进程,对正在运行程序(处理器、主存、I/O 设备)的抽象

虚拟机,对计算机的抽象

第一部分 程序结构和执行

第二章 信息的表示和处理

三种最重要的数字表示:无符号编码,补码编码,浮点数编码

字长,决定虚拟地址空间的最大大小

  • C 语言中的位级运算(按位)

    • ,OR
    • &,AND
    • ~,NOT
    • ^,异或

    位级运算的常见用法是掩码运算

  • C 语言中的逻辑运算

    •   ,OR
    • &&,AND
    • !,NOT
  • C 语言中的移位运算

    • 左移
    • 右移,算术右移和逻辑右移

第三章 程序的机器级表示

编译选项

  • -Og,-O1,-O2,从低到高表示不同优化级别

  • -S,生成汇编文件,.s 文件
  • -c,生成目标代码文件,.o 文件
  • prog,生成可执行文件

汇编语言

数据对齐

许多计算机系统对基本数据类型的合法地址做出了一些限制,要求某种类型对象的地址必须是某个值的 K(通常是 2,4 或 8) 的倍数。

任何 K 字节的基本对象的地址必须是 K 的倍数

无论数据是否对其,都能正确工作,但对齐后执行的内存访问次数少

GNU 的调试器 GDB

第四章 处理器体系结构

第五章 优化程序性能

内存别名使用

在只执行安全的优化中,编译器必须假设不同的指针可能会指向内存中同一个位置

用内联函数替换优化函数调用

使用命令行选项 “-finline”,或者优化等级 -O1 及以上

消除循环的低效率

减少过程调用

消除不必要的内存引用

第六章 存储器层次结构