异常处理记录

news/2024/9/29 3:19:53

异常处理过程:

当我们遇到异常时,我们首先需要把当前程序P的状态保存起来,而后跳到异常处理程序进行诊断。

  • 这里我们从指令集状态机S = {<R,M>}的视角来讨论咯 R为寄存器,M为内存。

异常处理程序和P事两个不同的程序,它们使用不同的M,所以:只要异常处理程序不随意修改P的M,则不必进行实质性的保存操作。
但是R只有一份,即P和异常处理程序共用寄存器,所以我们需要把P的寄存器状态保存起来。
但是R保存到哪里呢??
有几种方法:
1.保存到R:也就是增加新的一组寄存器,把P的寄存器状态复制到新寄存器中。
2.保存到M:也就是存到内存中,但是需要找到一处空闲的内存呢
3.保存到栈:栈有空间的话,这个可以有。

谁来保存?

  • 硬件保存:在CPU状态机的控制下保存
  • 软件保存: 通过指令控制CPU进行保存

所以保存R的设计,共有四种方法

R M
硬件保存 硬件保存到R_save 硬件保存到M
软件保存 软件保存到R_save 软件保存到M

当发生异常时的流程如下:P发生异常->硬件保存->跳转到异常处理程序->软件保存
这里要注意的是,当异常处理程序诊断时需要读取R_save。所以CPU还要添加相应的读取等指令。

RISCV硬件将PC保存到mepc这个特殊的寄存器中,也叫控制状态寄存器(CSR,control and status register)

CSR

用于控制和反映处理器状态的特殊寄存器(eg:mepc)

  • 硬件发生某些事会自动更新CSR,或者从CSR中读出值直接用
  • 软件也可以通过CSR指令来访问CSR
  • 所以每个CSR都有一个软件可见的编号(CSR地址空间)
    下面的图片中最上就是一条CSR指令,其中0x341代表mepc寄存器的地址空间(也是编号:-)
    image

最简单异常处理还需要的CSR——mtvec

mtvec:异常处理程序的入口地址,即当发生异常时CPU自动跳转到这个地址
一个简单的异常处理程序

#include <klib.h>
void handler() {uintptr_t mepc;  // 定义一个变量来存储异常发生时的程序计数器 (Program Counter)// 使用内联汇编读取 mepc 寄存器的值asm volatile ("csrr %0, mepc" : "=r"(mepc)); printf("exception at mepc = %p\n", mepc); // 打印异常发生的地址while (1); // 无限循环,防止返回
}
int main() {// 设置 mtvec 寄存器,指向异常处理程序 handlerasm volatile ("csrw mtvec, %0" : :"r"(handler));// 触发非法指令异常asm volatile (".word 0"); // 这行代码试图执行一个无效的指令printf("I am alive!\n");while (1); 
}

类似的还有mcause寄存器,即发生异常时,CPU将异常号写入这个CSR
具体的异常号如下

# RTFM了解异常号的含义0 - Instruction address misaligned1 - Instruction access fault2 - Illegal Instruction3 - Breakpoint4 - Load address misaligned5 - Load access fault6 - Store/AMO address misaligned7 - Store/AMO access fault8 - Environment call from U-mode9 - Environment call from S-mode
11 - Environment call from M-mode
12 - Instruction page fault
13 - Load page fault
15 - Store/AMO page fault

从异常状态返回

若诊断问题不大,P可以继续执行,则需要从异常处理程序返回P。那么返回需要先回复之前为P保存的状态(恢复寄存器就行)

  • RISC架构通过load指令将M中保存的内容恢复到R,然后返回P
  • 但是异常处理程序和P事两个不同的程序,不可以通过ret/jal返回
  • jalr指令需要先把返回地址写入一个寄存器,但是那样会改变P的状态,如果返回后P需要用这个寄存器,就会报错。
    所以综上,我们需要添加一条特殊的返回指令mret,即跳转到mepc中存放的地址
uintptr_t mepc, mcause;
// 读取 mepc 寄存器的值(异常发生时的程序计数器值)
asm volatile ("csrr %0, mepc" : "=r"(mepc));
// 读取 mcause 寄存器的值(异常原因)
asm volatile ("csrr %0, mcause" : "=r"(mcause));
// 打印异常原因和异常发生时的程序计数器值
printf("exception mcause = %p at mepc = %p\n", mcause, mepc);
// 仅限于演示,没有恢复其他寄存器
// 检查异常原因是否为2(通常表示非法指令异常)
if (mcause == 2) {// 更新 mepc 寄存器的值为 mepc + 4(跳过导致异常的指令)asm volatile ("csrw mepc, %0; mret" : : "r"(mepc + 4));
}
while (1);

硬件实现异常处理

在单周期实现异常

实现异常处理我们得先

  • 实现CSR

  • 添加CSR的读写指令,而后在指令异常时注意通用寄存器GPR和CSR之间的数据交换。

  • 实现异常的触发,在译码时要检查非法指令,识别ecall指令等,识别到异常事件后,我们还需要通过电路更新mmepc,,mcause等CSR,而后跳转到mevec中存放的地址

  • 实现mret指令,即跳转到mepc中存放的地址

异常处理的状态机模型

在异常处理状态下,状态机模型又需要改变了,状态机模型需要加一个扩展(CSR),也就是:
R = {PC, GPR,CSR},M无需扩展,注意在这里指令的执行并不是always成功了,定义一个函数
f_ex : S->{0,1},给定任意状态S:

  • f_ex(S) = 0,则按照当前指令的语义进行状态转移
  • f_ex\(S)= 1,则执行一条特殊指令raise_intr异常号,并更新状态如下
CSR[mepc] <- PC
CSR[mcause] <- 异常号
PC <- CSR[mtvec]

说白了,模型状态机一旦异常(f_ex(S)=1),就是把各种异常号,异常的pc值存到CSR寄存器中
image

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hjln.cn/news/45513.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈,一经查实,立即删除!

相关文章

kali

1.下载kali下载地址:Get Kali | Kali Linux 我们直接下载已经搭建好的kali虚拟机 ​​根据你的需求选择版本下载,一般都是选择64位的,点击VMware ​​直接开始下载,如果下载速度慢,请自行挂代理加速下载! 2.安装Kali下载完成之后是一个压缩包文件,请将其解压在无中文目录…

《操作系统原理》读书笔记

《操作系统原理》读书笔记信息 《操作系统原理(第4版)》 庞丽萍 华中科技大学出版社 摘录 绪论 存储程序式计算机冯诺依曼计算机体系结构从20世纪40年代至今,计算机体系结构不断地发展变化,但冯诺依曼计算机体系结构定义的一个存储程序式计算机的家族,几乎是当代所有计算机系…

SAP: SALV Grid 单元格颜色

SALV GRID 单元格颜色1、SAP: SALV Grid 单元格颜色 2、详细程序代码*&---------------------------------------------------------------------* *& Report Z17_43 *& *&---------------------------------------------------------------------* *& SA…

编程学习MarkDown学习

软件 Typora 标题 几个#代表几级标题,最多6级 基本操作 粗体 斜体 划线 分割线图片超链接 百度 列表 有序列表1, 2, 3. 无序列表 减号加空格 引用

基于禁忌搜索算法的TSP路径规划matlab仿真

1.程序功能描述 基于禁忌搜索算法的TSP路径规划,输出优化收敛曲线以及路线规划图。2.测试软件版本以及运行结果展示 MATLAB2022a版本运行3.核心程序for it = 1:Iterationit% 初始化本次迭代的最佳新解代价为正无穷 bestnewsol.Cost = inf;% 遍历所有动作并尝试应用它们 for …

Typora 样式

1:修改主题 可以根据 官方文档 修改主题 CSS。 配合左上角菜单 视图》开发者工具 来修改 CSS 效率更高。 2:我的主题 2.1:黑暗主题 根据自己的喜好在 night-new 主题上修改了点 https://blog.csdn.net/weixin_52023681/article/details/1202515232.2:光明主题 根据自己的喜…

基于cJSON及心知天气模块化实现获取城市气象信息(现在、未来)

用于请求心知天气的信息, 现在的信息, 未来n天的气象信息. 使用域名通过TCP连接到心知天气服务器, 采用cJSON进行解析.模块化实现, 可选择英文、中文;天数;城市;V1.0 2024年6月14日 发布于博客园目录序言功能描述运行结果示范注意!代码weather_api.hweather_api.cdemo.ccJSON.h…

pycharm配置anaconda虚拟环境

终于知道怎么给pycharm配置虚拟环境了()file——》setting 找到project:项目 点击python interpreter 点击add interpreter——》add local interpreter 选择conda envrionment(不用管右边红色的报错) 点击红色框里的文件夹形状的按钮 这里要导入的是.bat文件,一般在anac…