一 MIPS架构概述
1.1 基本概述
MIPS(Microprocessor without Interlocked Pipeline Stages),是一种采取精简指令集(RISC)的指令集架构(ISA),1981年出现,由 MIPS 公司开发并授权,广泛被使用在许多电子产品、网络设备、个人娱乐设备与商业设备上。最早的MIPS架构是 32 比特,最新的版本已经变成 64 比特。商业市场主要竞争对手为ARM与RISC-V。
MIPS 架构有多个版本。其中包括 MIPS I、II、III、IV,以及 MIPS V,它们各自各自是 MIPS32/64(分别是 32 位、64 位的实现)发布的五个版本。早期的 MIPS 架构只有 32 位的版本,而其 64 位的版本随后才被开发。截至 2017 年 4 月,MIPS32/64 的当前版本是 MIPS32/64 Release 6。MIPS32/64 与 MIPS I–V 的主要区别在于它除了用户态架构外,还定义了特权内核模式系统控制协处理器。
MIPS 架构有几个可选的拓展。比如 MIPS-3D,它是一个专用于常见 3D 计算任务的浮点 SIMD 指令集的简单集合;MDMX(MaDMaX)是一个应用更加广泛的整数 SIMD 指令集,它使用了 64 位浮点数寄存器;MIPS16e 则为提供了指令流压缩的功能,这可以减小程序的体积;MIPS MT 则提供了多线程的能力。
1.2 延迟槽
为了减少各种指令后流水线的阻塞,MIPS I代版本引入了延迟槽机制,在分支与加载指令后都有一条指令的延迟槽。分支指令延迟槽中的内容会先于分支指令被提交。而加载指令的延迟槽中则不允许使用刚刚加载的数据。一般情况下延迟槽的安排会由汇编器完成,但在一些情况下程序员仍然需要关注他的存在。对于实在无法安排指令的延迟槽可以直接填入“NOP”。
1.3 操作数
MIPS包括32个寄存器和2^30个存储器字,详见下表。
名字 | 举例 | 注释 |
32个寄存器 | $s0 ~ $s7,$t0 ~ $t9,$zero,$a0 ~ $a3,$v0 ~ $v1,$gp,$fp,$sp,$ra,$at | 寄存器用于数据的快速访问。在MIPS中,只能对存放在寄存器中的数执行算术操作,寄存器$zero恒为0,寄存器$at被汇编器保留,用于处理大的常数。 |
2^30个存储字 | Memory[0],Memory[4],…,Memory[4294967292] | 存储器只能通过数据传输指令访问。MIPS使用字节编址,所以连续的字地址相差4。存储器用于保存数据结构、数组和溢出的寄存器 |
1.4 指令格式
在MIPS架构中,指令被分为三种类型:R型、I型和J型。三种类型的指令的最高6位均为6位的opcode码。从25位往下:
- R型指令用连续三个5位二进制码来表示三个寄存器的地址,然后用一个5位二进制码来表示移位的位数(如果未使用移位操作,则全为0),最后为6位的function码(它与opcode码共同决定R型指令的具体操作方式);
- I型指令则用连续两个5位二进制码来表示两个寄存器的地址,然后是一个16位二进制码来表示的一个立即数二进制码;
- J型指令用26位二进制码来表示跳转目标的指令地址(实际的指令地址应为32位,其中最低两位为00,)。
三种类型的指令图示如下:
类型 | 位 | |||||||||||||||||||||||||||||||
31 | 30 | 29 | 28 | 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 | 19 | 18 | 17 | 16 | 15 | 14 | 13 | 12 | 11 | 10 | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | |
R | opcode (6) | rs (5) | rt (5) | rd (5) | shamt (5) | funct (6) | ||||||||||||||||||||||||||
I | opcode (6) | rs (5) | rt (5) | immediate (16) | ||||||||||||||||||||||||||||
J | opcode (6) | address (26) |
1.5 指令
MIPS I代版本具有访存8-bit字节,16-bit半字,32-bit字的能力, 并且只支持“基地址+偏移”一种寻址模式。 由于MIPS I是一种32位架构,少于32-bit的加载指令在目标寄存器中都会对高位进行符号扩展或全零扩展到32-bit。带有 “无符号” 后缀的指令会被进行全零扩展,其他的指令会进行符号扩展。 加载指令会从一个通用寄存器中获取基地址 (rs) 并将从操作地址读取的结果写入一个通用寄存器 (rt)。存储指令则会从一个通用寄存器获取基地址(rs),将另一个通用寄存器(rt)中的内容写入相应操作地址。所有的访存指令都会将基地址加上指令中的有符号16-bit立即数immediate偏移以获得最终操作地址。 MIPS I代版本要求所有的访存指令与操作单位对齐,也就是目标地址必须是所访问数据字节数的整数倍。为了支持高效的非对其访存,MIPS提供了带左/右后缀的访存指令。所有的加载指令后面带有一个延迟槽,延迟槽内的指令不得使用刚刚加载的指令。
指令功能 | 助记符 | 格式 | 格式 | |||
加载字节 | LB | I | 3210 | rs | rt | offset |
加载半字 | LH | I | 3310 | rs | rt | offset |
加载字左 | LWL | I | 3410 | rs | rt | offset |
加载字 | LW | I | 3510 | rs | rt | offset |
加载无符号字 | LBU | I | 3610 | rs | rt | offset |
加载无符号半字 | LHU | I | 3710 | rs | rt | offset |
加载字右 | LWR | I | 3810 | rs | rt | offset |
存储字节 | SB | I | 4010 | rs | rt | offset |
存储半字 | SH | I | 4110 | rs | rt | offset |
存储字左 | SWL | I | 4210 | rs | rt | offset |
存储字 | SW | I | 4310 | rs | rt | offset |
存储字右 | SWR | I | 4610 | rs | rt | offset |