1. 信息就是位+上下文
- 一些概念:
源程序(源文件)
位(比特)
字节
上下文
文本文件:只由ASCII字符构成的文件,所有其他文件都称为二进制文件
二进制文件
- 基本思想:系统中所有的信息都是由一串比特表示的,区分不同数据对象的唯一方法是我们读到这些数据对象时的上下文。比如,在不同上下文中,一个同样的字节序列可能表示一个整数、浮点数、字符串、或者机器指令。
2. 程序被其他程序翻译成不同格式
- 一些概念
编译器驱动程序
翻译
预处理器、源程序、C程序
编译器、汇编语言程序
汇编器、机器语言指令、可重定向目标程序
链接器、可执行目标程序(可执行目标文件)
编译系统
- 在Unix系统上,从源文件到目标文件的转化是由编译器驱动程序完成的,翻译的过程可分为四个阶段完成。执行这个四个阶段的程序(预处理器、编译器、汇编器、链接器)一起构成了编译系统。
- 预处理阶段
预处理器(cpp)根据以字符#开头的命令,修改原始的C程序。预处理器读取系统头文件内容并把它直接插入程序文本中,得到另一个C程序,通常是以.i作为文件扩展名。(hello.c-->hello.i)
- 编译阶段
编译器(cll)将文本文件hello.i翻译成hello.s,它包含一个汇编语言程序。(hello.i-->hello.s)
- 汇编阶段
汇编器(as)将hello.s翻译成机器语言指令,把这些指令打包成可重定向目标程序(relocatable object program),并将结果保存在目标文件hello.o中。hello.o文件是一个二进制文件,包含的是指令编码。
- 链接阶段
链接器(ld)负责合并,结果得到一个hello文件,它是一个可执行目标文件(简称为可执行文件),可以被加载到内存中,由系统执行。
何为合并:hello程序调用了printf函数,它是每个C编译器都提供的标准C库的一个函数。printf函数存在于一个名为printf.o的单独的预编译好了的目标文件中,而这个文件必须以某种方式合并到我们的hello.o程序中。
3. 处理器读并解释存储在内存中的指令
- 一些概念
总线、字、字长
I/O设备、磁盘
主存、动态随机存取存储器、地址
处理器、程序计数器、指令集架构、寄存器文件(register file)、算数/逻辑单元(ALU)
加载、存储、操作、跳转
- 系统的硬件组成
1)总线
通常总线被设计成传送定长的字节块,也就是字(word)。字中的字节数(即字长)是一个基本的系统参数,各个系统中都不尽相同。
2)I/O设备
用户输入:键盘、鼠标
用户输出:显示器
长期存储数据和程序:磁盘驱动器(磁盘),最开始,可执行程序hello就存放在磁盘上。
3)主存
临时存储设备,在处理器执行程序时,用来存放程序和程序处理的数据。
物理上来说:由一组动态随机存取存储器(DRAM)芯片组成
逻辑上来说:存储器是一个线性的字节数组,每个字节都有其唯一的地址(数组索引),这些地址是从0开始的。
4)处理器
解释(或执行)存储在主存中指令的引擎。
存储器的核心:程序计数器(PC),一个大小为一个字的存储设备(或寄存器)。在任何时候,PC都指向主存中的某条机器语言指令(即包含该指令的地址)。
指令集架构决定指令执行模型,CPU看上去是按照这个模型操作的。在这个模型中,指令按照严格的顺序执行,而执行一条指令包含一系列步骤。指令指示的简单操作不多,它们围绕主存、寄存器文件(register file)和算数/逻辑单元(ALU)进行。
寄存器文件:一个小的存储设备,由一些单个字长的寄存器组成,每个寄存器都有唯一的名字。
ALU:计算新的数据或地址值。
一些简单操作的例子:
- 加载:从主存复制一个字或者一个字节到寄存器,以覆盖寄存器原来的内容。
- 存储:从寄存器复制一个字或者一个字节到主存的某个位置,以覆盖原来这个位置上的内容。
- 操作:把连个寄存器的内容复制到ALU,ALU对这两个字做算数运算,并将结果存放到一个寄存器,以覆盖该寄存器中原来的内容。
- 跳转:从指令本身中抽取一个字,并将这个字复制到程序计数器(PC)中,以覆盖PC中原来的值。