1-0GET实践技巧
如何避免由计算机表示数字的方式引起的奇怪的数字错误
通过一些小技巧来优化自己的C代码,以充分利用现代处理器和存储器系统的设计
了解编译器是如何实现过程调用的,以及如何利用这些知识来避免缓冲区溢出错误带来的安全漏洞
学会如何识别和避免链接时那些令人讨厌的错误
编写自己的Unix shell、自己的动态存储分配包,甚至自己的Web服务器
认识并发带来的希望和陷阱
1-1信息就是位+上下文
源进程:由进程员通过编辑器创建并保存的文本文档,实际上是一个由0和1组成的位序列
位:又称比特,是一个“0”或一个“1”占据的空间
字节:8个位被组织成一组称为字节,表示进程中的某些文本字符
大部分的现代计算机系统都使用ASCII标准来表示文本字符,然后以唯一的单字节大小的数字来表示每个字符。 [非英文字符有其他的编码方式(Unicode)表示]
系统中所有的信息都是由一串比特表示的。
区分不同数据对象的唯一方法是我们读到这些数据对象时的上下文
C语言
- C语言与Unix操作系统关系密切
- C语言小而简单
- C语言是为实践目的设计的
1-2进程被其他进程翻译成不同的格式
进程的生命周期是从高级语言进程[能被读懂的形式]开始的,对机器而言则需要将高级语言进程转化为一系列的低级机器语言命令。然后按照可执行目标进程的格式打包命令,并以二进制磁盘文档的形式存放起来。
源文档到目标文档的转换
- 命令:gcc -o hello hello.c
执行过程
- 预处理阶段:源进程 通过cpp(预处理器) 处理以字符“#”开头的命令,比如处理#include<stdio.h>时cpp则会加载头文档stdio.h的内容,修改原始的C进程得到”.i”文档
- 编译阶段:编译器(ccl)将文本文档hello.i翻译成汇编文本hello.s
- 汇编阶段:汇编器(as)将hello.s翻译成机器语言命令,并打包成“可重定位目标进程”hello.o[它是一个二进制文档]
- 链接阶段:在hello进程中调用了printf函数,而printf函数单独存在于一个名为printf.o的文档中,而这个文档必须以某种方式合并到hello.o中。链接器(ld)就负责处理合并,结果产生可执行文档hello,它可以被加载到内存中,由系统执行
1-3了解编译系统是如何工作的大有益处
优化进程性能
理解链接时的错误
避免安全漏洞
1-4处理器读并解释存储在内存中的命令
1. 系统的硬件组成
- 总线:一组贯穿整个系统的电子管道,用于传送字节块(字)。在32位系统中一个字为4个字节,64位系统中一个字为8个字节。
- I/O设备:是系统与外部系统的联系通道
- 主存:是一个临时的存储设备,在处理器执行进程的时,用来存放进程和进程处理的数据
- 处理器:中央处理单元(CPU),是解释或执行存储在主存中命令的引擎。处理器的核心是一个大小为一个字的寄存器,称为进程计数器(PC)。在任何时候,PC都指向主存中的某条机器语言命令。
2. 运行hello进程
- 在键盘上输入 ./hello , shell进程字符逐一读到寄存器,然后再复制到主存
- 当我们按下回车键,shell进程知道我们以及结束了命令的输入,然后加载可执行的hello进程
- 加载完毕后,处理器就会从main函数开始执行
1-5高速缓存至关重要
大专栏 计算机系统漫游9%97%B4" class="headerlink" title="缓存是为了减少信息复制来节省时间">缓存是为了减少信息复制来节省时间
较大的存储设备通常比较小的存储设备运行得慢,但是同类型的高速设备造价远高于同类型的低速设备
随着半导体技术的发展,加快处理器的运行速度比加快主存的运行速度要容易和便宜得多
系统设计时为了减小主存和处理器之间的差距,选用更小更快的存储设备(高速缓存器)作为暂时的集结区域,用于存储最近可能会用的的信息。
L1高速缓存接近寄存器的访问速度
1-6存储设备形成层次结构
寄存器:CPU在这里保存从高速缓存加载的字
L1高速缓存
L2高速缓存
L3高速缓存
主存
本地磁盘
远程磁盘
1-7操作系统管理硬件
操作系统的两个基本功能
- 防止硬件被失控导致应用进程滥用
- 向应用进程提供简单一致的机制来控制复杂而又通常大不相同的低级硬件设备
操作系统通过几个抽象的概念来实现这两个功能
- 进程是操作系统对一个正在运行的进程的一种抽象。在一个系统上可以同时运行多个进程,而每个进程都好像在独立地使用硬件。
- 并发运行:指一个进程的命令和另一个进程的命令是交错运行的。操作系统实现这种交错执行的机制称为上下文切换。
- 上下文:操作系统保持跟踪进程运行时所需的所有状态信息。
- 线程:是进程的执行单元,一个进程可以由多个线程组成,每个线程都运行在进程的上下文中,并共享同样的代码和全局数据。多线程比多进程之间更容易共享数据。
虚拟内存:为每个进程提供一个假象,即每个进程都在独占地使用主存。每个进程看到的内存都是一致的,称为虚拟地址空间。每个进程看见的虚拟地址空间是由大量准确定义的区构成,每个区都有专门的功能。
- 进程代码和数据:对于所有进程来说,代码是从统一固定地址开始,紧接着的是和全局变量相对应的数据位置。代码和数据区是直接按照可执行目标文档的内容初始化的。
- 堆:可以在运行时动态地扩展和收缩。
- 共享库:用来存放像C标准库和数学库这样地共享库地代码和数据地区域。
- 栈:用户栈,编译器用它来实现函数调用。和堆一样,用户栈在进程执行期间可以动态地扩展和收缩。特别地,每次调用一个函数时,栈就会增长;从一个函数返回是,栈就会伸缩。
- 内核虚拟内存:不允许应用进程读写这个区域的内容或者直接调用内核代码定义的函数。必须调用内核来执行这些操作。
文档就是字节序列
1-8系统之间利用网络通信
1-9 重要主题
给驱动数字计算机进步提供持续动力的两个需求
- 想要计算机做得更多
- 想要计算机运行得更快
并发和并行
- 并发:指一个同时具有多个活动的系统
- 并行:指的是用并发来使一个系统运行得更快
线程级并发
- 使用一台计算机在它正在执行得进程间快速切换实现得
命令级并行
- 现代处理器可以同时执行多条命令的属性称为命令级并行
单命令、多数据并行
- 许多现代处理器拥有特殊的硬件,允许一条命令产生多个可以并行执行的操作。