1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > 【汇编语言与计算机系统结构笔记18】MIPS指令集与汇编程序设计 异常处理

【汇编语言与计算机系统结构笔记18】MIPS指令集与汇编程序设计 异常处理

时间:2022-12-05 13:32:02

相关推荐

【汇编语言与计算机系统结构笔记18】MIPS指令集与汇编程序设计  异常处理

本次笔记内容:

28.MIPS指令集与汇编程序设计-2

补充:MIPS32异常处理

注:我找到了对应内容的课件,请见我于GitHub的CS笔记仓库。

本节课对应幻灯片:汇编语言程式设计-MIPS.pdf,第49页起。

在B站视频中,缺了一节课,即 ‘MIPS32异常处理’ ,感谢 UP 主东南偏南做的补充:汇编语言程序设计(清华大学张悠慧)P27。

我们讲 MIPS32 ,主要集中在其特色部分。

文章目录

P49 定长指令造成了一些困扰P51 指令编码P58 MIPS汇编指示(Directives)示例一:分别计算整数数组中正数、负数的和示例二:阶乘(delay slot关闭)MIPS32异常处理异步异常(中断)异常处理向量(Vectors)精确异常处理(MIPS支持)MIPS32的异常种类MIPS异常处理基本过程异常返回中断MIPS处理器的中断控制设计SPIM模拟器支持的异常处理流程Status寄存器Cause寄存器异常处理实例

P49 定长指令造成了一些困扰

如上。某些操作数的限制(如立即数宽度)增加了汇编编程难度。为降低难度,MIPS汇编器会做一些预处理。

如上,at寄存器保留给汇编器专用,就用在了这里。因此一般情况下不要手动使用。

对于li $3, -5,其意义其实就是因为 -5 不大,因此直接用 addiu 装到 $3 中。

对于li $4, 0x8000正好放得下 16 位中,因此转换的方法较多,这里转换为ori 或指令,是可以的。

对于0x120000,把 12 拿出来,放到高 16 位对应的位置,低 16 位清零。

对于0x12345,对于低 16 位不全为 0 的,转换为两条指令luiori

在如上的例子中,对于第三条lw $2, addr,这个数宽度较大,至少得把这个指令拆成两条:

%hi相当于汇编中的宏,取高的半字(16位);%lo则是取低的半字。

对于sw $2, addr($3),在基址上加上偏移。

P51 指令编码

三种类型:I-Type、J-Type、R-Type。

Op 段编码如上。其他段编码不再复制,详见 ppt 。

最终,我们要把段编码总结成一个真值表,以此构建电路、控制信号。

P58 MIPS汇编指示(Directives)

注意这里的 word 是 32 byte 。

.data 是一般的数据段,存了 3 个 word ,初值分别是 1,2,3。

.text 定义了 func 的入口地址。

.bss 非初始化的变量在其中,还分为全局可见的local。与 x86 类似。

数据类型定义如上。

这个 .extern 与 C 中的不太一样。

比如,对于lw "offset",偏移量 16 位宽可能不太够。假设地址不够,我们可以如之前一样,换成 2 条指令。但是这样太麻烦了,MIPS32做了简化:

有一个全局指针$gp;程序初始化时,$gp已经初始化好;我们把全局变量放在$gp附近,这样只要变动$gp一点,就可以访问全局变量了。相当于$gp是个轴base。

因此,用.extern定义了全局变量,让其在$.gp上下 64 byte 范围。

示例一:分别计算整数数组中正数、负数的和

先声明数据段;遍历一遍数据段;进入 main 。

这里的syscall是模拟器提供的syscall。在 SPIM 这么简单的一个模拟器中,做不到一个模拟一个 OS ,只是做了一个模仿。

这里与计组的“控制冲突”结合起来了,在跳转jal后要有nop无关指令用于 delay slot 。

接着,老师操作了 SPIM 。

示例二:阶乘(delay slot关闭)

如上,在模拟器中还是尊重了MIPS的规范,建立了一个栈帧。

如上,把栈顶的地址$sp向下拉了 32 。

MIPS32异常处理

关于同步异常需要自己看 ppt 了解。

异步异常(中断)

由“外部事件”引起,往往是外设触发。如:IO中断、Hard Reset、Soft Reset。

重新执行当前指令或者下一条指令。

异常处理向量(Vectors)

每类异常都有其编号以及异常处理入口地址,往往在内存中构成一张地址表。所以称之为向量。

精确异常处理(MIPS支持)

精确异常指的就是——在处理异常时,产生异常指令之前的指令都应执行完毕;该指令之后(包括该指令本身)的指令则都不处理。

需要精确记录异常的位置(指令) Branch Delay Slot 需要取消后续指令需要正确恢复执行

MIPS32的异常种类

MIPS异常处理基本过程

其实比较复杂,这里讲一个通用的情况。

保存现场——在异常程序入口,硬件只记录了被打断程序的很少量的信息,因此需要保留相关的控制寄存器等值使得异常处理程序能够执行(k0k1寄存器专门保留给异常处理使用);判断不同的异常——查询Cause寄存器,根据其不同的异常原因来进行不同的处理流程;构造异常处理内存空间——异常处理程序可能由高级语言书写,需要保留通用寄存器,构造堆\栈存储区(可选);处理异常——……返回——恢复寄存器,清零Cause寄存器,将Status寄存器的相关位置1以开中断。

异常返回

一般而言,异常处理代码工作在核心态,而被中断的程序是在用户态,所以异常返回意味着状态转换。

◦ 这个转换与指令返回必须“同时”完成,即用一条指令完成。

为什么?加入一个当前程序是工作在核心态,标识位核心态;如果先把核心态标识去掉,变成用户态;后面再执行核心态的 ERET 指令,这就非法了。

ERET指令:

返回EPC指向的地址:一般来说 EPC 或 EPC-4 是被中断的那个地址Status寄存器修改

中断

中断是异步发生的,是来自处理器外部的I/O设备的信号引发的。

硬件中断不是由任何一条专门的指令造成的:

I/O设备,比如网络适配器,磁盘控制器等通过处理器芯片上的一个引脚发送信号,并将中断号放到系统总线上,用来触发中断,这个异常号标识了引起中断的设备。

MIPS处理器的中断控制设计

在中断发生时,如果指令已经完成了 MEM 阶段的操作,则需保证该指令执行完毕。

反之,则丢弃这条指令的工作。

除 NMI 外,所有的内部或外部硬件中断(Hardware Interrupt)均共用这一个异常向量(Exception Vector)。

P84 嵌套异常比较复杂,不细讲。

SPIM模拟器支持的异常处理流程

SPIM实现了部分CP0寄存器。

异常中断后,如果能够正常返回之前的指令,那么返回的地址存储在 EPC 中。

Status寄存器

SPIM 实现了 Status 寄存器的部分功能。

Cause寄存器

用于记录发生异常的原因。

Branch 来决定返回的指令地址是 EPC 还是 EPC-4 。

异常处理实例

这节课也给大家留了一个作业,关于异常处理。

为什么不存储在栈上?

因为问题可能出现在栈上,因此现在不能相信栈。

为什么把 Cause 右移两位?见Cause寄存器结构。

老师用 SPIM 做了些演示。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。