MIPS-1

合集下载
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

在中高档服务器中采用RISC 指令的CPU 主要有Compaq (康柏,即新惠普)公司的Alpha 、HP 公司的PA-RISC 、IBM 公司的Power PC 、MIPS 公司的MIPS 和SUN 公司的Spare 。

MIPS汇编:
汇编语言是CPU二进制指令的可读写版本。

大多数MIPS汇编语言都是非常古板的,都是一些寄存器号码。

但是工具链(toolchains)可以使得使用微处理机语言变得简单。

工具链至少允许程序员引用一些助记符,而严格的汇编语言要求严格的数字编码。

大多我们都是用比较熟悉的C预处理器。

C预处理器会把C风格的注解去掉,而得到一个可用的汇编代码。

有C预处理器的帮助,MIPS汇编程序都是用助记符来表示寄存器。

助记符同时也代表了每个寄存器的用法
对於熟悉汇编语言但不熟悉MIPS的读者,下面是一些例子。

/* this is a comment */
#so is this
entrypoint: #this''s a label
addu $1, $2, $3 # (registers) $1 = $2 + $3
与大多数汇编语言一样,MIPS汇编语言也是以行为单位的。

每一行的结束是一个指令的结束,并且忽略任何“#”之后的内容,认为是注释。

在一行里可以有多条指令。

指令之间要用分号“;”隔开。

一个符号(label)是一个后面跟着冒号“:”的字。

符号可以是任何字符串的组合。

符号被用来定义一段代码的入口和定义数据段的一个存储位置。

如上所示,许多指令都是3个操作数/符(operand)。

目标寄存器在左侧(注意,这一点与Inetel x86 正相反)。

一般而言,寄存器结果和操作符的顺序与C语言或
其他符号语言的方式是一致的。

例如:
subc $1, $2, $3
意味着:
$1 = $2 - $3;
这方面我们就先讲这么多。

对於一个程序,可以有32个通用寄存器,分别为:$0-$31。

其中,两个,也只有两个的使用不同于其他。

$0:不管你存放什么值,其返回值永远是零。

$31:永远存放着正常函数调用指令(jal)的返回地址。

请注意call-by-registe的jalr 指令可以使用任何寄存器来存放其返回地址。

当然,如不用$31,看起来程序会有点古怪。

其他方面,所有的寄存器都是一样的。

可以被用在任何一个指令中(你也可以用$0作为一个指令的目标寄存器。

当然不管你存入什么数据,数据都消失了。

)
MIPS体系结构下,程序计数器不是一个寄存器,其实你最好不要去那样想。

在一个具有流水线的CPU中,程序计数器的值在一个给定的时刻有多个可选值。

这一点有点迷惑人。

jal指令的返回地址跟随其后的第二条指令。

..
jal printf
move $4, $6
xxx # return here after call
上述的解释是有道理的,因为紧跟踪jal指令后面的指令,由於在delay slot(延迟位置)上--请记住,关于延迟位置的规则是该指令将在转移目标(如上述的printf)之前执行。

延迟位置指令经常被用来传递函数调用的参数。

MIPS里没有状态码。

CPU状态寄存器或内部都不包含任何用户程序计算的结果状态信息。

hi和lo是与乘法运算器相关的两个寄存器大小的用来存放结果的地方。

它们并不是通用寄存器,除了用在乘除法之外,也不能有做其他用途。

但是,MIPS里定义了一些指令可以往hi和lo里存入任何值。

想一想我们会发现,这是非常有必要的当你想要恢复一个被打断的程序时。

浮点运算协处理器(浮点加速器,FPA),如果存在的话,有32个浮点寄存器。

按汇编语言的简单约定讲,是从$f0到$31。

实际上,对於MIPS I和MIPS II的机器,只有16个偶数号的寄存器可以用来做数学计算。

当然,它们可以既用来做单精度(32位)和双精度(64位)。

当你做一个双精度的运算时,寄存器$f1存放$f0的余数。

奇数号的寄存器只用来作为寄存器与FPA之间的
数据传送。

MIPS III CPU有32个FP寄存器。

但是为了保持软件与过去的兼容性,最好不要用奇
数号的寄存器。

助记符与通用寄存器的用法
我们已经描述了一些体系结构方面的内容,下面来介绍一些软件方面的内容。

寄存器编号助记符用法
0 zero 永远返回值为0
1 at 用做汇编器的暂时变量
2-3 v0, v1 子函数调用返回结果
4-7 a0-a3 子函数调用的参数
8-15 t0-t7 暂时变量,子函数使用时不需要保存与恢复
24-25 t8-t9
16-25 s0-s7 子函数寄存器变量。

子函数必须保存和恢复使用过的变量在函数返回之前,从而调用函数知道这些寄存器的值没有变化。

26,27 k0,k1 通常被中断或异常处理程序使用作为保存一些系统参数
28 gp 全局指针。

一些运行系统维护这个指针来更方便的存取“static“和”extern" 变量。

29 sp 堆栈指针
30 s8/fp 第9个寄存器变量。

子函数可以用来做桢指针
31 ra 子函数的返回地□
''7d
虽然硬件没有强制性的指定寄存器使用规则,在实际使用中,这些寄存器的用法都遵循一系列约定。

这些约定与硬件确实无关,但如果你想使用别人的代码,编译器和操作系统,你最好是遵循这些约定。

寄存器约定用法引人了一系列的寄存器约定名。

在使用寄存器的时候,要尽量用这些约定名或助记符,而不直接引用寄存器编号。

1996年左右,SGI开始在其提供的编译器中使用新的寄存器约定。

这种新约定可以用来建立使用32位地址或64位地址的程序,分别叫"n32"和"n64"。

我们暂时不讨论这些,将会在第10章详细讨论。

寄存器名约定与使用
*at: 这个寄存器被汇编的一些合成指令使用。

如果你要显示的使用这个寄存器(比如在异常处理程序中保存和恢复寄存器),有一个汇编directive可被用来禁止汇编器在directive之后再使用at寄存器(但是汇编的一些宏指令将因此不能再可用)。

*v0, v1: 用来存放一个子程序(函数)的非浮点运算的结果或返回值。

如果这两个寄存器不够存放需要返回的值,编译器将会通过内存来完成。

详细细节可见10.1节。

*a0-a3: 用来传递子函数调用时前4个非浮点参数。

在有些情况下,这是不对的。

请参10.1细节。

* t0-t9: 依照约定,一个子函数可以不用保存并随便的使用这些寄存器。

在作表达式计算时,这些寄存器是非常好的暂时变量。

编译器/程序员必须注意的是,当调用一个子函数时,这些寄存器中的值有可能被子函数破坏掉。

*s0-s8: 依照约定,子函数必须保证当函数返回时这些寄存器的内容必须恢复到函数调用以前的值,或者在子函数里不用这些寄存器或把它们保存在堆栈上并在函数退出时恢复。

这种约定使得这些寄存器非常适合作为寄存器变量或存放
一些在函数
调用期间必须保存原来值。

* k0, k1: 被OS的异常或中断处理程序使用。

被使用后将不会恢复原来的值。

因此它们很少在别的地方被使用。

* gp: 如果存在一个全局指针,它将指向运行时决定的,你的静态数据(static data)区域的一个位置。

这意味着,利用gp作基指针,在gp指针32K左右的数据存取,系统只需要一条指令就可完成。

如果没有全局指针,存取一个静态数据区域的值需要两条指令:一条是获取有编译器和loader决定好的32位的地址常量。

另外一条是对数据的真正存取。

为了使用gp, 编译器在编译时刻必须知道一个数据是否在gp的64K范围之内。

通常这是不可能的,只能靠猜测。

一般的做法是把small global data (小的全局数据)放在gp覆盖的范围内(比如一个变量是8字节或更小),并且让linker报警如果小的全局数据仍然太大从而超过gp作为一个基指针所能存取的范围。

并不是所有的编译和运行系统支持gp的使用。

*sp: 堆栈指针的上下需要显示的通过指令来实现。

因此MIPS通常只在子函数进入和退出的时刻才调整堆栈的指针。

这通过被调用的子函数来实现。

sp通常被调整到这个被调用的子函数需要的堆栈的最低的地方,从而编译器可以通过相对於sp的偏移量来存取堆栈上的堆栈变量。

详细可参阅10.1节堆栈使用。

* fp: fp的另外的约定名是s8。

如果子函数想要在运行时动态扩展堆栈大小,fp 作为桢指针可以被子函数用来记录堆栈的情况。

一些编程语言显示的支持这一点。

汇编编程员经常会利用fp的这个用法。

C语言的库函数alloca()就是利用了fp来动态调整堆栈的。

如果堆栈的底部在编译时刻不能被决定,你就不能通过sp来存取堆栈变量,因此fp被初始化为一个相对与该函数堆栈的一个常量的位置。

这种用法对其他函数是不可见的。

* ra: 当调用任何一个子函数时,返回地址存放在ra寄存器中,因此通常一个子程序的最后一个指令是jr ra.
子函数如果还要调用其他的子函数,必须保存ra的值,通常通过堆栈。

MIPS简述:
Million Instructions Per Second的缩写,每秒处理的百万级的机器语言指令数。

这是衡量CPU速度的一个指标。

像是一个Intel 80386 电脑可以每秒处理3百万到5百万机器语言指令,既我们可以说80386是3到5MIPS的CPU。

MIPS只是衡量CPU性能的指标。

MIPS技术公司是一家设计制造高性能、高档次及嵌入式32位和64位处理器的厂商,在RISC处理器方面占有重要地位。

1984年,MIPS计算机公司成立。

1992年,SGI收购了MIPS计算机公司。

1998年,MIPS脱离SGI,成为MIPS技术公司。

MIPS公司设计RISC处理器始于二十世纪八十年代初,1986年推出R2000处理器,1988年推R3000处理器,1991年推出第一款64位商用微处器R4000。

之后又陆续推出R8000(于1994年)、R10000(于1996年)和R12000(于1997年)等型号。

随后,MIPS公司的战略发生变化,把重点放在嵌入式系统。

1999年,MIPS公司发布MIPS32和MIPS64架构标准,为未来MIPS处理器的开发奠定了基础。

新的架构集成了所有原来NIPS指令集,并且增加了许多更强大的功能。

MIPS公司陆续开发了高性能、低功耗的32位处理器内核(core)MIPS324Kc 与高性能64位处理器内核MIPS64 5Kc。

2000年,MIPS公司发布了针对MIPS32 4Kc的版本以及64位MIPS 64 20Kc处理器内核。

MIPS是世界上很流行的一种RISC处理器。

MIPS的意思是“无内部互锁流水级的微处理器”(Microprocessor without interlocked piped stages),其机制是尽量利用软件办法避免流水线中的数据相关问题。

它最早是在80年代初期由斯坦福(Stanford)大学Hennessy教授领导的研究小组研制出来的。

MIPS公司的R 系列就是在此基础上开发的RISC工业产品的微处理器。

这些系列产品为很多计算机公司采用构成各种工作站和计算机系统。

MIPS技术公司是美国著名的芯片设计公司,它采用精简指令系统计算结构(RISC)来设计芯片。

和英特尔采用的复杂指令系统计算结构(CISC)相比,RISC 具有设计更简单、设计周期更短等优点,并可以应用更多先进的技术,开发更快的下一代处理器。

MIPS是出现最早的商业RISC架构芯片之一,新的架构集成了所有原来MIPS指令集,并增加了许多更强大的功能。

1986年推出R2000处理器,1988年推出R3000处理器,1991年推出第一款64位商用微处理器R4000。

之后,又陆续推出R8000(于1994年)、R10000(于1996年)和R12000(于1997年)等型号。

1999年,MIPS公司发布MIPS 32和MIPS 64架构标准。

2000年,MIPS公司发布了针对MIPS 32 4Kc的新版本以及未来64位MIPS 64 20Kc处理器内核。

在MIPS芯片的发展过程中,SGI公司在1992年收购了MIPS计算机公司,1998年,MIPS公司又脱离了SGI,成为MIPS技术公司; MIPS32 4KcTM 处理器是采用MIPS技术特定为片上系统(System-On-a-Chip)而设计的高性能、低电压32位MIPS RISC 内核。

采用MIPS32TM体系结构,并且具有R4000存储器管理单元(MMU)以及扩展的优先级模式,使得这个处理器与目前嵌入式领域广泛应用的R3000和R4000系列(32位)微处理器完全兼容。

新的64 位MIPS 处理器是RM9000x2,从“x2”这个标记判断,它包含了不是一个而是两个均具有集成二级高速缓存的64位处理器。

RM9000x2 主要针对网络基础设施市场,具有集成的DDR 内存控制器和超高速的HyperTransport I/O 链接。

处理器、内存和I/O均通过分组交叉连接起来的,可实现高性能、全面高速缓存的统一芯片系统。

除通过并行处理提高系统性能外,RM9000x2 还通过将超标量与超流水线技术相结合来提高单个处理器的性能。

64位处理器MIPS 64 20Kc的浮点能力强,可以组成不同的系统,从一个处理器的Octane工作站到64个处理器的Origin 2000服务器;这种CPU更适合图形工作站使用。

MIPS最新的R12000芯片已经在SGI的服务器中得到应用,目前其主频最大可达400MHz。

MIPS处理器是八十年代中期RISC CPU设计的一大热点。

MIPS是卖的最好的RISC CPU,可以从任何地方,如Sony,Nintendo的游戏机,Cisco的路由器和SGI超级计算机,看见MIPS产品在销售。

目前随着RISC体系结构遭到x86芯片的竞争,MIPS有可能是起初RISC CPU设计中唯一的一个在本世纪盈利的。

和英特尔相比,MIPS的授权费用比较低,也就为除英特尔外的大多数芯片厂商所采用。

MIPS的系统结构及设计理念比较先进,其指令系统经过通用处理器指令体系MIPS I、MIPS II、MIPS III、MIPS IV到MIPS V,嵌入式指令体系MIPS16、MIPS32到MIPS64的发展已经十分成熟。

在设计理念上MIPS强调软硬件协同
提高性能,同时简化硬件设计。

MIPS是世界上很流行的一种RISC处理器。

MIPS的意思是“无内部互锁流水级的微处理器”(Microprocessor without interlocked piped stages),其机制是尽量利用软件办法避免流水线中的数据相关问题。

它最早是在80年代初期由斯坦福(Stanford)大学Hennessy教授领导的研究小组研制出来的。

MIPS公司的R系列就是在此基础上开发的RISC工业产品的微处理器。

这些系列产品为很多计算机公司采用构成各种工作站和计算机系统。

MIPS技术公司是美国著名的芯片设计公司,它采用精简指令系统计算结构(RISC)来设计芯片。

和英特尔采用的复杂指令系统计算结构(CISC)相比,RISC 具有设计更简单、设计周期更短等优点,并可以应用更多先进的技术,开发更快的下一代处理器。

MIPS是出现最早的商业RISC架构芯片之一,新的架构集成了所有原来MIPS指令集,并增加了许多更强大的功能。

新的64 位MIPS 处理器是RM9000x2,从“x2”这个标记判断,它包含了不是一个而是两个均具有集成二级高速缓存的64位处理器。

RM9000x2 主要针对网络基础设施市场,具有集成的DDR 内存控制器和超高速的HyperTransport I/O 链接。

处理器、内存和I/O均通过分组交叉连接起来的,可实现高性能、全面高速缓存的统一芯片系统。

除通过并行处理提高系统性能外,RM9000x2 还通过将超标量与超流水线技术相结合来提高单个处理器的性能。

64位处理器MIPS 64 20Kc的浮点能力强,可以组成不同的系统,从一个处理器的Octane工作站到64个处理器的Origin 2000服务器;这种CPU更适合图形工作站使用。

MIPS最新的R12000芯片已经在SGI的服务器中得到应用,目前其主频最大可达400MHz。

中国龙芯2和前代产品采用的都是64位MIPS指令架构,它与大家平常所知道的X86指令架构互不兼容,MIPS指令架构由MIPS公司所创,属于RISC 体系。

过去,MIPS架构的产品多见于工作站领域,索尼PS2游戏机所用的“Emotion Engine”也采用MIPS指令,这些MIPS处理器的性能都非常强劲,而龙芯2也属于这个阵营,在软件方面与上述产品完全兼容。

作者点评:MIPS技术公司则是一家设计制造高性能、高档次及嵌入式32位和64位处理器的厂商。

在通用方面,MIPS R系列微处理器用于构建SGI的高性能工作站、服务器和超级计算机系统。

在嵌入式方面,MIPS K系列微处理
器是目前仅次于ARM的用得最多的处理器之一(1999年以前MIPS是世界上用得最多的处理器),其应用领域覆盖游戏机、路由器、激光打印机、掌上电脑等各个方面。

由于服务器RISC处理器市场的激烈竞争结果导致HP 公司放弃它的PA-RISC和“私生子”Alpha 两种类型服务器处理器,而“Alpha技术”则被Intel 和AMD吸收应用到他们自身的处理器中;MIPS处理器应用范围则较广,对于作为服务器RISC处理器来说,主要是应用于专门的图形工作站/服务器上;相对来说,应用面较专业,因而竞争较少。

就目前的服务器RISC处理器来说,主要是IBM 的POWER和SUN 的UltraSPARC 两大处理器之间的竞争;相对而言,IBM在这场RISC处理器竞争中是个大赢家。

UltraSPARC处理器是Sun的命脉,以UltraSPARC为基础的Unix服务器曾为Sun 带进大量营收,不过,经过.com 泡沫化的冲击,加上Unix服务器市场渐趋平稳,在营收下滑之际,UltraSPARC庞大的研发费用转为Sun 沉重的负担。

面对自己的良机顿挫,Sun近来连续宣布UltraSPARC新策略,大幅改变UltraSPARC产品计划(roadmap),以改变目前的不利局势。

例如取消了UltraSparc V与Gemini处理器,而将资源重点转向代号为Niagara 与Rock的高吞吐量计算处理器。

并且Sun和富士通计划在2006年之前将它们基于Sparc处理器的服务器产品合并在一起,共同来对付他们的竞争对手IBM;到底鹿死谁手,人们正拭目以待。

MIPS架构:
MIPS体系结构首先是一种RISC架构
1 MIPS32架构中有32个通用寄存器,其中$0(无论你怎么设置,这个寄存器中保存的数据都是0)和$31(保存函数调用jal的返回地址)有着特殊的用途,其它的寄存器可作为通用寄存器用于任何一条指令中。

虽然硬件没有强制性的指定寄存器使用规则,在实际使用中,这些寄存器的用法都遵循一系列约定。

这些约定与硬件确实无关,但如果你想使用别人的代码,编译器和操作系统,你最好是遵循这些约定。

寄存器编号助记符用法
0 zero 永远返回值为0
1 at 用做汇编器的暂时变量
2-3 v0, v1 子函数调用返回结果
4-7 a0-a3 子函数调用的参数
8-15 t0-t7
24-25 t8-t9 暂时变量,子函数使用时不需要保存与恢复
16-25 s0-s7 子函数寄存器变量。

子函数必须保存和恢复使用过的变量在函数返回之前,从而调用函数知道这些寄存器的值没有变化。

26,27 k0,k1 通常被中断或异常处理程序使用作为保存一些系统参数
28 gp 全局指针。

一些运行系统维护这个指针来更方便的存取“static“和”extern" 变量。

29 sp 堆栈指针
30 s8/fp 第9个寄存器变量。

子函数可以用来做桢指针
31 ra 子函数的返回地
2 MIPS32中如果有FPA(浮点协处理器),将会有32个浮点寄存器,按汇编语言的约定为$f0~$f31,MIPS32中只能实用偶数号的浮点寄存器,奇数号的用途是:在做双精度的浮点运算时,存放该奇数号之前的偶数号浮点寄存器的剩余无法放下的32位。

比如在做双精度的浮点运算时,$1存放$0的剩余的部分,所以在MIPS32中可以通过加载偶数号的浮点寄存器而把64位的双精度数据加载到两个浮点寄存器中,每个寄存器存放32位。

比如:
l.d $02, 24(t1)
被扩充为两个连续的寄存器加载:
lwc1 $f0, 24(t1)
lwc1 $f1, 28(t1)
3 MIPS架构中没有X86中的PC(程序计数)寄存器,它的程序计数器不是一个寄存器。

因为在MIPS这样具有流水线结构的CPU中,程序计数器在同一时刻可以有多个给定的值,如jal指令的返回地址跟随其后的第二条指令。

...
jal printf
move $4, $6
xxx # return here after call
MIPS32中也没有条件码,比如在X86中常见的状态寄存器中的Z、C标志位在
MIPS32中是没有的,但是MIPS32中是有状态寄存器
4 MIPS32中不同于其它的RISC架构的地方是其有整数乘法部件,这个部件使用两个特殊的寄存器HI、LO,并且提供相应的指令mfhi/mthi,mthi/mtlo来实现整数乘法结果--hi/lo寄存器与通用寄存器之间的数据交换
5 数据加载与存储.MIPS CPU可以在一个单一操作中存储1到8个字节。

文档中和用来组成指令助记符的命名约定如下:
C名字MIPS名字大小(字节) 汇编助记符
long long dword 8 "d"代表ld
int/long word 4 "w"代表lw
short halfword 2 "h"代表lh
char byte 1 "b"代表lb
5.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)
5.2数据存储.包括这样几条指令SB、SH、SW
由于加载就是把寄存器中的数据加载到内存中,所以不存在位扩展的问题。

6 CP0 (协处理器0)--MIPS处理器控制.用于控制和设置MIPS CPU,里面包含了一些寄存器,同过对这些寄存器的不同的位的操作可以实现对处理器的设置
CP0类似于X 86只能有内核(高优先级权限)访问的一些处理器资源,而前面提到的通用寄存器GPR和FPR则可以有由所有的优先级权限访问CP0提供了中
断异常处理、内存管理(包括CACHE、TLB)、外设管理等途径(而这些只能由高优先级的内核才能访问到)。

6.1常见的MIPS CPU控制寄存器包括:
SR( 状态寄存器) 12
Config (CPU参数设置寄存器)-16
EPC (例外程序寄存器)13、CAUSE(导致中断和异常的原因寄存器) 14、BadVaddr(地址错误时存放地址的寄存器)8
Index-0、Random-1、EntryLo0-2、EntryLo1-3、EntryHi-10、PageMask
Count-9、Compare-11共同组成了高精度的时钟
6.2CP0寄存器的访问指令
mtc0 ts, #把通用寄存器ts中的数据送到协处理器0中的寄存器nn
mfc0 ts, #把送到协处理器0中寄存器nn 的值送到通用寄存器ts
dmtc0 ts, #把通用寄存器ts中的数据送到协处理器0中的寄存器nn
dmfc0 ts, #把送到协处理器0中寄存器nn 的值送到通用寄存器ts
6.3起作用的寄存器及其作用时机
加电后:你需要设置SR和Config寄存器,以确保CPU进入正确的引导状态,并且SR寄存器还设置了中断码。

以决定系统响应哪些中断。

进入任何异常:处理任何例外都会调用一个“通用异常处理程序”。

MIPS体系并没有为进入异常作任何的寄存器保存,也没有关于堆栈方面的任何支持,进入异常时唯一保存的就是异常返回地址保存在EPC中。

所以这些都需要操作系统的软件实现。

操作系统可以使用K0或者K1寄存器作为堆栈指针,指向某个位置,并且在需要保存的寄存器保存到这个栈上。

然后通过Cause寄存器找到发生异常的原因,这样才能跳转到对应的中断处理程序中。

从异常返回:从异常返回到EPC制定的地址之前要把CPU的状态回复到异常之前,好象什么事情都没有发生一样。

在R3000中使用rfe指令作这样的事情,但是着条指令仅仅恢复了一些寄存器中的内容,但是并没有转移控制指令,你需要把EPC内容保存到一个通用寄存器中,然后调用jr指令返回到EPC指向的地址处,
7 MIPS的存储管理模型.MIPS32中的存储器模型被划分为四个大块,其中:
0x0000,0000~0x7fff,ffff(0~2G-1) USEG
must be mapped (set page table and TLB)and set cache before use
0x8000,0000~0x9fff,ffff(2G~2.5G-1) KSEG0
directly mapped(no need to set page table and TLB) but need to set cache before use
0xa000,0000~0xbfff,ffff(2.5G~3G-1) KSEG1
directly mapped(no need to set page table and TLB) and never use cache
0xc000,0000~0xffff,ffff(3G~4G-1) KSEG2
muse be mapped(set page table and TLB) and set cache before use
这样的存储器管理模型和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通过页表访问。

8 MIPS32中的状态寄存器SR.状态寄存器来设置处理器的一些功能集合,包括设置协处理器0~3的可用性的位CU0~CU3(28~31)
复位向量BEV
中断屏蔽位8~15
KUc、IEc0~1,基本的CPU保护单位
KUc为1时表示运行在内核态,为0时运行在用户模式。

在内核态下,可以访问所有的地址空间和协处理器0,运行在用户态下值只能访问0x0000,0000~0x7fff,ffff之间的地址空间。

KUp、IEp2~3
当异常发生时,硬件把KUc、IEc的值保存到KUp、IEp中,并且将KUc、IEc 设置为[1,0]--内核态、关中断。

异常返回时rfe指令可以把KUp、IEp的内容复制到KUc、IEc中
KUo、IEo
当异常发生时,硬件把KUp、IEp的值保存到KUo、IEo中;返回时把KUo、IEo 的内容复制到KUp、IEp中。

相关文档
最新文档