我们已经知道了如何用机器来表示信息,现在我们希望用机器来处理信息。信息的处理可以看作一个程序(一个函数)。人类的自然语言,或是一些人类设计的形式语言,可以“表示”一个程序(“表示”的意思是语言指向了一个逻辑形式下的程序)。计算机的基本工作,就是要自动“执行”高级语言程序。“执行”就是指通过一套精心设计的系统,自动把高级语言还原为信息的储存和搬运,并在最简单的逻辑门下做运算。出于效率的考虑,这个还原的过程并不是一步到位的,而是会经历多个层级。最底层是机器指令,这些指令是人们为特定机器设定的特定协议,它包含最基础的信息储存、搬运、计算操作。为了让机器指令变得更加人类可读,人类设计了汇编语言来表示机器指令。比汇编语言更高层级地有C,Python等等。因此,此刻我们关心以下问题:(1) 这个处理信息的机器是什么样的?它有什么样的结构,有哪些组成部件,具有什么样的功能?(2) 最底层的机器指令有哪些?它们和高级语言(以C为例)有什么联系?
我们接下来讨论的这个系统称为x86-84,它是最主流的计算机系统,由INTEL公司开发。首先让我们关注这个系统里最重要的两个部件,一个称为中央处理单元(Central Processing Unit, CPU),一个称为内存(Memory)。让我们把内存暂时看作一个巨大的数组,数组的每一个栏位存储着一个字节的信息,数组的下标就称为地址(address)。CPU由五个部分组成,分别是寄存器、算数逻辑单元(Arithmetic Logical Unit, ALU)、控制单元(Control Unit)、高速缓存(Cache)、总线接口(Bus Interface)。寄存器用来临时存储正在被处理的一些数据,ALU负责完成最基本的计算,控制单元负责从内存中读取当前指令,高速缓存和总线接口之后再说。
首先让我们列出x86-64中的16个整数寄存器的名字:(每个寄存器都是64位的,32,16,8分别对应着较低位的部分,其命名是INTEL开发的历史遗留下来的)
寄存器
整数寄存器
| 64/32/16/8 | Caller/Callee saved | 常用功能 | 备注 |
|---|
| rax/eax/ax/al | 调用者保存 | 函数返回值 | |
| rbx/ebx/bx/bl | 被调用者保存 | | |
| rcx/ecx/cx/cl | 调用者保存 | 第4个参数 | |
| rdx/edx/dx/dl | 调用者保存 | 第3个参数 | |
| rsi/esi/si/sil | 调用者保存 | 第2个参数 | |
| rdi/edi/di/dil | 调用者保存 | 第1个参数 | |
| rbp/ebp/bp/bpl | 被调用者保存 | | |
| rsp/esp/sp/spl | / | 栈指针 | |
| r8/r8d/r8w/r8b | 调用者保存 | 第5个参数 | |
| r9/r9d/r9w/r9b | 调用者保存 | 第6个参数 | |
| r10/r10d/r10w/r10b | 调用者保存 | | |
| r11/r11d/r11w/r11b | 调用者保存 | | |
| r12/r12d/r12w/r12b | 被调用者保存 | | |
| r13/r13d/r13w/r13b | 被调用者保存 | | |
| r14/r14d/r14w/r14b | 被调用者保存 | | |
| r15/r15d/r15w/r15b | 被调用者保存 | | |
条件码寄存器
| 名称 | 常用功能 | 备注 |
|---|
| zf | zero flag | 上一指令结果是否为0 |
| sf | sign flag | 上一指令结果是否为负数 |
| cf | carry flag | 上一无符号运算是否有进位 |
| of | overflow flag | 上一有符号运算是否溢出 |
指令
比较和测试
| 指令 | 基于 | 备注 |
|---|
cmp s1 s2 | s1 - s2 | 根据两数的差设置条件码 |
test s1 s2 | s1 & s2 | 根据两数的与设置条件码 |
跳转指令
| 指令 | 跳转条件 | 备注 |
|---|
jmp Label | 无 | 跳转到Label |
je Label | ZF | 相等就跳转 |
jne Label | ~ZF | 不相等就跳转 |
jg Label | ~(SF^OF) & ~ZF | (有符号)大于就跳转 |
jge Label | ~(SF^OF) | (有符号)大于等于就跳转 |
jl Label | (SF^OF) | (有符号)小于就跳转(less) |
jle Label | `(SF^OF) | ZF` |
ja Label | ~CF & ~ZF | (无符号)大于就跳转(above) |
jae Label | ~CF | (无符号)大于等于就跳转 |
jb Label | CF | (无符号)小于就跳转(below) |
jbe Label | `CF | ZF` |