MIPS32异常处理

官方信息技术老师·18 页·深入(追求细节与边界)·0 次浏览·2 天前
异常向量CP0寄存器上下文切换ERET返回

MIPS32异常处理

看清异常触发到ERET返回的每一步:CP0状态切换、向量分流与现场恢复

按 空格/→ 演示下一步

1 / 18 页

全部页面点击任意一页,跳回舞台从这页播放

异常向量CP0寄存器上下文切换ERET返回

MIPS32异常处理

看清异常触发到ERET返回的每一步:CP0状态切换、向量分流与现场恢复

1第 1 页 · MIPS32异常处理

什么是MIPS异常

你正在写代码,同事拍你肩膀问问题——你必须暂停手头工作回应,处理完再继续。CPU执行指令时也会遇到类似情况,MIPS把所有这类'正在做的事被强行打断'的事件,统称为异常。

异常的本质
任何打断CPU顺序执行的事件,MIPS统称为异常
中断
外部硬件异步发出,CPU随时可能被打断
同步异常
执行当前指令时由CPU内部检测触发
统一处理
MIPS将两者统一转入异常处理入口执行
办公室工作被打断对应 →MIPS异常

同事叫你=外部中断;发现代码bug=内部异常;都让你暂停手头工作

2第 2 页 · 什么是MIPS异常

异常类型详解

CPU 逐条执行指令时,可能被各种事件打断:硬件敲门、电话响起、算账溢出……异常种类繁多,本页按触发方式给它们分类。

中断(Interrupt)
硬件异步触发;外部设备或计时器拉线;可屏蔽
系统调用(Syscall)
程序主动触发;请求内核服务;同步精确
陷阱(Trap)
条件陷阱指令触发;如 teqi/tnei;同步精确
溢出(Overflow)
有符号整数运算结果超出范围;同步精确
错误类异常
保留指令、地址错误、TLB 缺失;同步精确
前台接待的访客对应 →MIPS异常分类

客人突然来访(中断)vs 同事按铃求助(系统调用)vs 账目算错(溢出)

3第 3 页 · 异常类型详解

异常分类结构图

树状图展示各类型异常的包含关系

异常分类结构图
树状图展示各类型异常的包含关系
4第 4 页 · 异常分类结构图

异常向量基础

认识了那么多异常类型——中断、syscall、TLB miss——CPU 在异常发生的那一瞬间,是怎么知道该跳到哪段代码去处理的?这就要靠「异常向量」了。

异常向量的本质
异常处理程序的入口地址,CPU 异常时自动跳转到这里
MIPS32 入口定位
由 CP0 的 EBase 寄存器(r2 起)或 BEV 位(r1)决定基址
通用异常偏移 0x180
通用异常入口地址 = 基址 + 0x180,MIPS 规范写死的偏移
共享入口与二次分发
多类异常共用同一入口,handler 读 Cause 寄存器再分发
医院急诊分诊对应 →MIPS 异常向量

急症先到分诊台统一登记,再由护士按症状分发到对应科室

5第 5 页 · 异常向量基础

异常向量内存布局

从0x80000000起,4个向量槽以0x80字节为间距顺次排列。

图解渲染中…
n1TLB未命中专用入口,最高频n3Cache奇偶校验错误专用n4通用入口,承接绝大多数异常
6第 6 页 · 异常向量内存布局

向量模式与地址计算

上一节我们看到异常入口被摆在固定地址。但同一类异常里可能混着多个设备在喊,CPU 怎么知道是谁?两种「寻路模式」给出了不同答案。

普通向量模式
一类异常共享一个入口,软件读 Cause[IP] 二次分发
向量化中断
Cause[IV]=1 时启用,每个 IP 位对应独立 ISR 入口
地址计算公式
EBase + 0x200 + n×0x20,n 来自 Cause[IP]
模式开关位
Cause[IV] 控制走 0x180 通用向量还是 0x200 中断专用
公司前台对应 →普通向量模式

所有访客先到前台,再由前台引导到对应部门

Vectorn=EBase+0x200+n×0x20\text{Vector}_n = \text{EBase} + 0\text{x}200 + n \times 0\text{x}20
7第 7 页 · 向量模式与地址计算

硬件自动行为

硬件接管异常瞬间,会自动完成五件关键动作,软件无需插手。

1
EPC保存PC
把触发异常指令的地址存入EPC寄存器,作为处理完后的返回点
2
Cause记录原因
Cause寄存器标记异常类型码和Branch Delay标志
3
Status字段移位
Status整体右移一位,旧KSU与IE压入前态字段
4
切内核关中断
进入Kernel态,IE清0,新中断被屏蔽
5
PC指向向量
PC被硬件改写为异常向量入口地址,控制权移交
8第 8 页 · 硬件自动行为

EPC寄存器详解

上页讲到硬件自动保存现场,最关键的是 EPC。它不是简单备份 PC,而是定义了"异常处理完后从哪里恢复执行"。这个寄存器在精确/非精确异常、延迟槽等边界场景下有讲究。

EPC的职责
保存异常瞬间的程序计数器,决定异常返回后从哪里继续执行
指向未完成指令
不是上一条,不是下一条,是那条"闯祸"且未提交的指令
精确异常语义
中断、系统调用等,EPC就是触发异常的那条指令地址
非精确异常边界
总线错误等场景,EPC指向异常时尚未提交的指令
延迟槽陷阱
异常指令在分支延迟槽时,EPC指向分支本身,Cause.BD被置位
看书书签对应 →EPC

书签标记"被打断的那一页"。EPC标记"闯祸的指令",ERET把书签插回原处

9第 9 页 · EPC寄存器详解

Cause与Status寄存器

前面 EPC 保存了『从哪里来』,但处理器还要回答两个问题:『异常是什么类型』、『当前处理器处于什么状态』。分别由 Cause 和 Status 两个寄存器承担。

Cause寄存器
CP0 $13,记录异常原因;ExcCode 字段占 6-2 位,编码 0~31 号具体异常
Status寄存器
CP0 $12,记录处理器状态,控制中断使能与当前运行模式
BD 位
Cause bit 31,标记异常是否发生在分支延迟槽
EXL 位
Status bit 1,异常时硬件自动置 1,进入内核模式并禁止嵌套异常
IM 与 IE
IM(15-8 位)按位屏蔽硬件中断源;IE(bit 0)作为全局中断开关
急诊分诊台对应 →Cause 与 Status

Cause=病历诊断(什么病、在哪发作);Status=病人当前状态与可用的治疗权限

10第 10 页 · Cause与Status寄存器

软件处理流程

进入异常向量后,软件接管,按顺序完成五件事。

1
保存现场
把 GPR 与 Status 压栈,防止处理过程破坏原上下文
2
读取Cause
查看 Cause.ExcCode 字段,识别异常具体类型
3
分发处理
按类型跳转对应 handler:系统调用、断点、TLB、中断等
4
恢复现场
从栈中加载之前保存的寄存器值
5
ERET返回
原子恢复 PC←EPC、清 EXL 与 IE 位,跳回原断点
11第 11 页 · 软件处理流程

异常处理完整时序图

硬件到软件的全流程时序

异常处理完整时序图
硬件到软件的全流程时序
12第 12 页 · 异常处理完整时序图

基础异常处理代码

最小可运行的异常处理框架

基础异常处理代码
最小可运行的异常处理框架
13第 13 页 · 基础异常处理代码

系统调用异常处理

asm

一段 MIPS32 syscall 处理汇编:硬件自动保存上下文后,内核按 o32 约定分发。

代码高亮加载中…

L7 提取 BD 位;L20-L22 是 o32 约定——v0 传 syscall 号,a0/a1 装参数;L35 eret 原子清 EXL 跳回 EPC。

14第 14 页 · 系统调用异常处理

实例流程分析

从执行syscall到返回用户态,按时序看硬件与软件如何接力。

图解渲染中…
CPUCPU硬件自动行为REGEPC/Cause/Status寄存器MEM异常向量表所在内存HND操作系统异常处理代码
15第 15 页 · 实例流程分析

核心概念自测

点击作答

MIPS 异常若发生在分支延迟槽内,硬件自动保存到 EPC 寄存器的是哪条指令的地址?

16第 16 页 · 核心概念自测

MIPS32异常处理要点

  • 向量入口地址由硬件固定映射,软件只需放置处理例程
  • 硬件只保存PC与状态位,通用寄存器全靠软件压栈
  • EPC返回靠jr写回PC,rfe弹出Status栈恢复旧状态
  • Cause区分异常来源,Status栈位实现中断嵌套屏蔽
  • 异常与中断共享同一向量机制,区别仅在触发来源
延伸主题:TLB缺失处理细节异常嵌套与优先级MIPS64R向量扩展
17第 17 页 · MIPS32异常处理要点

课后思考

先独立思考再看参考答案,三题对应回顾、应用与边界三个层次。

1硬件自动保存EPC、Cause、Status寄存器的设计,相比让软件来保存这些状态有什么根本优势?

参考答案硬件自动保存让关键状态不依赖软件正确性——即便handler有bug导致崩溃,现场也已保留;纯软件保存则可能在崩溃时丢失上下文,本质是信任边界的划分。

2若异常处理程序内部又触发了新异常(如TLB缺失),MIPS如何防止无限递归?嵌套处理的关键机制是什么?

参考答案EPC和Cause会被覆盖为新异常的现场,但Status.EXL使CPU进入内核态并屏蔽后续异常;handler必须显式清除EXL才能重新允许嵌套,本质是状态机保护。

3在实时系统中要求异常处理延迟不超过100个周期,你会从哪些维度优化异常入口的执行路径?

参考答案三个维度:①缩小保存寄存器集,只save实际用到的;②handler紧致排布并对齐i-cache减少miss;③用EPC+4直接跳转,跳过向量表查表开销。

18第 18 页 · 课后思考