(一)计算机系统漫游
从某种意义上来说,本书的目的就是要帮助你了解当你在系统上执行hello程序时,系统发生了什么以及为什么会这样。
#include <stdio.h>
int main()
{
printf("hello, world\n");
return 0;
}
信息就是位 + 上下文
hello程序的生命周期是从一个源程序开始的,源程序实际上就是一个由值0和1组成的位序列,8个位被组织成一组,称为字节。每个字节表示程序中的某些文本字符。
像hello.c这样只由ASCII字符构成的文件称为文本文件,所有其他文件都称为二进制文件。
GCC编译器驱动程序读取源程序文件hello.c,并把它翻译成一个可执行目标文件hello。这个翻译过程可分为四个阶段完成,执行这四个阶段的程序(预处理器、编译器、汇编器和链接器)一起构成了编译系统。
预处理阶段:预处理器根据以字符#开头的命令,修改原始的C程序。比如hello.c中第1行的#include <stdio.h>命令告诉预处理器读取系统头文件stdio.h的内容,并把它直接插入程序文本中。结果就得到了另一个C程序,通常以.i作为文件扩展名。
编译阶段:编译器将文本文件hello.i翻译成文本文件hello.s,它包含一个汇编语言程序。
汇编阶段:汇编器将hello.s翻译成机器语言指令,把这些指令打包成一种叫做可重定位目标程序的格式,并将结果保存在目标文件hello.o中。hello.o文件是一个二进制文件,它包含的17个字节是函数main的指令编码。
链接阶段:printf函数存在于一个名为printf.o的单独的预编译好的目标文件中,而这个文件必须以某种方式合并到我们的hello.o程序中。链接器就负责处理这种合并,结果得到一个可执行目标文件,可以被加载到内存中,由系统执行。
了解编译系统如何工作
1 优化程序性能:为了在C程序中做出好的编码选择,我们需要了解一些机器代码以及编译器将不同C语句转化为机器代码的方式。
2 理解链接时出现的错误:一些最令人困扰的程序错误往往都与链接器操作有关,尤其是试图构建大型的软件系统时。
3 避免安全漏洞:缓冲区溢出错误是造成大多数网络和Internet服务器上安全漏洞的主要原因。存在这些错误是因为很少有程序员能够理解需要限制从不受信任的源接收数据的数量和格式。
处理器
从系统通电开始,直到系统断电,处理器一直在不断地执行程序计数器指向的指令,再更新程序计数器,使其指向下一条指令。
内核
内核不是一个独立的进程,相反,它是系统管理全部进程所用代码和数据结构的集合。
Amdahl定律
当我们对系统的某个部分加速时,其对系统整体性能的影响取决于该部分的重要性和加速程度。
有时候对系统的一个主要部分做出重大改进,但是获得的系统加速比却明显小于这部分的加速比。这就是Amdahl定律的主要观点——要想显著加速整个系统,必须提升全系统中相当大的部分的速度。