CSAPP-第一章

前言

计算机系统是由硬件和系统软件组成的,它们共同工作来运行应用程序。在当今,所有计算机系统都有相似的硬件和软件,又执行着相似的功能,为了深入了解这些组件是如何工作的以及这些组件是如何影响程序的正确性和性能的,以此来提高自身的性能。

1.1 infomation is Bits + Context

1.1讲解了文件信息在计算机系统是以什么形式存储的,比如我们的hello.c源文件,在计算机系统中是如何识别每一个字符的

源程序实际上就是一个由值0或1的位(比特)组成的序列,8个位组成的序列为为一组,被称为字节。每个字节表示程序中的某些文本字符,不同的编码意味着一样的字符,比如中文汉字国,在不同的编码,比如,ANSI,UTF-8,GBK,GB2312,由不同的字节组成

所以hello.c这个源文件,在这个计算机系统中,是以ASCII编码规范来存储字符序列的
比如 : #include <stdio.h>
以ASCII码存储在文件中的内容是:35 105 110 99 108 117 100 101 32 60 115 116 100 105 111 46 104 62,那么这些数字在ASCII码的编码规范下都是以一个字节存储在文件中。
像hello.c这样只由ASCII字符构成的文件称为文本文件,所有其他文件都称为二进制文件

hello.c的表示方法说明了一个基本思想:系统中的所有信息–包括磁盘文件,内存中的程序,内存中存放的用户数据以及网络上传送的数据,都是一串比特组成的。
区分不同数据对象的唯一方法就是我们读到这些数据对象时的Context,在我看来就是编码方式,比如同一个字节序列,在不同的编码方式下就是不同的内容

1.2Programs Are Translated by Other Programs into Different Forms

1.2讲解了源文件被什么程序通过什么处理过程逐渐成为一个可执行程序的

为了让系统运行hello.c,需要将每条C语句被其他程序转化为一系列的低级机器语言指令。然后这些指令按照一种成为可执行目标程序的格式打好包,并以二进制磁盘文件的形式存放起来。目标程序也被称为可执行目标文件。

在Unix系统上,从源文件到目标文件的转化是由编译器驱动程序完成的

gcc -o hello hello.c

gcc 编译器驱动程序 执行四个阶段的程序(预处理器,编译器,汇编器和链接器)把hello.c翻译成一个可执行的目标文件hello

预处理器,通过修改源文件的文本,将以#开头的C语言程序进行替换插入,生成hello.i的文本文件

编译器,将文本文件hello.i翻译成文本文件hello.s,也就是将所有的C语言代码转变为汇编语言程序

汇编器,将hello.s翻译成机器语言指令,也就是全是0或1的指令,然后汇编器将这些指令进行打包,形成一种叫做可重定位目标程序,并将结果形成hello.o的二进制文件

链接器,由于hello.c调用了标准io库stdio.h的printf函数,而printf函数的源代码存在于一个提前编译好的二进制文件printf.o中,所以链接器将printf.o合并到hello.o文件中,那么hello.o就能够实现printf的功能,合并之后生成可执行文件hello

将可重定位目标程序hello.o进行反汇编,要使用objdump工具

objdump -d hello.o

1.3 It Pays to Understand How Compilation Systems Work

1.3强调了理解编译系统工作原理的重要性
1.优化程序效率,例如switch 和 if
2.理解链接时的错误
3.避免安全漏洞,如缓冲区溢出的漏洞

1.4 Processors Read and Interpret Instructions Stored in Memory

shell 是一个命令行解释器,如果该命令行的第一个单词不是一个内置的shell命令,那么shell就会假设这是一个可执行文件的名字,它将加载并运行这个文件。

1.4.1 Organization of System

为了理解运行hello程序时发生了什么,我们需要了解一个典型系统的硬件组织

总线

贯穿整个系统的一组电子管道,称为总线,它携带信息字节并负责在各个部件间传递。总线一次传输定长的字节数,称为字,字时一个基本的系统参数,有32位和64位

I/O设备

I/O设备就是输入Input和输出Output设备,是外设比如键盘鼠标显示器等等
每个I/O设备都通过一个控制器或适配器与I/O总线相连,控制器和适配器之间的区别在于他们的封装方式,控制器是I/O设备本身或者系统的主板上的芯片组,而适配器则是一块插在主板插槽上的卡。

主存

主存是一个临时存储设备,在处理器执行程序时,用来存放程序和程序处理的数据。从物理上来说,主存是由一组DRAM(动态随机存取存储器)组成的。

处理器

中央处理单元(CPU),简称处理器,是解释(或执行)存储在主存中指令的引擎。处理器的核心是一个大小为一个字的存储设备(或寄存器),称为程序计数器,在任何时刻,PC都指向主存中的某条机器语言指令(即含有该指令的地址)

从系统通电开始,直到系统断电,处理器一直在不断地执行程序计数器指向的指令,再更新程序计数器,使其指向下一条指令。处理器看上去是按照一个非常简单的指令执行模型来操作的,这个模型是由指令集架构决定的。在这个模型中,指令按照严格的顺序执行,而执行一条指令包含执行一系列的步骤

处理器从程序计数器指向的内存处读取指令,解释指令中的位,执行该指令指示的操作,然后再更新PC,使其指向下一条指令

处理器看上去是它的指令集架构的简单实现,但是实际上现代处理器使用了非常复杂的机制来计算程序的执行。因此,我们将处理器的指令集架构和处理的微体系架构区分:指令集架构描述的是每条机器代码指令的效果,而微体系结构描述的是处理器实际上是如何实现的

1.4.2how system process when program works

使用DMA技术,hello程序直接加载到主存储器,处理器之后开始执行hello程序的指令,这些指令将hello world字符串中的字节从主存储器复制到寄存器文件,再从寄存器文件中复制到显示设备,最终显示在屏幕上