1. MIPS指令集的限制
o 所有的指令长度都是32位 o 指令操作必须适合流水线 o 三操作数的指令 o 32个寄存器
o 寄存器零(?作用)
o 没有条件码(很强大)?没有标志位,但是所有信息保存在寄存器堆中
2. 寻址和访存
o 访问内存只能通过简单的寄存器加载和存储(对内存变量进行算术运算会打乱流水线)
o 只有一种数据寻址方式(单个寄存器基址加上一个16位的常数偏移量寻址内存) o 字节地址访问(?) o load/store必须对齐
o 跳转指令(有228=256MB的地址空间)(超过的可以使用一个寄存器跳转指令做到,可以跳到任意32位地址)(条件分支只有128KB的范围)
3. MIPS的特性
o 没有字节或半字数据的运算:所有的算术和逻辑操作都在32位的数据上进行。(int类型32位的整数)
o 没有对堆栈的特殊支持(堆栈弹出不能适应流水线(因为有两个寄存器要写:来自堆栈的数据和增加指针值))
o 最少的子程序支持(?很大的好处?(返回地址存入$31(返回地址寄存器))) o 最少的中断处理
o 最少的异常处理(保留了两个寄存器给用于异常,这样异常处理程序可以自举?)
MIPS架构中的PC(程序计数)
MIPS架构中没有X86中的PC(程序计数)寄存器,它的程序计数器不是一个寄存器。因为在MIPS这样具有流水线结构的CPU中,程序计数器在同一时刻可以有多个给定的值,如jal指令的返回地址跟随其后的第二条指令。 ...
jal printf move $4, $6
xxx # return here after call
1 / 6
MIPS32中也没有条件码,比如在X86中常见的状态寄存器中的Z、C标志位在MIPS32中是没有的,但是MIPS32中是有状态寄存器
MIPS32中整数乘法部件
MIPS32中不同于其它的RISC架构的地方是其有 整数乘法部件 ,这个部件使用两个特殊的寄存器HI、LO,并且提供相应的指令 mfhi/mthi,mthi/mtlo来实现整数乘法结果--hi/lo寄存器与通用寄存器之间的数据交换
CP0 (协处理器0)--MIPS处理器控制
MIPS支持最多4个协处理器。协处理器CP0为CPU的控制协处理器,是体系结构中必须实现的。CP1为浮点处理器。CP2保留,各生产厂商往往用来实 现一些自己的特色功能,例如RMI的Fast Message Ring等。CP3原本也是保留共扩展用,但很多MIPS III和MIPS IV时代的扩展指令集使用了它。为适应处理器向多核时代的演进,MIPS引入了多核操作必要的原子指令(Atomic operation)、内存屏障(Barrier)等操作。在SMP或AMP等多核架构中,这些指令是并行计算同步的保障。
CP0用于控制和设置MIPS CPU,里面包含了一些寄存器,同过对这些寄存器的不同的位的操作可以实现对处理器的设置。CP0类似于X 86只能有内核 (高优先级权限)访问的一些处理器资源,而提到的通用寄存器GPR和FPR则可以有由所有的优先级权限访问。CP0提供了 中断异常处理、内存管理(包括CACHE、TLB)、外设管理 等途径(而这些只能由高优先级的内核才能访问到)。
起作用的寄存器及其作用:加电后,你需要设置SR和Config寄存器,以确保CPU进入正确的引导状态,并且SR寄存器还设置了中断码。以决定系统响应哪些中断。
进入任何异常:处理任何例外都会调用一个“通用异常处理程序”。MIPS体系并没有为进入异常作任何的寄存器保存,也没有关于堆栈方面的任何支持,进入异 常时唯一保存的就是异常返回地址保存在EPC中。所以这些都需要操作系统的软件实现。操作系统可以使用K0或者K1寄存器作为堆栈指针,指向某个位置,并 且在需要保存的寄存器保存到这个栈上。然后通过Cause寄存器找到发生异常的原因,这样才能跳转到对应的中断处理程序中。从异常返回:从异常返回到 EPC制定的地址之前要把CPU的状态回复到异常之前,好象什么事情都没有发生一样。在R3000中使用rfe指令作这样的事情,但是着条指令仅仅恢复了 一些寄存器中的内容,但是并没有转移控制指令,你需要把EPC内容保存到一个通用寄存器中,然后调用jr指令返回到EPC指向的地址处,
数据加载与存储
2 / 6
MIPS CPU可以在一个单一操作中存储1到8个字节。文档中和用来组成指令助记符的 命名约定如下: C名字
大小(字
MIPS名字
节)
汇编助记符
-----------+----------+--------+--------- long long int/long short char
•
dword 8 word
4
\"d\"代表ld \"w\"代表lw \"h\"代表lh \"b\"代表lb
halfword 2 byte
1
数据加载
包括这样几条记载指令lb/lbu、lh/lhu、lw
byte和short的加载有两种方式。带符号扩展的lb和lh指令将数据值存放在
32位寄存器的低位中,剩下的高位用符号位的值来扩充(位7如果是一个byte,位15如果是一 个short)。这样就正确地将一个带符号整数放入一个32位的带符号的寄存器中。
不带符号指令lbu和lhu用0来扩充数据,将数据存放纵32位寄存器的低位中,并将高位用零来填充。例如,如果一个byte字节宽度的存储器地址为 t1,其值为0xFE(-2或254如果是非符号数),那么将会在t2中放入0xFFFFFFFE(-2作为一个符号数)。t3的值会是 0x000000FE(254作为一个非符号数) lb t2, 0(t1) lbu t3, 0(t1)
•
数据存储
包括这样几条指令sb、sh、sw
由于加载就是把寄存器中的数据加载到内存中,所以不存在位扩展的问题。
MIPS的存储管理模型
MIPS32中的存储器模型被划分为四个大块,其中: 虚拟地址范围
3 / 6
命
描述 名
------------------------------------+-------+-------------------------------------------------------------------------------------
0x0000,0000~0x7fff,ffff(0~2G-1)
0x8000,0000~0x9fff,ffff(2G~2.5G-1)
0xa000,0000~0xbfff,ffff(2.5G~3G-1)
4 / 6
must be mapped (set page tablUSe and EG TLB)and set cache before use directly mapped(no need to set page KStablEGe and 0 TLB) but need to set cache before use KSdireEGctly 1 mapp
ed(no need to set page table and TLB) and never use cache muse be mapped(set page tablKS
e and EG
TLB) 2 and set cache before use
0xc000,0000~0xffff,ffff(3G~4G-1)
这样的存储器管理模型和X86差距比较大,X86有一个实模式,内核在启动保护模式之前,运行在实模式之下,直到设定了保护模式之后才能运行在保护模式下。在MIPS32中没有保护模式那么系统是如何启动的呢?
MIPS32中的 处理器启动向量 位于KSEG1中0xbf10,0000,由于KSEG1是
directly mapped的,所以直接对应了物理地址0x1fc0,0000,你可以在内核中一直使用0xa000,0000~0xbfff,ffff之间的虚拟地址 来访问物理地址0~512M-1,在设置了KSEG0的cache之后,也可一使用0x8000,0000~0x9fff,ffff之间的虚拟地址来访问 0~512M-1之间的物理地址。对于512M以上的物理地址只能由KSEG2和USEG通过页表访问。 x86的处理器启动向量为0xffff,fff0 ARM的处理器启动向量为
5 / 6
MIPS32的C语言中参数传递和返回值的约定
caller至少使用16bytes 堆栈空间存放参数,然后把这16 bytes存放到通用寄存器a0~a3中, called subroutine 直接使用寄存器中的参数,同时caller 堆栈中的16bytes的数据可以不去理会了。
需要理解的是带有浮点参数和结构体的参数传递,对于带有浮点参数的传递需要看第一个参数是否是浮点,如果是浮点则将参数放到 \\(f12和\\)f14这两个浮点寄存器中,如果第一个参数不是浮点数,则不用浮点寄存器存放参数。对于结构体的参数传递和x86类似对于整数和指针类型 的
[文档可能无法思考全面,请浏览后下载,另外祝您生活愉快,工作顺利,万事如意!]
6 / 6
因篇幅问题不能全部显示,请点此查看更多更全内容