《深入理解计算机系统》——读书笔记(一)

  这本书从一个简单的C语言的hello程序讲起...

  这是这个小程序的生命周期的一个部分:

  hello程序,从被创建(文本格式),到被执行(在屏幕上打印出来)。

  其间,有个翻译过程,即将高级程序语言(如这里的hello程序),翻译成计算机能理解的二进制语言。

  这个翻译过程,分为四个阶段。

  1. 预处理阶段:预处理器根据以字符“#”开头的命令,修改原始的C程序(修改后,仍然是C程序)。比如上面 hello程序中的第一行中的#include<stdio.h>,这行语句告诉预处理器,让它读取 stdio.h 这个文件(实际上,这个文件即库函数,它提供了你所需要的函数和一些变量的声明),并把它插到hello程序的文本中。最后,得到一个在原有语句的基础上,增加了一些语句的C程序(hello.i)。

  2. 编译阶段:将高级程序语言翻译成汇编语言。一般说来,不同的高级程序语言(如C和Java),在经过编译后,得到的是一样的一样的汇编语言文件(hello.s)。

  3. 汇编阶段:将汇编语言翻译成机器语言(即只有0和1的二进制语言),此时,得到的是二进制文件(hello.o)
    Plus:Java的字节码文件不是二进制文件。

  4. 链接阶段:可以看到,HelloWorld程序调用了printf()函数,该函数的函数原型(类似于函数头声明)在 stdio.h 文件中。这个函数的完整体存在于一个名为 printf.o 的文件中,而这个文件必须以某种方式合并到我们的hello.o 程序中。链接器的任务就是负责处理这种合并。结果得到 hello.exe文件,它是一个可执行目标文件(它可以被加载到计算机内存中,由系统执行)

 

  我们为什么要知道编译系统是如何工作的呢?

  • 优化程序性能。我们无需为了写出高效代码而去理解编译器的内部工作。但我们需要了解一些机器代码以及编译器将不同的C语句转化成机器代码的方式,以做出更好的编码方式选择。比如一个switch语句是否比一系列的if-else语句高效?while循环比for循环有效吗?等等。

  • 理解编译时的错误,更快地解决问题。

  • 避免安全漏洞。

  刚才,我们讨论了 hello程序的被翻译的过程,接下来,我们进一步地讨论它被执行的过程。为了理解这个过程,我们需要一些系统硬件知识的铺垫。如下图所示,是一个典型系统的硬件组织图。

  • I/O总线:贯穿整个系统的一组电子管道,它负责将固定大小的信息字节块在各个部件间进行传输。一般来说,信息字节块的大小不是4个字节(对应32位),就是8个字节(对应64位)。

  • I/O设备(总线下方):I/O(输入/输出)设备是系统与外部世界的联系通道。比如上图的:鼠标、键盘、显示器、磁盘都属于I/O设备。这些设备通过控制器或适配器与I/O总线相连。控制器和适配器的区别在于它们的封装方式控制器是电脑主板上的芯片组,而适配器则是一块插在电脑主板插槽上的卡。但无论如何,它们的功能都是在总线和I/O设备之间传递信息。

  • 主存储器(总线右上方):

 

  • 中央处理器(CPU):简称处理器,是解释(或执行)储存在主存中的指令的引擎。CPU的核心是一个大小为一个字节的储存设备,寄存器(又称为程序计数器PC),它存放了当前正在执行的指令(在主存中)的地址,以及下一条指令(在主存中)的地址。

 

posted @ 2018-07-18 00:19  Ezreal_Geek  阅读(392)  评论(0编辑  收藏  举报