205-MIPS 体系结构
# 205-MIPS 体系结构
MIPS 是精简指令系统的代表,采用了与 X86 相反的设计理念,并引领了精简指令系统的潮流,那就让我们一起来看一看这 究竟是怎么一回事。
要探讨 MIPS 指令系统,就得从它的设计者 John Hennessy 开始说起。 Hennessy 1977 年进入斯坦福大学, 1981 年领导了 RISC 微处理器研究小组,他也被称为 RISC 的先驱。 RISC 是精简指令系统计算机的简称,与之相对,之前的计算机上的指令系统就被称为复杂指令系统,X86 就是其中的代表。 后来,Hennessy 共同创立了 MIPS 计算机系统公司, 90 年代,他主要是在斯坦福计算机系担任系主任等职务, 2000 年起开始担任斯坦福大学的校长。
由于他所设计的 MIPS 体系结构引领了精简指令系统的潮流, 后来还获得了 IEEE 的荣誉奖章, 而他所创立的 MIPS 公司也一度创造了辉煌。 在 80 年代末上市,后来被收购, 然后再一次上市,再一次被收购, 现在 MIPS 处理器已经不再应用在计算机产品中了, 但是在广义的计算设备包括数字电视,游戏机,网络设备等领域仍然有广泛的应用,其实 MIPS 公司商业上的兴衰 也是诸多 RISC 微处理器公司的命运写照。
第一代的 MIPS 是 32 位的, 在 1985 年推出了对应的处理器,R2000,90 年, R3000 处理器对应着第二代的 MIPS, 92 年,MIPS 扩展到了 64 位,94 年,64 位的 MIPS 又 进一步升级,96 年的 MIPS5 并没有对应的处理器, 然后在 99 年,MIPS 指令系统进行了较大的调整, 形成了 MIPS32,到了 99 年,以 MIPS5 为基础, 推出了 MIPS64 指令系统。
MIPS 的设计指导思想非常的简单, 从它的名字就可以看出来。MIPS 全称的含义 是一个流水线不会互锁的微处理器,流水线是 现代微处理器为提高性能而采用的一项技术,而流水线中的互锁 则是导致流水线性能降低的一个非常重要的因素。从这个名称也可以看出,MIPS 的 指导思想是希望其指令的设计能让微处理器运行的更快,性能更好。 所以它主要的关注点是减少指令的类型,并且降低指令的复杂度,所以在 MIPS 指令系统当中, 指令的总数是很少的。 而且每条指令都比较简单。它的主要目的就是希望可以用 一个非常简单的 CPU 来支持这样的指令系统。而 CPU 越简单就可以运行的更快。假设要编写程序完成同样的任务,用 MIPS 指令编写,其指令数量是 X-86 指令的 5 倍, 但是如果 MIPS 的 CPU 能够做到比 X86 CPU 快 10 倍,那它仍然获得了明显的性能优势。 这就是 MIPS,同时也是 RISC 的设计思想。
那 MIPS 的指令是怎么体现它这样的设计思想的呢?
- 第一,MIPS 固定了指令的长度,都是 32 个比特, 也就说 MIPS 中的一个 WORD,我们要注意这和 X86 中一个 WORD 是 16 位是不同的。 固定的指令长度,大大简化了 CPU 从存储器中取指令的工作。 不用像 X86 CPU 那样需要判断每条指令的长度。
- 第二,MIPS 采用了非常简单的寻址模式,相比于 X86 提供的复杂多样的寻址模式, 虽然给编程带来了不变,但是大大简化了 CPU 访问存储器的控制逻辑。
- 第三 MIPS 指令的数量比较少,每条指令的工作也很简单, 基本上一条指令只完成一个操作,不像 X86 的指令,一条指令往往完成丰富的功能, 这样可以简化指令的执行过程,不但简化了 CPU 的控制逻辑,而且可以方便的实现各种让指令并行执行的技术,从而提高 CPU 的性能。
- 第四,在 MIPS 指令系统中只允许 LOAD 和 STORE 这两种指令访问存储器, 而不支持 X86 指令中这些让算术指令访问存储器的操作。 因为访存是一个相对复杂的工作, 这种限制就可以让运算指令的实现变得非常的简单,但是我们要注意,MIPS 的这些特点让直接使用 MIPS 指令进行编程变得非常的困难, 因此,想要有高效率的 MIPS 程序, 必须要有优秀的编译器的支持。
我们来看几个 MIPS 指令的例子。 例如加法指令,它的格式是 ADD A,B,C 我们注意,与 X86 指令不同,MIPS 的加法指令是三个操作数,这 A,B,C 可以是三个- 寄存器, 除了加法运算,这里还列出了减法,乘法,除法等等,还有逻辑运算, 还有左移和右移这样的移位运算。这类我们可以看出 MIPS 的运算指令 格式都非常简洁和统一,而且这些指令的操作数都不可以是存储器操作数。
要访问存储器,就必须使用专门的访存指令。我们来看一个例子,假设 A 是一个 100 个字的数组,它的首地址存放在 19 号寄存器中, MIPS 的寄存器编号用$符进行标记, 那如果我们想完成这样一个运算,也就说将一个变量 H 加上数组 A 中的第三个元素,并赋给数组 A 的第十个元素,我们注意, 变量 H 放在 18 号寄存器中,而我们可以使用 8 号寄存器用来存放临时数据, 那么对应的 MIPS 指令需要如下几条,
首先要用 LOAD 指令将 19 号寄存器对应的地址加上偏移量 12,因为 MIPS 当中 一个字是 32 位,所以第三个元素与首地址之间的偏移是 12, 将存储器中的这个字装入到 8 号寄存器中, 这就相当于将数组 A 中的第三个元素赋给了一个临时变量,
第二句是一个加法指令,将 8 号寄存器与 18 号寄存器相加, 并将结果存放在 8 号寄存器。这就 相当于将数组 A 的第三个元素与变量 H 相加,还存在这个临时变量中,
第三条指令是将 8 号寄存器中的数 也就是运算的结果存到以 19 号寄存器为首地址,偏移量为 40 的内存单元, 这就是数组 A 的第十个元素的位置。 那我们用这三条 MIPS 指令就完成了这个功能。
而这张表列出了 MIPS 的所有的通用寄存器,总共有 32 个, 每个都是 32 位,相比于 X86 的寄存器,MIPS 的通用寄存器是非常规正的。 这 32 个寄存器的编号从 0, 一直到 31,那我们可以用 $ 符加上编号 进行指示,同时每个寄存器还有一个符号的名称, 并且约定了一些特定的用途,例如 8 号到 15 号寄存器, 又被称为 T0,到 T7 的寄存器,用来保存临时的变量, 而 1 号寄存器,它的名称是 AT, 专门留给汇编器使用。
在编写汇编程序时, 我们可以用数字,也可以用名称,来表示这些寄存器,例如这两条指令所表达的含义以及对应的二进制编码都是一样的。这两条指令也是如此。如果我们直接用 MIPS 指令进行汇编语言的编程, 从 T0 到 T7,S0 到 S7,这些寄存器都是我们经常使用的。MIPS 的体系结构简明扼要,需要说明的就是这些。
我们已经了解了 MIPS 的设计理念, 那这样的理念究竟是如何实现的呢?在下一节我们将一起来探究 MIPS 的指令。