引言
MIPS(Microprocessor without Interlocked Pipeline Stages)作为经典RISC架构的代表,其设计哲学深刻影响了现代处理器的发展。MIPS架构通过精简指令、统一编码、流水线优化等设计,实现了软硬件协同的高效运行。本讲将结合理论模型与实践案例,深入解析MIPS架构的核心要素。
一、MIPS的寄存器设计
1. 寄存器组织架构表
寄存器名 | 编号 | 功能描述 | 调用约定 |
---|---|---|---|
$zero | 0 | 恒零寄存器 | 不可修改 |
$at | 1 | 汇编器保留 | 临时变量 |
v0−v0−v1 | 2-3 | 函数返回值 | 调用者保存 |
a0−a0−a3 | 4-7 | 函数参数传递 | 调用者保存 |
t0−t0−t9 | 8-15,24-25 | 临时寄存器 | 调用者保存 |
s0−s0−s7 | 16-23 | 保存寄存器 | 被调用者保存 |
k0−k0−k1 | 26-27 | 内核专用 | 系统保留 |
$gp | 28 | 全局指针 | 静态数据寻址 |
$sp | 29 | 栈指针 | 函数栈管理 |
$fp | 30 | 帧指针 | 可选栈帧基准 |
$ra | 31 | 返回地址 | 子程序跳转 |
设计特点:
- 32个通用寄存器(32位架构)实现快速数据存取
- 硬件零寄存器($zero)消除零值加载开销
- 调用约定分离(Caller/Callee-Saved)提升子程序效率
二、MIPS的数据表示
1. 基础数据类型表
数据类型 | 位宽 | 存储方式 | 对齐要求 |
---|---|---|---|
字节(Byte) | 8位 | 补码/ASCII | 任意地址 |
半字(Half) | 16位 | 补码 | 地址末位为0 |
字(Word) | 32位 | 补码/IEEE 754单精度浮点 | 地址末两位为0 |
双字(Double) | 64位 | IEEE 754双精度浮点 | 地址末三位为0 |
关键规范:
- 大端序存储(Big-Endian)为主流实现
- 非对齐访问触发异常(AdEL/AdES)
- 浮点数据独立使用协处理器寄存器(f0−f0−f31)
三、MIPS的数据寻址方式
1. 五类寻址模式
(1)立即数寻址
- 应用指令:
addi $t0, $t1, 0x100
- 取值范围:16位有符号数(-32768~32767)
(2)基址+偏移寻址
- 地址计算:
EA = base + offset
- 典型指令:
lw $t0, 0x2000($s1)
(3)PC相对寻址
- 跳转范围:±128KB(18位符号扩展)
- 应用场景:条件分支指令
beq $s0, $s1, label
四、MIPS的指令格式
1. 统一编码结构表
指令类型 | 字段划分(32位) | 典型指令 |
---|---|---|
R型 | op(6) | rs(5) |
I型 | op(6) | rs(5) |
J型 | op(6) | target(26) |
-
R类指令(寄存器操作)
- 结构:6位操作码 + 5位rs + 5位rt + 5位rd + 5位shamt + 6位funct。
- 示例:DADDU R1, R2, R3(功能码指定无符号加法)。
-
I类指令(立即数操作)
- 结构:6位操作码 + 5位rs + 5位rt + 16位立即数。
- 示例:LW R2,40(R3)(从内存地址40+R3装入字到R2)。
-
J类指令(跳转操作)
- 结构:6位操作码 + 26位跳转偏移。
- 示例:J name(直接跳转到目标地址)。
设计精髓:
- 固定32位长度简化流水线设计
- 功能码复用(funct字段)扩展指令集
- 立即数分段处理实现大范围地址覆盖
2. 特殊格式指令案例
指令类型 | 格式示例 | 编码特性 |
---|---|---|
移位指令 | sllv $rd, $rt, $rs | 使用rs寄存器值作为移位量 |
乘除指令 | mult $rs, $rt | 结果存入HI/LO寄存器 |
原子操作 | ll $rt, offset($rs) | 原子加载(需配合sc使用) |
浮点指令 | lwc1 $ft, offset($rs) | 协处理器专用opcode=0x31 |
五、MIPS的操作类型
1. 数据搬运类指令
指令类型 | 汇编语法 | 功能描述 |
---|---|---|
立即数 | li $t0, 0x1234 | 加载32位立即数(伪指令) |
寄存器 | move $s1, $s2 | 寄存器间拷贝(伪指令) |
内存加载 | lw $t0, 0($sp) | 加载字(32位) |
lb $t1, ($a0) | 加载字节(符号扩展) | |
lui $t2, 0xFFFF | 加载高16位立即数 | |
内存存储 | sw $t3, 4($gp) | 存储字 |
sb $t4, ($a1) | 存储字节 |
2. 算术逻辑类指令
(1)基础ALU运算
add $t0, $t1, $t2 # 有符号加法(溢出触发异常)
addu $t3, $t4, $t5 # 无符号加法(常用于地址计算)
sub $a0, $a1, $a2 # 有符号减法
and $v0, $v1, $a3 # 位与运算
xor $s0, $s1, $s2 # 位异或运算
(2)移位运算
sll $t0, $t1, 3 # 逻辑左移3位(空位补0)
srl $t2, $t3, 2 # 逻辑右移2位
sra $t4, $t5, 1 # 算术右移1位(符号位保持)
(3)乘除运算
mult $t0, $t1 # 有符号乘(结果存HI/LO)
div $a0, $a1 # 有符号除(HI=余数,LO=商)
mfhi $s0 # 将HI寄存器值移至通用寄存器
mflo $s1 # 将LO寄存器值移至通用寄存器
3. 特殊功能指令
指令类型 | 汇编语法 | 功能描述 |
---|---|---|
空操作 | nop | 填充延迟槽(实际是sll 0,0,0,0) |
系统调用 | syscall | 触发操作系统服务 |
断点调试 | break 0x1234 | 产生调试异常 |
协处理器 | mtc0 $t0, $12 | 写CP0寄存器(用于异常处理) |
六、MIPS的控制指令
1. 条件分支指令集
指令格式 | 功能描述 | 延迟槽处理 |
---|---|---|
beq $rs, $rt, label | 相等时跳转(PC←PC+4+offset×4) | 必须填充有效指令 |
bne $rs, $rt, label | 不等时跳转 | 常用nop 或有用指令填充 |
bgtz $rs, label | 大于零跳转 | 示例:bgtz $s0, loop |
blez $rs, label | 小于等于零跳转 | 需要配合slt指令实现复杂条件 |
2. 跳转与子程序指令
(1)绝对跳转
j 0x00400000 # 直接跳转到指定地址
jr $ra # 跳转到$ra保存的返回地址
(2)过程调用
jal proc_name # 1. $ra←PC+4
# 2. PC←目标地址
jalr $t0 # 跳转到$t0地址,同时保存$ra
(3)延迟槽编程技巧
beq $s0, $s1, target
addi $t0, $t0, 1 # 延迟槽指令总被执行
3. 异常控制指令
指令格式 | 触发条件 | 典型应用场景 |
---|---|---|
teq $rs, $rt | rs=rt时触发陷阱 | 除零检测 |
tne $rs, $rt | rs≠rt时触发陷阱 | 空指针检查 |
syscall | 系统调用 | 输入输出操作 |
eret | 从异常返回 | 中断处理例程结尾 |
七、MIPS的浮点操作
1. 浮点处理单元
(1)数据移动指令
lwc1 $f2, 0($t0)
加载单精度浮点数sdc1 $f4, 8($t1)
存储双精度浮点数
(2)运算指令特点
- 独立控制状态寄存器(FCSR)管理异常标志
- 非精确异常模式提升流水线效率
结语:MIPS架构的设计哲学
MIPS的成功源于三大核心原则:
- 精简指令:通过Load/Store架构减少访存指令占比至15%
- 流水线友好:统一指令格式使5级流水线CPI降至1.2
- 软硬件协同:编译器优化弥补硬件简化带来的代码膨胀
当前MIPS架构在嵌入式与教学领域仍具生命力,其设计思想深刻影响了RISC-V等新一代架构的发展。理解MIPS的精髓,是掌握现代处理器设计方法论的重要基石。