《深入理解计算机系统》读书笔记

第一章 计算机系统漫游

1.1 信息就是位+上下文

这里的就是比特

源程序就是由值0和1组成的比特序列。八个比特组织成一组,称为字节。每个字节表示程序中某些文本字符。大部分现代计算机系统使用ASCII标准表示字符。实际上就是一个唯一的单字节大小的整数值表示每个字符。

系统中所有的信息都是由一串比特表示的。区分不同数据对象的唯一方法就是读到这些数据对象时的上下文。 所以说,一个相同的字节序列可以表示出不同的内容。

C从一开始就是作为Unix系统的程序语言开发出来的。大部分Unix内核以及所有支撑工具就是用C编写的。同样,C语言还缺乏对非常有用的抽象的显式支持,例如类,对象和异常。

1.2 程序被其他程序翻译成不同的格式

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

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

linux> gcc -o hello hello.c

这里的-o指令,就是指定编译后的可执行文件保存在哪里。

GCC编译器驱动程序读取源程序hello.c,翻译成一个可执行目标文件hello。一共四个阶段。

  • 预处理阶段。预处理器(CPP)根据#开头的命令,修改原始的C程序。比如#include<stdio.h>会直接将stdio.h的内容插入程序文本,得到.i扩展名的文件。
  • 编译阶段。编译器(ccl)将.i文件翻译成文本文件hello.s,包含一个汇编语言程序。汇编语言为不同高级语言的不同编译器提供了通用的输出语言。
  • 汇编阶段。汇编器(as)将.s文件翻译成机器语言指令。把这些指令打包成一种叫做可重定位目标程序的格式,并将结果保存在.o文件中。.o扩展名文件是一个二进制文件。
  • 链接阶段。例如调用了printf函数,这个函数出自标准C库。存在于一个名为printf.o的单独预编译好了的目标文件中,需要合并到最终的.o文件中。链接器(ld)就负责处理这种合并。结果就得到了可执行目标文件,可以被加载到内存中,由系统执行。

GCC是GNU项目开发出的工具之一。GNU全称:GNU’s Not Unix。目标开发出一个类Unix的系统。(似乎是因为Unix收费且不开源)。GNU开发出一个包含Unix操作系统的所有主要部件的环境,但不包括内核。内核是Linux项目独立发展的。现在开源的思想源头就是GNU的自由软件概念。且Linux如此受欢迎也要感谢GNU提供的环境。

GCC编译器已经发展到支持很多语言了。能够为许多不同的机器生成代码。如C,C++,Fortran,Java,Pascal,Obj-C,Ada。

1.3 了解编译系统如何工作是大有益处的

一些原因促使程序员必须知道编译系统是如何工作的。

  • 优化程序性能。需要了解一些机器代码及编译器将不同的C语句转化为机器代码的方式。例如:while循环是否比for循环更有x?switch语句是否比一系列if-else语句高效的多?
  • 理解链接时出现的错误。一些最令人困扰的程序错误往往都与链接器有关。例如:静态变量与全局变量的区别是什么?链接器报告说它无法解析一个引用,这是什么意思?
  • 避免安全漏洞。缓冲区溢出错误是造成大多数网络和Internet服务器上安全漏洞的主要原因。要理解数据和控制信息存储在程序栈上的方式会引起的后果。

1.4 处理器读并解释在内存中的指令

1.4.1 系统的硬件组成

总结

总体来说还是处于启蒙阶段,提出一些问题,告诉你后几章会讲解到。

无聊的吐槽

2019.12.17:准备开写,希望入土前能写完