程序被翻译成不同的格式:
系统的组成:总线、I/O设备、主存、处理器。
处理器:中央处理单元(cpu),简称处理器,是解释(或执行)存储在主存中指令的引擎。
处理器的核心是一个寄存器,称为程序计数器(PC),程序计数器在任何时刻都指向某条指令的地址。
处理器执行的操作并不多,它们围绕着主存、寄存器组和算术/逻辑单元进行。通常CPU在指令的要求下可能会执行这些操作:
- 加载:从主存复制一个字节或者一个字到寄存器,以覆盖寄存器原来的内容。(主存->CPU)
- 存储:从寄存器复制一个字节或者一个字到主存的某个位置,以覆盖这个位置上原来的内容。(CPU->主存)
- 操作:把两个寄存器的内容复制到ALU,ALU对这两个字做算术运算,并将结果存放到一个寄存器中,以覆盖该寄存器中原来的内容。(两个寄存器->一个寄存器)
- 跳转:从指令本身中抽取一个字,并将这个字复制到程序计数器(PC)中,以覆盖程序计数器中原来的值。(指令中的值->程序计数器)
进程的虚拟地址空间:需要了解的是,进程所看到的内存都是一致的,称为虚拟地址空间。换句话说,每个进程都认为独占地使用了真个内存。
地址空间最上面的区域(高地址区)是保留给操作系统中的代码和数据的,这对所有进程来说都是一样的。地址空间的底部区域(低地址区)存放用户进程定义的代码和数据。
进程的虚拟地址空间的分布:(从低地址到高地址)
- 程序代码和数据:这段区域是只读的。对所有的进程来说,代码是从同一固定地址开始,紧接着的是和C全局变量相对应的数据位置。
- 堆:代码和数据区后紧随着的是运行时堆。与代码和数据区不同的是,代码和数据区从一开始运行时,就被指定了大小,但调用像malloc和free这样的标准库和数学库这样的C标准库函数时,堆可以在运行时动态地扩展和收缩。
- 共享库:用来存放像C标准库和数学库这样的共享库的代码和数据的区域。
- 栈:位于用户虚拟地址空间顶部的是用户栈,编译器用它来实现函数的调用。和堆一样,用户栈在程序的执行期间可以动态地扩展和收缩。每次我们调用一个函数时,栈就会增长;从一个函数返回时,栈就会收缩。
- 内核虚拟内存:地址空间顶部的区域是为内核保留的。不允许应用程序读写这个区域的内容或者直接调用内核代码定义的函数。相反,它们都必须调用内核来执行这些操作。