源文件:0, 1 组成每行以一个看不见的’\n’结尾,
执行一个源文件分四个阶段:预处理, 编译,汇编,连接
.i 文件:.c文件预处理后生成
.ii文件: .cpp文件预处理后生成
- 预处理阶段:预处理器(cpp)根据以#开头的命令修改源程序,(如把一些头文件的内容,直接插入到程序文本中)
- 编译阶段。编译器(ccl)将.i 文本翻译成 .s 文本,他包含了一个汇编程序,汇编语言程序中没仪表语句都以一种标准的额问题本格式确切的描述了一条低级机器语言指令
- 汇编阶段。汇编器(as) 将.s 文件翻译成机器语言指令,并将其打包成可重定位目标程序的格式。并将结构保存在.o 文件中,.o文件是一个二进制文件,他的编码是机器语言指令而不是字符,所以当我们用文打开.o文件是看到的是一堆乱码。
-链接阶段。比如在刚刚的程序中调用了printf函数,他是每一个c编译器都会提供的标准C库的一个程序,它存在一个名为printf.o的单独预编译好的目标文件中,而这个文件必须以某种方式合并到hello.o程序中,连接器就是负责处理这种合并的,并生成可执行文件
要想在unix上执行可执行文件,我们需要将他的文件名输入到shell的应用程序中
shell是一个命令行解释器,它输出一个提示符,等待命令输入,然后执行命令,如果输入的不是一个内置的shell命令,那么shell就会假设这是一个可执行文件,并对其进行加载运行
系统的硬件组成
- 主存:一个临时存储设备,在处理器执行程序时,用来存放和程序处理的数据,从物理上来说,主存是一组由动态随机存储器(DRAM)组成的,从六级上来说,存储器是一个线性的字节数组,每一个字节都一个唯一的地址,
- 处理器:*处理单元,除利息的核心是一个字常德存储设备,称为程序计数器,在任何时刻,PC都指向主存的某条机器语言指令。指令按照严格的顺序执行。
- 指令集结构:描述没每条机器代码指令的效果
-
微体系结构:描述处理器实际上的具体实现
进程 :操作系统对一个正在运行的程序的一种抽象,操作系统保持跟组进程运行所需的所有状态信息,当操作系统决定要把控制权从当前进程抓移到某个新进程时,就会进行上下文切换(保存当前进程的上下文,恢复新进程的上下文,然后将控制权传递到新进程)
线程:一个进程实际上可以由多个称为线程的执行单元组成,每个线程都运行在进程上下文中,并共享同样的代码和全局数据,
虚拟存储器:一个抽象概念,它为每个进程提供了一个假象,即每个进程都在独立地使用主存。Linux中,地址空间最上面的区域是为操作系统中的代码和数据保留的,这对素有进程来说是一样的,地址空间的地步存放用户进程定义的数据和代码
- 程序代码和数据。对所有的进程来数,代码是从同一固定地址开始的,紧接着是C全局变量,代码和数据区是直接按照可执行文件加载的,如上图的hello片段。
- 堆:代码和数据区后是运行时堆,代码和数据区是进程在一开始运行时就被规定了大小,但是堆可以在调用malloc和free等函数式动态的扩展和收缩
- 共享库:大约在地址空间的中间部分是用来存放C标准库等这样共享库的代码和数据的区域。
- 栈:位于用户虚拟地址空间的顶部,编译器用它来实现函数调用,和堆一样,在程序执行期间可以动态地扩展和收缩。(调用函数会使得栈增加,从函数返回时,栈收缩)
- 内核虚拟存储器:内核总是驻留在内存中,是操作系统的一部分,不允许程序续写,或直接调用内核代码定义的函数。
文件:字节序列。I/O设备,磁盘,键盘,显示器都可视为文件。
并行和并发
- 并发:值一个同事具有多个活动的系统
-
并行:是用并发使一个系统运行得更快
线程级并发:
- 超线程:有时称为同时多线程,是一项允许一个CPU执行多个控制流的技术。
指令级并发:在较低的抽象层次上,现代处理器可以同事执行多条指令
单指令,多数据并行:允许一条指令产生多个可以并行执行的操作,这种方式称为单指令,多数据,