《深入理解计算机系统》笔记——计算机系统漫游

1.计算机系统

由硬件与软件组成,他们共同工作来运行程序。

2.信息的表示

#include <stdio.h>
 
int main()
{
 printf("Hello World\n");
 return 0;    //c标准规定建议main函数返回值为int
} 

编写程序时将上面的 Hello World 程序保存在一个 hello.c 的文件中,他将以字序列方式存储在文件中。

:由若干个字节构成,字的位数叫做字长,不同档次的机器有不同的字长。例如一台8位机,它的1个字就等于1个字节,字长为8位。如果是一台16位机,那么,它的1个字就由2个字节构成,字长为16位。在32位操作系统当中,一个字是4个字节,字是计算机进行数据处理和运算的单位。

字节:8个二进制位构成1个"字节(Byte)",它是存储空间的基本计量单位。1个字节可以储存1个英文字母或者半个汉字,换句话说,1个汉字占据2个字节的存储空间。

:"位(bit)"是电子计算机中最小的数据单位。每一位的状态只能是0或1。

我们将hello.c文件变为用ASCII码表示:
在这里插入图片描述
例如:0x23对应表示的是‘#’字符
hello.c文件等这类由ADSCII码组成的文件称为“文本文件”,其他称之为“二进制文件”。

2.1系统中所有的信息都是由位+上下文构成

包括磁盘文件、存储器中的程序,存储器中存放的用户数据以及网络上传送的数据都是由一串位来表示。而区分不同数据对象的唯一方法就是他们对应的上下文,在不同的上下文中,一个同样的字节序列可能表示不同的内容。

3.程序的编译

我们将要将 hello.c 变成一个可执行的目标程序,他就必须要经过 预处理器cpp、编译器ccl、汇编器as、链接器ld 的处理。

1.预处理阶段:预处理器 cpp 根据以字符 # 开头的命令,修改原始的 C 程序、得到新的hello.i

2.编译阶段:编译器 ccl 将文本文件 hello.i 翻译成文本文件 hello.s,它包含一个汇编语言程序,汇编语言程序中的每条语句都以一种标准的文本格式确切的描述一条低级机器语言指令。汇编语言能为不同高级语言的不同编译器提供通用的输出语言。

3.汇编阶段:汇编器 as 将hello.s 翻译成机器语言指令,把这些指令打包成一种叫做可重定位目标程序的格式,并将结果保存在目标文件 hello.o 中,hello.o 文件是一个二进制文件,它的字节编码是机器预言指令而不是字符。如果我们用文本编辑器打开 hello.o 文件,将会是一堆乱码。

4.链接阶段:在 hello.c 程序中,程序调用了 printf 函数,printf 函数存在于一个名为 printf.o 的单独的预编译好了的目标文件中,而这个文件必须以某种方式合并到我们的 hello.o 程序中。链接器 ld 就是负责处理这种合并,结果就得到一个 hello 文件,它是一个可执行的目标程序。

过程:hello.c->hello.i->hello.s->hello

4.程序的运行

hello.c经过上面的过程编译已经变为了hello程序放在了磁盘上。
图为书中程序运行的过程
在这里插入图片描述
在这里插入图片描述
图内出现名称解析:

1.总线:贯穿整个系统的一组电子管道,通常被设计成用来传送定长的字节块,也就是字。字的大小与系统相关,比如在32位操作系统当中,一个字是4个字节。

2. I/O设备:输入/输出(I/O)设备是系统与外部世界联系通道,图有4个I/O设备(鼠标 键盘 显示器 磁盘)。每一个I/O设备都通过一个控制器或者适配器与I/O总线相连。控制器是置于I/O设备本身的或者系统的主印刷电路板(通常称为主板)上的芯片组,而适配器则是一块插在主板插槽上的卡。无论如何,它们的功能都是在 I/O 总线和 I/O 设备之间传递信息。

3.主存:它是计算机中的一个临时存储设备,在处理器执行程序的时候,用来存放程序和程序处理的数据。物理上来说,主存是由一组动态随机存取存储器(DRAM)组成的,逻辑上来说,它是一个线性的字节数组,每一个字节都有唯一的地址(即数组索引)。

4. 处理器:全称中央处理器(CPU),是解释(或执行)存储在主存中指令的引擎。处理器的核心是一个字长的存储设备(或寄存器),简称程序计数器(PC),在任何时刻,它都会指向主存中的某条机器指令(即含有该条指令的地址)。从系统通电到断点,处理器一直在不断的执行程序计数器所指向指令,再更新程序计数器,使其指向下一条指令。处理器所做的操作是围绕主存、寄存器文件以及算术/逻辑单元(ALU)进行的,寄存器文件是一个小的存储设备,由一些1字长的寄存器组成,每个寄存器都有唯一的名字。ALU则计算新的数据和地址值。

5.存储设备

5.1 从磁盘加载可执行文件到主存

在这里插入图片描述

5.2 将输出字符串从内存写到显示器

在这里插入图片描述

5.3 高速缓存存储器

数据的传输就是数据的复制过程。从写入到存储在寄存器文件花费很多时间来执行。
那么如何减少这种由数据复制所引起的开销呢?
机械原理,较大的存储设备比较小的存储设备运行的慢,我们通常会在高速缓存存储器(简称高速缓存),作为暂时的集结区域,用来存放处理器近期可能会需要的信息
在这里插入图片描述

5.4 存储设备的金字塔结构

在这里插入图片描述
每一层高速缓存都为下一级的高速缓存(如 L1为L2的高速缓存)。

6.操作系统

我们可以把操作系统看成应用程序和硬件之间插入的一层软件,如图:
在这里插入图片描述

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

①、防止硬件被失控的应用程序滥用。

②、向应用程序提供简单一致的机制来控制复杂而又大相径庭的低级硬件设备。

7.进程

当我们执行hello程序时,操作系统给我们提供一种假象,就好像系统只有这个程序在运行,而这种假象是通过进程的概念来实现的。
实际上,他们是并发的在运行,即一个进程的指令和另一个进程的指令是交错运行的。
在这里插入图片描述
在单CPU系统中,系统在一个时刻只能运行一个进程,多CPU系统中,系统则是能够同时处理多个进程。但无论是单核还是多核,一个CPU只能并发的执行多个进程,这是通过处理器在进程间切换来实现的。而操作系统实现这种交错机制称为上下文切换
在这里插入图片描述

进程A与进程B在并发进行,进程通过上下文来回切换。

8.虚拟存储器

虚拟存储器是一个抽象概念,它为每个进程提供了假象,即每个进程都在独占的使用主存。
 每个进程看到的是一致的存储器,称为虚拟地址空间。在这里插入图片描述
 图中出现的名词解析:

程序代码和数据:对于所有进程来说,代码是从同一固定地址开始的,分别为0x08048000(32位)以及0x00400000(64位),紧接着是全局变量相对应的数据位置。

:代码和数据区后紧随的是运行时堆。代码和数据区是在进程一开始运行时就规定了大小,而当调用malloc和free这样的 C 标准库函数 时,堆可以在运行时动态的扩展和收缩。

共享库:存放像C标准库和数据库这样的代码和数据的区域。

:位于用户虚拟地址空间顶部,编译器用它来实现函数调用,用户栈在程序执行期间可以动态的扩展和收缩。当我们调用一个函数时,栈会增长;从一个函数返回时,栈会收缩。

内核虚拟存储器:内核总是驻留在内存中,是操作系统的一部分,不允许应用程序读写这个区域的内容或者直接调用内核代码定义的函数。

9.计算机系统中抽象的重要性

抽象的使用是计算机科学中最重要的概念之一。例如,为一组函数规定一个简单的应用程序接口API就是一个很好的编程习惯。程序员无需了解它内部的工作原理便可以使用这些代码。这在Java当中的典型比如类的定义,C语言中的函数原型。
  在这里插入图片描述

10.结束

那么深入理解计算机系统第一章计算机系统的漫游将到此结束,之后的每一部分每一章会对之间内容详细讲解。

猜你喜欢

转载自blog.csdn.net/qq_43265890/article/details/83040596