本章从简单的hello,world程序讲起,讲解了系统为了执行该程序时,系统发生了什么以及为什么会这样

#include <stdio.h>int main(){printf("hello,world\n");return 0;
}

1.1 信息就是位+上下文

一个程序的生命周期是从一个源程序开始的,即程序员通过编辑器创建并保存的文本文件。

源程序实际上就是由值0和1组成的位(比特)序列

大部分的现代计算机系统都使用ASCII标准来表示文本字符

hello.c的表示方法说明了一个基本思想:系统中的所有信息----包括磁盘文件、内存中的程序,内存中存放的用户数据以及网络上上传的数据,都是由一串比特表示的

1.2 程序被其他程序翻译称为不同格式

为了在系统上运行hello程序,每条C语句都必须被其他程序转化为一系列的低级机器语言指令

linux中,GCC编译器驱动程序读取源文件hello.c,并把它翻译为一个可执行目标文件hello。

linux> gcc -o hello hello.c

这个翻译过程可分为四个阶段完成, 如图1-3所示。 执行这四个阶段的程序(预处理器、 编译器、 汇编器和链接器一起构成了编译系统

预处理阶段

预处理器(cpp)根据以字符#开头的命令, 修改原始的C程序,将头文件的内容直接插入程序文本中得到以.i作为扩展名的文件

编译阶段

译器(eel)将文本文件hello.i 翻译成文本文件hello.s, 它包含一 个汇编语言程序。该程序包含函数main的定义,如下

mainsubq $8,%rspmovl $.LC0,$edicall putsmovl $0,$eaxaddq $8,%rspret

汇编阶段

汇编器(as) 将 hello.s 翻译成机器语言指令,把这些指令打包成一种叫做可重定位目标程序(relocatable object program) 的格式,并将结果保存在目标文件 hello.o 中。 hello.o 文件是一个二进制文件,它包含的 17 个字节是函数 main 的指令编码。

链接阶段

链接器(Id) 负责将本程序中使用到的C编译器提供的标准C库的函数与本文件链接起来,得到 hello 文件,它是一个可执行目标文件 (或者简称为可执行文件),可以被加载到内存中, 由系统执行。

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

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

  • 优化程序性能

    • 一个 switch 语句是否总是比一系列的 if-else 语旬高效得多?
    • 一个函数调用的开销有多大?
    • while 循环比 for循环更有效吗?
    • 指针引用比数组索引更有效吗?
    • 为什么我们只是简单地重新排列一下算术表达式中的括号就能让函数运行得更快?
  • 理解链接时出现的错误
    • 链接器报告说它无法解析一个引用, 这是什么意思?
    • 静态变量和全局变量的区别是什么?
    • 如果在不同的C文件中定义了名字相同的两个全局变量会发生什么?
    • 静态库和动态库的区别是什么?
    • 在命令行上排列库的顺序有什么影响
    • 为什么有些链接 错误直到运行时才会出现?
  • 避免安全漏洞

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

hello.c 源程序已经被编译系统翻译成了可执行目标文件 hello, 并被存放在磁盘上。 要想在 Unix 系统上运行该可执行文件, 我们将它的文件名输入到称为 shell 的应用程序中:

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

1.4.1 系统的硬件组成

上图是一个典系统的硬件组织,接下来进行分别介绍

总线

贯穿整个系统的是一组电子管道, 称作总线, 它携带信息字节并负责在各个部件间传递。

通常总线被设计成传送定长的字节块, 也就是字 (word)。

I/O设备

I/O(输入/输出)设备是系统与外部世界的联系通道。

本示例中共有四个I/O设备作为用户输入的键盘和鼠标, 作为用户输出的显示器, 以及用千长期存储数据和程序的磁盘驱动器(简单地说就是磁盘)。

每个 I/O 设备都通过一个控制器或适配器与 I/O 总线相连

控制器和适配器之间的区别主要在于它们的封装方式。

  • 控制器是1/0设备本身或者系统的主印制电路板(通常称作 主板)上的芯片组。
  • 而适配器则是一块插在主板插槽上的卡。

它们的功能都是在 I/O 总线和 I/O 设备之间传递信息。

主存

主存是一个临时存储设备,在处理器执行程序时, 用来存放程序和程序处理的数据。

  • 从物理上来说, 主存是由一组动态随机存取存储器(DRAM)芯片组成的。
  • 从逻辑上来说, 存储器是一个线性的字节数组, 每个字节都有其唯一的地址(数组索引), 这些地址是从零开始的。

处理器

中央处理单元(CPU) ,简称处理器, 是解释(或执行)存储在主存中指令的引擎

从系统通电开始, 直到系统断电, 处理器一直在不断地执行程序计数器指向的指令,再更新程序计数器, 使其指向下一条指令。

程序计数器(PC)

是一个大小为一个字的存储设备(或寄存器)

在任何时刻, PC 都指向主存中的某条机器语言指令(即含有该条指令的地址)

处理器看上去是它的指令集架构的简单实现, 但是实际上现代处理器使用了非常复杂 的机制来加速程序的执行。

1.4.2 运行hello程序

初始时, shell程序执行它的指令, 等待我们输入一个命令。 当我们在键盘上输入字符串 "./hello" 后, shell 程序将字符逐一读入寄存器, 再把它存放到内存中, 如图 1-5 所示

当我们在键盘上敲回车键时, shell程序就知道我们已经结束了命令的输入。 然后 shell执行一系列指令来加载可执行的hello文件, 这些指令将hello目标文件中的代码和数据从磁盘复制到主存。 数据包括最终会被输出的字符串 “hello, world\n”

利用直接存储器存取(DMA)技术, 数据可以不通过处理器而直 接从磁盘到达主存。 这个步骤如图1-6所示。

一旦目标文件hello中的代码和数据被加载到主存, 处理器就开始执行hello程序的main程序中的机器语言指令。 这些指令将 “hello, world\" 字符串中的字节从主存复制到寄存器文件, 再从寄存器文件中复制到显示设备, 终显示在屏幕上。 这个步骤如图1-7所示。

1.5 高速缓存至关重要

针对处理器与主存之间的速度差异, 系统设计者采用了更小更快的存储设备, 称为高速缓存存储器(cache memory, 简称为cache或高速缓存), 作为暂时的集结区域, 存放处理器近期可能会需要的信息

高速缓存是用一种叫做**静态随机访问存储器(SRAM)**的硬件技术实现的

可以通过建立多级缓存的方式来缓解速度与容量之间的矛盾

系统可以获得一个很大的存储器, 同时访问速度也很快, 原因是利用了高速缓存的局部性原理, 即程序具有访问局部区域里的数据和代码的趋势。通过让高速缓存里存放可能经常访问的数据, 大部分的内存操作都能在快速的高速缓存中完成

图1-8展示了一个典型系统中的高速缓存存储器。

1.6 存储设备形成层次结构

实际上, 每个计算机系统中的存储设备都被组织成了一个存储器层次结构,如图1-9所示。在这个层次结构中,从上至下, 设备的访问速度越来越慢、容最越来越大,并且每字节的造价也越来越便宜。寄存器文件在层次结 构中位于最顶部,也就是第0级或记为L0。这里我们展示的是三层高速缓存L1到L3,占据存储器层次结构的第1层到第3层。主存在第4层,以此类推。

存储器层次结构的主要思想是上一层的存储器作为低一层存储器的高速缓存。

1. 7 操作系统管理硬件

可以把操作系统看成是应用程序和硬件之间插入的一层软件

如图1-10所示。所有应用程序对硬件的操作尝试都必须通过操作系统。

操作系统有两个基本功能:

  • 防止硬件被失控的应用程序滥用;
  • 向应用程序提供简单一致的机制来控制复杂而又通常大不相同的低级硬件设备。

操作系统通过几个基本的抽象概念(进程、虚拟内存和文件)来实现这两个功能。如图1-11所示, 文件是对I/O设备的抽象表示, 虚拟内存是对主存和磁盘 I/O 设备的抽象表示, 进程则是对处理器、 主存和 I/0 设备的抽象表示

CSAPP第一章读书笔记相关推荐

  1. 《Go语言圣经》第一章 - 读书笔记

    <Go语言圣经>第一章 - 读书笔记 第一章 Go语言入门 01 Hello World 02 命令行参数 练习 练习1.1 练习1.2: 练习1.3: 03 查找重复的行 例子运行 du ...

  2. 《自控力》 【美】凯利·麦格尼格尔 第一章读书笔记

    题记:在CSDN潜水已经快两年了,看了很多给力的博客,学到了很多收获了很多,当时就觉得写博客是件好事,即帮到了别人也成长了自己,所以也有写点博客的想法.可快两年过去了,自己的博客除了草啥都没有,一直都 ...

  3. 第三章 地势坤,君子以厚德载物 ——《箴言》第一章读书笔记之三

    梁先生在说完"入门最基本的方法就是从C语言入手"时,意犹未尽地又再次给我们描绘了神奇的"高手的境界": "事实上,到达高手的境界以后,不管什么语言不语 ...

  4. 《从Paxos到Zookeeper:分布式一致性原理与实践》第一章读书笔记

    第一章主要介绍了计算机系统从集中式向分布式系统演变过程中面临的挑战,并简要介绍了ACID.CAP和BASE等经典分布式理论,主要包含以下内容: 集中式的特点 分布式的特点 分布式环境的各种问题 ACI ...

  5. Computer Systems A Programmer's Perspective(深入理解计算机系统)第一章读书笔记

    第一章    计算机系统漫游 1.1信息就是位+上下文 源程序实际上就是一个由0和1组成的位(又称比特位)序列,这些位被组织成8个一组,称为字节.每个字节都表示程序中某个文本字符. 系统中的所有信息都 ...

  6. python基础读后感_《python基础教程 》第一章 读书笔记

    python是一个简单强大的直译语言,它同样提供交互式编译环境,学起来还算有趣,在学习的过程中,同样体会了动态语言的直接与强大. 第一章 基础知识 一 运行python 在ubuntu终端输入 pyt ...

  7. 被讨厌的勇气:第一章读书笔记

    本笔记为岸见一郎先生的著作<被讨厌的勇气>部分文字的摘抄. 引言 人可以改变.世界极其简单.人人能获得幸福. 人并不是住在客观的世界,而是住在自己营造的主观世界里.你所看到的世界不同于我所 ...

  8. 《Topology Without Tears》第一章读书笔记,笑着学拓扑(欸嘿嘿,嘿嘿,学你妈!

    淦,写狗日的论文涉及到了流形优化,流形优化有涉及到了拓扑,只能从零开始学拓扑了...这是一个非常痛苦的过程... 在网上找来找去,发现了<无泪的拓扑>大家都说好.结果我一看,好家伙,尽管这 ...

  9. Android深度探索--HAL与驱动开发----第一章读书笔记

    1.1   Android拥有非常完善的系统构架可以分为四层: 第一层:Linux内核.主要包括驱动程序以及管理内存.进程.电源等资源的程序 第二层:C/C++代码库.主要包括Linux的.so文件以 ...

最新文章

  1. 在mysql中会话变量前面的字符是什么_在MySQL中仅使用会话变量仅对字符的首次出现执行搜索/替换...
  2. Scala方法定义及调用
  3. random_normal_initializer 使用
  4. html使用element ui_Kendo UI for jQuery使用教程:自定义小部件(二)
  5. Introduce Null Object(引入Null 对象)
  6. 抛砖引玉,终于完成了自己的客户端校验提示Extender
  7. Node.js文件的同步异步事件循环
  8. AcWing 103. 电影
  9. excel中相对引用、绝对引用、混合引用
  10. prometheus如何评估告警策略以及如何推送告警消息到alertmanager?
  11. 狄利克雷原理及其应用
  12. docker容器化部署nginx前端项目
  13. 打造离线版 123D Catch
  14. 申报市级瞪羚企业应具备的基本条件
  15. 大多数linux分区的文件系统,Linux分区、文件系统
  16. Vertica:C-Store 七年之痒
  17. 数字信号处理实验matlab版答案刘舒帆,数字信号处理实验(MATLAB版) 刘舒帆,费诺,陆辉 西安电子科技大学出版社 9787560620060...
  18. 教你如何在中关村这个险恶的地方买到最便宜的称心如意的笔记本电脑
  19. Java编辑工具——IDEA图标含义大全
  20. 中国乳房X射线探测器市场趋势报告、技术动态创新及市场预测

热门文章

  1. Java代码点和代码单元及其区别
  2. 基于(plc)portal v14的三级传送带设计
  3. 晴天科技冲刺上市:实控人丁一波系本科肄业,粤民投为其股东
  4. 基于深度学习的图像识别模型发展
  5. 揭秘长尾关键词的力量:如何在搜索引擎上挤掉竞争对手?
  6. LMS原理推导及代码实现
  7. apache安装错误error: APR notfound解决办法
  8. Python初识对象
  9. iOS icon图标尺寸
  10. 详解docker镜像管理命令