本文已收录到:MIPS汇编语言学习笔记 专题
- MIPS汇编语言学习笔记03:print HelloWorld
- MIPS汇编语言学习笔记04:print character
- MIPS汇编语言学习笔记05:print integer
- MIPS汇编语言学习笔记06:print a float
- MIPS汇编语言学习笔记07:print a double
- MIPS汇编语言学习笔记08:Adding Integers
- MIPS汇编语言学习笔记09:Subtracting Integers
- MIPS汇编语言学习笔记10:Multiplying Integers (mul方法)
- MIPS汇编语言学习笔记11:Multiplying Integers (mult方法)
- MIPS汇编语言学习笔记12:Multiplying Integers sll
- MIPS汇编语言学习笔记13:Dividing Integers part 1
- MIPS汇编语言学习笔记14:Dividing Integers part 2
- MIPS汇编语言学习笔记15:Introduction to Functions
- MIPS汇编语言学习笔记16:Function Arguments and Return Values
- MIPS汇编语言学习笔记17:将寄存器保存到堆栈
- MIPS汇编语言学习笔记18:函数嵌套调用、递归
- MIPS汇编语言学习笔记19:获取用户输入的整数
- MIPS汇编语言学习笔记20:获取用户输入的单精度浮点数
- MIPS汇编语言学习笔记21:获取用户输入的双精度浮点数
- MIPS汇编语言学习笔记22:获取用户输入的文本
- MIPS汇编语言学习笔记23:if 语句分支指令
- MIPS汇编语言学习笔记26:MIPS While 循环
- MIPS汇编语言学习笔记27:数组
- MIPS汇编语言学习笔记28:使用While循环打印数组
- MIPS汇编语言学习笔记29:数组初始化
- MIPS汇编语言学习笔记30:浮点数(小数)运算
- MIPS汇编语言学习笔记32:浮点数 与 If 语句
在学习关于浮点数运算之前可以先复习下第06讲的打印浮点数。
在06讲打印浮点数中,用到了lwc1指令,它的作用与lw类似。作用是将某个内存地址中的值加载到寄存器中。只不过lw后面的c1指的是一号协处理器。
为什么是一号协处理器?MIPS CPU共有多少个协处理器?
在MIPS体系结构中,最多支持4个协处理器(Co-Processor)。其中,CP0用作系统控制,CP1和CP3用于FPU,CP2用于特点实现。CP0是必须具备的协处理器,其余三个协处理器是选配的。
0号协处理器(CP0)
他们的作用可以在MIPS官方《The MIPS32™ Privileged Resource Architecture》手册中的第《Coprocessor 0 Registers》章节可以看到.
标号 | 寄存器助记符/名称 | 功能描述 | 备注 |
0 | Index | TLB阵列的入口索引 | 与MMU、TLB有关 |
1 | Random | 产生TLB阵列的随机入口索引 | 与MMU、TLB有关 |
2 | EntryLo0 | 偶数虚拟页的入口地址的低位部分 | 与MMU、TLB有关 |
3 | EntryLo1 | 奇数虚拟页的入口地址的低位部分 | 与MMU、TLB有关 |
4 | Context | 指向内存虚拟页表入口地址的指针 | 与MMU、TLB有关 |
5 | PageMask | 控制TLB入口中可变页面的大小 | 与MMU、TLB有关 |
6 | Wired | 控制固定的TLB入口的数目 | 与MMU、TLB有关 |
7 | 保留 | ||
8 | BadVAddr | 记录最近一次地址相关异常的地址 | |
9 | Count | 处理器记数周期 | |
10 | EntryHi | TLB入口地址的高位部分 | 与MMU、TLB有关 |
11 | Compare | 定时中断控制 | |
12 | Status | 处理器状态和控制寄存器 | |
13 | Cause | 保存上一次异常原因 | |
14 | EPC | 保存上一次异常时的程序计数器 | |
15 | PRId | 处理器标志和版本 | |
16 | Config | 配置寄存器,用来设置CPU的参数 | |
17 | LLAddr | 加载链接指令要加载的数据存储器地址 | |
18 | WatchLo | 观测点watchpoint地址的低位部分 | 与调试有关 |
19 | WatchHi | 观测点watchpoint地址的高位部分 | 与调试有关 |
20 | 保留 | ||
21 | 保留 | ||
22 | 保留 | ||
23 | Debug | 调试控制和异常状况 | 与调试有关 |
24 | DEPC | 上一次调试异常的程序计数器 | 与调试有关 |
25 | 保留 | ||
26 | ErrCtl | 控制Cache指令访问数据和SPRAM | 与Cache有关 |
27 | 保留 | ||
28 | TagLo/DataLo | Cache中Tag接口的低位部分 | 与Cache有关 |
29 | 保留 | ||
30 | ErrorEPC | 上一次系统错误时的程序计数器 | |
31 | DESAVE | 用于调试处理的暂停寄存器 | 与调试有关 |
MARS软件中列出了比较常用的寄存器:
1号协处理器(CP1)
用于FPU,共有32个寄存器可供使用,自行分配。
2号协处理器(CP2)
暂不研究,MARS中没有实现。
3号协处理器(CP3)
FPU,自行分配使用。MARS中没有实现。
浮点数加载到CP1中
下面的代码就可以分别将位于内存中的 number1和 number2 加载到浮点寄存器:
.data number1: .float 2.5 number2: .float 3.5 .text main: lwc1 $f1, number1 lwc1 $f2, number2
关于浮点数的存储,为什么 2.5 存为 0x40200000,请参考:MIPS汇编语言学习笔记06:print a float 这边文章中的视频,里面对计算机浮点数的存储有了详细的讲解。具体是依据IEEE754标准。
浮点数运算
.data number1: .float 3.6 number2: .float 3.5 .text main: lwc1 $f1, number1 lwc1 $f2, number2 # 浮点数相加 add.s $f3, $f1, $f2 # 浮点数相减 sub.s $f4, $f1, $f2 # 浮点数相乘 mul.s $f5, $f1, $f2 # 浮点数相除 div.s $f6, $f1, $f2
将寄存器中的值使用 浮点数转换小工具:https://lostphp.com/hexconvert/ 转换后得到十进制数值。从下面的结果中我们也可以看到,计算机中使用二进制保存浮点数是一定会存在精度问题的。也就是说,计算机中对浮点数的存储都是不精确的,只不过这种精度足够我们业务使用就OK了。
更多浮点数运算指令
可参考这篇文章中提供的MIPS指令手册:MIPS汇编语言学习笔记03:print HelloWorld
参考文献:https://www.cs.cornell.edu/courses/cs3410/2008fa/MIPS_Vol3.pdf