# 机器指令要素,表示及类型
# 机器指令要素
- 机器指令:CPU 能直接识别并执行的指令
- 二进制编码
- 为了方便,通常用汇编编码表示
- 指令集(ISA):CPU 可以执行的所有机器指令的集合
- 指令集决定 CPU 所能完成的各项功能
- 指令集的格式和功能直接影响机器的硬件结构及机器的适用范围
- 操作码 (Operation code)
- 指定指令所要完成的操作
- 源操作数引用 (Source Operand reference)
- 指定指令操作所需输入的位置
- 涉及一个或多个源操作数
- 结果操作数引用 (Result Operand reference)
- 指定指令操作可能产生结果的位置
- 下一指令引用 (Next lnstruction Reference)
- 指示 CPU 指令执行完本条指令后到哪儿去取下一条指令
| PC | 转移指令 |
- 指示 CPU 指令执行完本条指令后到哪儿去取下一条指令
- 源和结果操作数可能位于如下位置
- 缓存、主存或虚存寄存器
- 若只有一个寄存器,对它的引用可以使隐式的若不止一个寄存器,则每个寄存器要指定一个唯一的名字或编号,指令必须提供所需寄存器的编号
- 立即数
- IO 设备:所涉及 IO 模块和设备的地址
# 机器指令表示
- 在计算及内部,指令由一个二进制位串来表示
- 该位串会划分为不同的字段,对应于指令的各个要素
- 由于程序员很难与二进制表示的机器指令打交道,因此普遍使用机器指令的符号表示法(助记符) e.g. ADD,SUB,MPY,DIV, etc
- 操作数也可用助记符表示:ADD A,B
- 这些助记符会唯一对应一组事先定义好的 01 编码样式,通过编译器就可以把这些助记符翻译为机器码
- 数据处理 — 算术和逻辑指令
- 数据存储 — 存储器指令
- 数据传送 —I/O 指令
- 指令流控制 — 测试和转移指令
- 任何数据处理任务都可以通过上述指令进行表达
- 任何用高级语言编写的程序需要转换成上述机器指令才能执行
- 高级语言使用变量,并以简明的代数形式来表达操作
- 机器语言是以涉及数据移入移出寄存器的基本形式来表达操作
# 机器指令地址数目
- 指令分为两部分:操作码和地址码
- 地址码用来指出该指令的源操作数地址、结果操作数地址以及下一指令地址
- 地址可以是存储器地址、寄存器地址以及 I/O 设备地址
- 指令依据地址码所给出地址的个数可分为
- 四地址指令、三地址指令、二地址指令以及零地址指令
- 以主存地址为例,分析指令的地址码字段
# 四地址指令
8 | 6 | 6 | 6 | 6 |
---|---|---|---|---|
OP | A1 | A2 | A3 | A4 |
A1 操作数和 A2 操作数执行 OP 操作,结果存入 A3,A4 存的是下一条指令的地址
- 简单直观,后续指令地址可以任意填写
- 基本没有实施 (地址空间太小)
[32 位指令,设第一个字节是操作码].{red}
第一个为操作码,剩下的空间四个平分 - 4 次访存 (A1~A4)
- 地址空间 2^6=64
# 三地址指令
8 | 8 | 8 | 8 |
---|---|---|---|
OP | A1 | A2 | A3 |
- 下一条指令地址通常是隐含的
- 不普遍
- 4 次访存
- 地址空间 2^8=256
# 二地址指令
8 | 12 | 12 |
---|---|---|
OP | A1 | A2 |
(A1)OP(A2)→A1 or (A1)OP(A2)→A2 or (A1)OP(A2)→(X)
- 前两种方式中一个地址既用于源操作数又用于结果操作数
- 第三种方式隐藏了结果操作数地址,一般为某个寄存器
- 可减少指令长度
- 前两种方式下需 4 次访存,第三种方式下 3 次访存
- 地址空间 2^12=4K
# 单地址指令
8 | 24 |
---|---|
OP | A1 |
(A1)OP(X)→A1 or (X)OP(A1)→(X)
- 第二个地址必须是隐含的
- 隐含的操作数地址往往是一个寄存器,通常是累加器 AC
- 在早期机器中很普遍
如:AC < 一 AC OP A - 第一种 3 次访问主存,第二种 2 次访存
- 地址空间 2^24 = 16M
# 零地址指令
- 只有操作码
- 隐含所有地址或没有地址
- 隐含的地址往往和堆栈有关 E.g RET
- 没有地址的指令往往控制 CPU 自身行为的指令 E.g NOP,HLT
# 指令地址的设计
- 地址数目多
指令功能相对也就强大,但同时指令也会更复杂为了提高速度,往往需要更多的寄存器
寄存器之间的操作更快
编写的程序总的指令条数更少 - 地址数目少
指令就会比较简单,功能相对简单
单地址指令通常只有一个通用寄存器可以利用编写的程序总的指令条数更多
总的执行时间可能会更长 - 为了平衡两方面的优点及灵活性的要求,大多数当代计算机采用了二地址和三地址指令的混合方式
# 操作数的类型
-
地址
无符号整数 -
数值
二进制整数 / 二进制浮点数 / 十进制数使用十进制可以避免转换
很多机器支持打包的十进制数 (压缩 BCD 码)
4 位二进制代码→1 个十进制数
246=0010 0100 0110 -
字符
-
逻辑数据
位或标志
布尔类型
字符串列表或字符串
某些机器还可能定义特殊数据类型或结构
# 机器指令的操作类型
数据传送
I/O
算术
系统控制
逻辑
控制转移
转换
# 数据传送
- 最基础的机器指令
- 指令中必须指明以下内容
源操作数的位置和结果操作数的位置
可能是寄存器、存储器或栈顶数据长度
寻址方式 - 数据传送指令
Move
Clear
Store
Set
Load
Push/Pop
Exchange
# 算术
- 加,减,乘,除
- 有符号整数
可能包括浮点数或压缩十进制数 - 其他可能有的指令
Increment (a++)
Negate (-a)
Decrement (a--)
Absolute
# 逻辑运算
- 按位进行操作 / 布尔运算
- 与,或,非,异或测试,比较
- 设置控制变量:
设置控制保护、中断处理、时间控制等标志 - 移位
- 循环移位
# 逻辑移位
- 常用于对无符号数进行乘 2^n 以及除 2^n 的运算
- 还可以用于对打包数据进行拆分
# 算术移位
常用于对有符号数的乘 2^n 以及除 2^n 的运算,以便提速
# 循环移位 (ROL,ROR) (X86)
常用于各种加密算法
# 转换
改变数据格式或对数据格式进行操作
- 基础转换
- 二进制到十进制
- 翻译
- 将内存中某些地址的值通过表查询进行格式转换
- ASCII→EBCDIC
# IO
- 可能是独立的指令(分离式 I/O)
- 输入 / 读 IN (51)
- 输出 / 写 OUT (51)
- 启动 IO
- 测试 IO
- 可能通过数据传送指令完成 (存储映射式 I/O)
- 可能通过 CPU 执行,也可能被分离的控制器 (DMA 或通道) 来完成
# 系统控制
特权指令:只能用于操作系统,普通用户不可使用
仅当 CPU 正处于某种特定状态或程序处于专门的特权存储区时才能执行
更新控制寄存器的内容,更新进程控制块
# 控制转移
- 分支 / 转移
- 有条件(依据条件码)
- 无条件
- 可以向前转移,也可以向后转移
- 跳步
- 包含一个隐含地址
- 隐含地址等于下一指令地址加上该地址的长度
# 过程调用
过程是一个自成一体的计算机程序,并能被一个更大的程序所调用
代码重用,任务分解
-
两类基本指令
- 调用指令:用于从当前程序位置转移至子程序的入口
- 返回指令:用于子程序执行完后重新返回到原程序的断点
属于转移指令的一种
-
可以从多个位置调用过程
-
过程内部还可以调用过程,这个调用不限于别的过程,还可以调用自己,而且允许过程嵌套到任一深度
- 过程嵌套就是指在过程调用中又发生了过程调用
- 递归
-
每一次调用必须要有对应的返回
# 返回地址
- 由于能从不同位置调用过程,所以处理器必须以某种方式保存返回地址
- 三个常用的方法
寄存器
被调用过程开始处
栈顶
前两种方法不利于重入
# 基本寻址方式
# 定义
用于确定当前指令中数据地址或确定下一条将要执行指令地址的方法
依赖 CPU 硬件,会直接影响指令格式和功能
# 两种类型
- 两种类型指令寻址
- 顺序寻址
下条指令的地址码使用程序计数器 PC 给出下条指令的地址 - 跳跃寻址
下条指令的地址不由 PC 给出,而是由本条指令给出
- 顺序寻址
- 数据寻址
# 寻址方式
立即数寻址
直接寻址
间接寻址
寄存器寻址
寄存器间接
寻址隐含寻址
偏移寻址
堆栈寻址
# 寻址方式的说明
每个计算机都提供不止一种寻址方式
- 一般是采用指令操作码与其寻址方式 —— 对应的方式来确定寻址方式
- 还有使用指令格式中的一段作为地址方式说明字段但这种情况 (较为少见)
# 有效地址 EA
指操作数的真实地址
- 在没有虚拟存储器的系统中,有效地址就是内存的地址或者是寄存器
- 在虚拟存储器系统中,有效地址就是虚拟地址或者寄存器
- 虚拟地址的长度往往会超过地址字段或者是寄存器的位数,就需要通过间接寻址或者是寄存器间接寻址以及偏移寻址方式等方式来获得
# 立即数寻址
- 操作数是指令的一部分,操作数 = 形式地址
- 数以补码形式存储,最左为符号位
- 当操作数装入数据寄存器时,按照补码扩展的方式来填充数据字的字长
- 优点
最简单的寻址模式,不需要访问内存或缓存快速 - 缺点
数的大小受限于地址字段长度,范围有限
定义和使用常量,设置变量的初始值
# 直接寻址
- 地址字段就含有操作数的有效地址
- 有效地址 EA = 指令中的形式地址
- 优点
只要求一次存储器访问
无需额外计算就可得出有效地址 - 缺点
受限于地址字段长度,只能提供有限的地址空间
# 间接寻址
-
指令中的地址字段((形式地址) 不直接给出操作数地址,而是指出有效地址所在的存储单元的地址
-
EA=(A)
查找地址 A,找到 A 中存放的内容 (A),该内容才是真正的操作数有效地址 (A), 然后再通过该地址查找到真正的操作数 -
允许进行嵌套或级联
e.g. EA =(((A))) -
优点
更大的地址空间
对于一次间接寻址,存储单元为 N 位字长来说寻址范围可达 2^N -
缺点
需要两次 (一次间接寻址) 或多次 (多次间接寻址) 内存访问来查找操作数
速度较慢
# 寄存器寻址
- 指令中的地址字段(形式地址) 直接给出
- 寄存器的编号
- EA=R
- 寄存器数量有限
- 寄存器编码比较短
- 3~5bits
- 优点
无须访存
执行速度快
指令更短 - 缺点
地址空间十分有限 - 程序员或编译器应判定哪些值应保留在寄存器中,哪些值应存于存储器中
对于经常使用的变量,最好将它们定义为寄存器变量
计算的中间结果
# 寄存器间接寻址
- 与间接寻址类似,地址字段给出的是寄存器的编号,操作数的有效地址是寄存器里的内容
- EA= ®
- 操作数在寄存器 R 的内容所指向的存储单元中
- 同样可以获得较大的地址空间 (2^N)
- 指令的执行仍需访存
- 寄存器间接寻址比间接寻址少一次存储器访问
# 隐含寻址
- 操作数的地址不会直接显示出来,地址隐含在某些特定寄存器中
E.g.AC - 隐含的具体寄存器与所使用的指令密切相关
- 有利于缩短指令长度
# 偏移寻址
- 一种更为有力的寻址方式
- 直接寻址和寄存器间接寻址的结合
EA=A+® - 指令要求有两个地址字段
两者至少有一个是显式的 A = 基址值
R = 偏移地址
反之亦可
基址寄存器,相对寻址,变址寻址
# 相对寻址
- R = 程序计数器 PC
PC 隐含
也被称为 PC 相对寻址 - EA=A+(PC)
A 是地址字段的值,被看为是补码 (可正可负)
有效地址是对当前指令地址的一个前后范围的偏移 - 常用于转移类指令
最大特点是转移地址不固定,随 PC 值的变化而变化
无论程序在内存的哪段区域都可正确运行
基于局部性原理,跳转的指令和目前正在执行指令距离不远,那么使用相对寻址可以节省指令中地址码所需的位数
# 基址寄存器寻址
- EA =A+®
A: 偏移量,被认为是无符号数
R: 基址 - R 可以是显式的也可以是隐式的
- 用于 OS 的地址转换
常常用于分页或分段后查找真正的物理地址
# 变址寻址
- A = 基址,一般不变
- R = 偏移量,被认为是无符号数
- EA=A+®
- 适合访问数组或编写循环程序
EA=A+®
R 十十 - 对寄存器的加 1 操作当然很快,所以能加速指令执行
# 组合寻址方式
- 后变址
在间接寻址之后再进行变址
EA=(A)+®
有效地址是地址 A 中内容与 R 中内容的加和
用于访问数据块,比如 PCB - 前变址
变址在间接寻址之前
EA=(A+®)
有效地址为地址 A 加上 R 中的内容作为地址访存所得到的内容
构建多路转移表
# 堆栈寻址
- 操作数 (隐式地) 位于栈顶
- SP 寄存器指向栈顶
- 对存储器中栈的访问实际属于寄存器间接寻址
- 栈顶指针 SP 隐含
# 指令格式
- 指令格式通过它的各个构成部分来定义指令的位安排
- 大多数的指令集使用不止一种指令格式
- 需要定义
指令长度
操作码的位数
地址码的位数
地址个数
寻址方式
指令字长和操作码位数是否可变
# 指令长度
决定了汇编编程人员所看到的指令的丰富性和灵活度
- 受以下因素影响
存储器尺寸
存储器组织
总线结构
CPU 复杂程度
CPU 速度 - 指令长度需在指令的强有力性和存储时节省空间之间进行权衡考虑
编程人员希望更多的操作码、更多的操作数、更多的寻址方式和更大的地址范围
这些都会导致指令长度变长
但过长的指令长度可能产生很大的浪费 - 指令长度应当等于数据总线宽度或其整数倍数
使得在取指周期得到整齐数目的指令 - 指令长度应当等于字符长度或定点数长度的整数倍
# 位的分配
- 对于一个给定的指令长度,显然要在操作码数目和寻址能力之间进行权衡
操作码越多,操作码字段越长,地址码就越少,寻址空间比较有限
操作码太少,功能就会不全 - 变长操作码
指定一个最小操作码长度
对于某些操作码,可以通过使用指令附加位的方法来指定附加的操作
只用于要求较少操作数及寻址方式较少的指令的情况
# 可变长度的指令
提供不同长度的各种指令格式
操作码长度不同
寻址方式可更加灵活
可适用于更复杂的 CPU
# 词汇
-
Bi-endian: 双端次序
-
Big endian: 大数在先
-
Little endian: 小数在先
-
Jump: 跳转
-
Operand: 操作数
-
Pop: 弹出
-
Push: 压入
-
Reentrant procedure: 可重入过程
-
Reverse Polish notation: 逆波兰表示法
-
Autoindexing: 自动变址
-
Effective address: 有效地址
-
Displacement addressing: 偏移寻址
-
Indexing: 变址
-
Instruction format: 指令格式
-
Relative addressing: 相对寻址
-
Postindexing: 后变址
-
Preindexing: 前变址
# keypoint
- Relationships between Instruction set, CPU and high-level language
- Instruction types
- What is 0 address instruction?
- Which are types of operands?
- Which are types of operations?
Shift - MMX Instructions and applications
Data types
Functions of MMX instructions - Common addressing modes
- PII addressing modes
- PII instruction format