CSAPP:第一章——计算机系统漫游

一、信息,就是位+上下文

计算机系统中的所有信息——包括磁盘文件、内存中的程序、内存中存放的用户数据以及网络上传送的数据,都是由一串比特序列(也可以说是字节序列,一个字节八个位,即八比特)表示的。区分不同数据对象的唯一方法是我们读到这些数据对象时的上下文。比如,在不同的上下文中,一个同样的字节序列可能表示一个整数、浮点数、字符串或者机器指令。

// 文件名:hello.c
#include <stdio.h>

int main() {
    
    
	printf("hello,world!\n");
	return 0;
}

上面源程序hello.c,以文本文件的形式被我们所看到,但是计算机中无法存放字符,只能存放0和1,而0和1只表示数字,所以大佬们就制定了一种全世界统一的标准,比如ASCII编码(或者其他编码),用一个数字代表、且只能代表一个字符。所以文本文件实际上在磁盘和内存中是以二进制的形式存放的,根据ASCII编码标准,每个字符都有特定且唯一的数值来表示。hello.c对应ASCII编码如下:
在这里插入图片描述
i字符对应的十进制数值是105,则在计算机中,i字符是以105的二进制数1101001存放的。根据区分计算机中不同数据对象的唯一方法——读到这些数据对象时的上下文可明白,当计算机中的比特序列1101001表示字符时,它就是字符i,当1101001表示无符号整数时,他就是105

二、程序被编译成不同的格式

hello.c程序的生命周期是从一个高级C语言程序开始的,因为这种形式能够被人读懂。然而为了在系统上运行hello.c程序,每条C语句都必须被其他程序转化为一系列的低级机器语言指令。然后这些指令按照一种称为可执行目标程序的格式打包好,并以二进制磁盘文件的形式存放起来。目标程序也称为可执行目标文件。
在这里插入图片描述
上面编译系统的整个过程,在编译器结构中详细介绍过。

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

1.系统硬件的组成

总线:贯穿整个系统的一组电子管道,称做总线,他携带信息字节并负责在各个部件间传递。总线被设计成传送定长的字节块,即字(word),字的字长由机器的位数决定,4字节(32位)还是8字节(64位)。

I/O设备:键盘,鼠标,显示器,磁盘等。

  • 每个I/O设备通过一个控制器或适配器与I/O总线相连。控制器和适配器的区别在于他们的封装方式:控制器是置于I/O设备本身的或者系统的主板上的芯片组;适配器则是一块插在主板插槽上的卡。
  • 两者功能都是在I/O总线和I/O设备之间传递信息。

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

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

处理器:解释(或执行)存储在主存中指令的引擎。处理器的核心是一个字长的存储设备或寄存器,称为程序计数器(PC,就是CS:IP)。在任何时刻,程序计数器都指向主存中的某条机器语言指令(也就是PC中存放着该条指令的地址)。
从通电到断电,处理器一直在不断地从PC指向的内存中读取指令,解释指令中的位,执行该指令提示的简单操作(加载、存储、ALU运算、跳转),然后更新PC,使其指向下一条指令,而这条指令并不一定和在内存中刚执行完的指令相邻。

在这里插入图片描述

2.运行hello程序

直接存储器存取(DMA)技术:数据可以不通过处理器而直接从磁盘到达主存。
在这里插入图片描述
在这里插入图片描述

四、高速缓存

hello程序的机器指令最初放在磁盘上,程序加载时,被复制到主存,处理器运行程序时,指令又从主存复制到处理器。

程序运行时,系统需花费大量的时间把信息从一个地方挪到另一个地方,但是主存和处理器之间的读取速率相差太大,主存拖后腿,增加额外的时间开销。所以系统设计者为了尽可能快的完成这一操作,搞了高速缓存这么个玩意,作为暂时的集结区域,用来存放处理器近期可能用到的信息。
在这里插入图片描述

五、存储设备层次结构

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

  • L1高速缓存的容量可以达到数万字节,访问速度几乎和访问寄存器一样快。
  • L2高速缓存的容量十万到数百万字节,通过一条特殊的总线连接到处理器。比L1长5倍。但还是比访问主存快5~10倍。
  • L1 和 L2高速缓存是用一种叫做静态随机访问存储器(SRAM)的硬件技术实现。
    在这里插入图片描述

六、操作系统管理硬件

操作系统是介于应用程序和硬件之间的一个软件,它有两个基本功能:

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

在这里插入图片描述
操作系统通过几个基本的抽象概念(进程, 虚拟内存, 文件 )来实现这两个功能。注意这只是抽象出来的概念,并非真实存在的设备,文件是对IO设备的抽象,虚拟内存是对主存和文件的抽象,进程是对处理器、内存和文件的抽象。
在这里插入图片描述

1.进程

进程是操作系统对一个正在运行的程序的一种抽象。进程数都是多于可以运行他们的CPU个数的。传统系统在一个时刻只能执行一个程序,而先进的多核处理器能够执行多个程序,无论实在单核还是多核系统,一个CPU看上去都像是在并发地执行多个进程。这是通过处理器在进程间切换来实现的,操作系统实现这种交错执行的机制称为上下文切换

上下文:即是进程运行所需的所有状态信息,比如PC和寄存器文件的当前值,以及主存内容。

上下文切换:即保存当前进程的上下文,恢复将要运行的新进程的上下文,然后将控制权传递给新进程,新进程就会在上一次停止的地方开始。

在这里插入图片描述

2.线程

一个进程实际可以由多个称为线程的执行单元组成,每个线程都运行在进程的上下文中,并共享同样的代码和全局数据。多线程比多进程更容易共享数据,有多处理器的时候,多线程也是一种使程序更快运行的方法。

3.虚拟内存

虚拟存储器是一个抽象的概念,它为每个进程提供了一个假象,即每个进程独占地使用所有主存。每个进程看到的内存都是一致的,称为虚拟地址空间。

地址空间最上面的区域为操作系统的代码和数据保留的,这对所有进程都是一样的。地址空间的底部区域存放用户进程定义的代码和数据。

在这里插入图片描述
每个进程的虚拟地址空间由大量准确定义的区构成,每个区都有专门的功能。从最低地址开始,逐步向上介绍:

  • 程序代码和数据:对于所有进程来说,代码从一固定地址开始,紧接和C全局变量相对应的数据位置。代码和数据区是直接按照可执行目标文件的内容初始化的。

  • :代码和数据区紧随着运行时堆。代码和数据区是在进程一开始就被规定了大小,与此不同,调用malloc和free时堆动态的扩展和收缩。

  • 共享库:地址空间的中间部分存放C标准库和数学库这样共享库代码和数据的区域。共享库概念非常强大,相当难懂。

  • : 用户虚拟地址顶部的是用户栈,编译器用它来实现函数调用。和堆一样,在执行时动态的扩展和收缩。

  • 内核虚拟存储器: 内核总是驻留在内存中,是操作系统一部分。

4.文件

文件 就是 字节序列,仅此而已。所有I/O设备 都可视为文件,包括磁盘、键盘、显示器、甚至是网络。系统中的所有输入输出都是通过使用Unix I/O 的系统函数调用读写文件来实现。

七、系统之间利用网络通信

从一个单独的系统来看,网络可视为一个I/O设备。如系统从主存中赋值一串字节经过网络适配器,再到另一台机器。
在这里插入图片描述

我们平时用XShell操作服务器时,程序运行的基本步骤与下面一样。

在这里插入图片描述

八、并发和并行

并发:是一个通用概念,指一个同时具有多个活动的系统。
并行:指的是用并发使一个系统运行的更快。并行可以在计算机多个抽象层次运用。

多处理系统县城及并发:独立的L1,L2高速缓存,寄存器;共享更高层次的高速缓存。
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_42570601/article/details/111876732