CA3 指令集体系结构
CA3 指令集体系结构
机器指令
包含:存储地址、寄存器地址、立即数
- 操作码 opcode
- 操作内容 add,mult
- 操作数 int,fp
- 操作数 operand
- 位置(寄存器或储存器)
- 操作数个数不定(1个或2个)
指令运行
- PC 存放的当前执行的指令在内存中的地址(32bit or 64bit)
- PC 输出到指令存储器 IM(只读)
- IM 传到 IR
- IR 译码器 到 通用寄存器 GPRs
- GPRs 包含 rs1->rd1 rs2->rd2 ws wd
- 输出到 A B 两个寄存器,通过 MUX 选择输出到 ALU
- ALU 运算输出结果,可以写到 DM 中,也可以写入 寄存器 wd 中
定义
- 是软件和硬件之间的边界
- 是程序员或编译器所见到的计算机
- 在某种意义上,是由一组所使用的汇编语言及它们所完成的工作来定义的
指令集体系结构里包含的基本内容
寄存器、存储器寻址和寻址方式、指令操作数、有效操作、控制流指令、指令编码……
设计目标
较短的指令宽度
- 最小化指令宽度,从而最小化程序长度
较好的指令密度(完成一件事情需要的指令数要少)
- 最小化指令数目,从而最小化程序长度
快速的指令操作
- 如:add (100) (200) (300) 执行的时间比 add r1 r2 r3 要长
简单的电路实现
优化的编译器
指令集体系结构类型
- 堆栈型(Stack)(早期)
- 所有操作数都来自堆栈
- 累加器型(Accumulator)
- 一个操作数在累加器中,另一个操作数必须显式地引用
- 寄存器型(Register)(现在主要使用)
- 所有操作数必须显式地引用
- 操作数可以存储在寄存器或存储器中
寄存器型指令集体系结构
- 操作数必须有明显的操作数格式
- 寄存器在 CPU 内部
- 指令集体系结构提供
- LOAD 存储器 -> 寄存器
- STORE 寄存器 -> 存储器
- 这种体系结构也被称为通用寄存器 General-Purpose Register 指令集体系结构
- 分为三种类型
- 寄存器-存储器 ISA
- 寄存器-寄存器 ISA(装入-存储 ISA)——现代 CPU 常用结构
- 存储器-存储器 ISA——废弃
寄存器-寄存器 ISA
- 特殊指令访问存储器:LOAD、STORE
- 基本运算步骤
- 从存储器装入第一个操作数到寄存器中
- 从存储器装入第二个操作数到寄存器中
- 在 ALU 中完成运算操作
- 如果需要,将操作结构存储到存储器中
- 两个操作数和结果的位置都需要显式地引用
寄存器数目
- 现代指令集体系结构倾向于拥有更多的寄存器
- 拥有更多的寄存器使得编译器拥有更多的机会来提高效率
- 通常,编译器预留一些寄存器用于特殊目的
- 保留函数调用的参数
- 帮助表达式求值
- 剩余的寄存器用于保存程序变量
存储器寻址
ISA 必须定义存储器的寻址方式
- 如何解释
- 如何在指令中说明
绝大多数的存储器寻址采用字节地址
能够寻址的最小存储器片段是一个字节
意味着每个字节拥有一个使用二进制串表示的地址
通常,ISA 可以访问
- 字节 8bit
- 半字 16bit
- 字 32bit
- 双字 64bit
存储对齐
当大多数计算机访问大于一个字节的对象时,往往必须对齐
定义:如果访问对象地址是对象长度 S 的倍数时,称问访问对象是对齐的
例如
- 在000000 访问一个 byte 是对齐的
- 在000001 访问一个 半字 是未对齐的
字节顺序
- 在半字、字和双字内的字节存在着两种约定
- 小端法 0x0000 的字节放的最低有效位
- 大端法 0x0000 的字节放的最高有效位
- 某些体系结构可以通过设置来决定采用哪种字节顺序
- 在绝大多数情况下不必关系字节顺序问题,但
- 当以双字和字节方式访问相同存储位置时,可能出现问题
- 当在计算机之间交换数据时,可能出现问题
寻址方式
寄存器寻址(直接写寄存器号得到寄存器的内容)
立即数寻址(立即数前加个#)
位移寻址(寄存器内容加上外部偏移量寻址)
寄存器间接寻址(将寄存器的内容作为地址来寻址)
索引寻址(两寄存器内容之和作为内存地址)
直接寻址(mem[100],直接写死地址)
存储器间接寻址(寄存器的内容作为mem地址进行寻址,再将这个mem读出的值作为地址来寻址,mem[mem[regs[R3]]])
自动增/减量寻址(寄存器简介寻址后该寄存器的值自增/减)
比例寻址(mem[100+regs[R2]+regs[R3]*d])
基准程序中各种寻址方式的频度
略
选择寻址方式:平衡
寻址方式的选择
- 一些 ISA 选择所有的寻址方式,如 WAX
- 另一些 ISA 只使用少数几种寻址方式,如 MIPS
平衡因素
- 寻址方式越多,IC(指令数) 越低
- 寻址方式越多,硬件越复杂
- 寻址方式越多,CPI(指令周期数) 越高
目标:平衡
- 简化硬件
- 拥有足够的寻址方式,以至于书写代码不会太痛苦
选择位移范围
- 权衡考虑
- 位移最大值越大,指令使用范围越广
- 位移最大值越小,指令编码越短
操作数类型和大小
- 字符 1byte
- 半字 2byte
- 字 4byte
- 单精度浮点和长整数 4byte
- 双精度浮点 8byte
各种类型操作
算术和逻辑(通用)
- 整数加减乘除、与或运算
数据传输(通用)
- 装入、存储
控制(通用)
- 分支、跳转、过程调用和返回、陷阱
系统(可变)
- 操作系统调用、管理虚拟内存指令
浮点数(可选)
- 加减乘、比较
字符串(可选)
- 字符串比较、字符串搜索
图形(可选)
- 像素点和顶点操作,压缩与解压操作
指令编码
关键考虑因素
- 拥有更多的寄存器和寻址方式,会造成较长的指令代码
- 期望降低平均指令代码长度和平均程序长度
- 期望指令能够容易且快速译码
指令编码方法
- 可变格式(满足前二)
- 固定格式(满足第三)
- 混合格式(尝试达到平衡)
可变的,如 intel 的 VAX;固定的,如 RISC-V,ARM,MIPS,PowerPC,SPARC;混合的
编译优化
- 高层优化
- 针对源代码进行,可能是源到源的转换
- 如:为了 cache 有效性来映射数据,除去条件等
- 局部优化
- 在较短的直线段源代码中优化代码
- 全局优化
- 跨过分支指令进行优化,循环优化(循环展开)
- 寄存器分配
- 寄存器赋初值
CISC vs RISC
- 谬误:“简约指令集”并不意味着指令数目少
- RISC 的关键
- 寄存器中完成操作
- 使用 LOAD 和 STORE 指令完成寄存器和存储器之间的通信
- 代码是由一系列简单操作实现的
- 注解:当代码量是关键因素时,RISC 并不是一个好的选择
All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.
Comment