# 计算机组成原理

# 计算机基本结构

# 冯诺伊曼结构

  • 控制计算机的程序应该存放在存储器中,而不是由开关连线实现,开关连线会降低计算机的运行效率
  • 计算机应该采用二进制而不是十进制,十进制的方式会导致计算机内部结构变得非常复杂
  • 计算机的内部结构由运算器控制器储存器输入设备输出设备这五个部分组成
  • 数据程序均以二进制的形式不区别的存放在储存器中,存放的位置由存储器地址(内存地址)指定
  • 每个内存地址都对应着一个储存单元,数据存在存储单元中
  • 计算机工作时能够自动从储存器中读取指令并执行
  • 指令由操作码和地址码构成,操作码表示计算机要做操作,例如指出寻址(地址)方式,定义参加运算的数据类型,定义参加运算的数据的长度

# 计算机的五大组成部分

  • 运算器 CA central arithmetical
  • 控制器 CC central control
  • 存储器 M memory
  • 输入设备 I inpit
  • 输出设备 O output

冯诺依曼结构图

  • CPU和存储器之间通过总线连接,总线可以细化为控制总线地址总线数据总线

随机存储器(RAM): 可以进行读取和写入,但断电后内容就会丢失。对应冯诺依曼结构中的储存器一般称之为内存或主存储器

移位寄存器(I/O):用来进行输入和输出

微处理器(CPU):一片或几片大规模集成电路组成的中央处理器,它用于读取指令、执行指令,以及与外界存储器和逻辑部件交换信息等操作,是微型计算机的运算控制部分。它可与存储器和外围电路芯片组成微型计算机。对应冯诺依曼结构中的控制器和运算器

只读存储器(ROM):用来存放一些指令,只能读取不能写入(第一次写入后就不能修改),断电以后内容不会丢失,不包括在冯诺依曼结构中

# 计算机运行过程

计算机运行过程

首先,程序和数据通过输入设备进入存储器,然后控制器发出地址存储器,并从存储器中获得程序中对应的指令,这时控制器会发出命令给运算器,指挥运算器存储器中的数据进行相应的运算运算器返回一些运算状态告诉控制器,例如运算是否成功,还会把运算后的结果存放在存储器中,最后通过输出设备输出结果。输出设备可以是显示屏,音响,或者一些存储设备等

# 存储器

  • 设计计算机时确定存储器的编址方式
  • 每个存储单元存放8位二进制数
  • 每个存储单元的地址是唯一的,不同存储单元的地址互不相同
  • 地址总线用来访问(读取/写入)计算机内存地址,地址总线宽度决定了CPU可以访问的物理地址空间,简单地说就是CPU到底能够使用多大容量的内存。如果地址总线宽度为n,则CPU能管理的存储单元是2n个,假设地址总线宽度为32位,那么CPU可以管理的存储单元为232=4GB
  • 数据总线传输CPU要读写的数据,数据总线的宽度一般为存储单元位宽整数倍
  • 控制总线用于传送控制信号和时序信号,用于接收CPU的读写信号或者反馈传输已经完成的信号

# 控制器

  • 指令寄存器(IR) 用于存放正在执行或即将执行的指令
  • 程序计数器(PC) 用于存放下一条指令的单元地址,具有自动递增的计数功能
  • 存储器地址寄存器(MAR) 用于存放CPU访问存储器时正在读写的地址
  • 内存数据寄存器(MDR) 用于存放CPU正在读取或写入存储单元的数据
  • 指令译码部件 用于对IR中的指令进行译码,以确定IR中存放的是哪一条指令
  • 当确定指令之后,控制电路就可以产生对应的控制信号,控制信号在时许脉冲的同步下控制各个部件的动作

# 运算器

  • 运算器用于完成运算,运算可以分为算数运算逻辑运算
  • 算数运算为
  • 逻辑运算为
  • ALU 这是运算器的核心部件,用于完成算术运算和逻辑运算

运算器结构

  • XYZ表示用于暂时保存数据的寄存器
  • 图中的ALU有两输入口和一个输出口,如果要进行加法运算,要做运算的两个数分别从A端口和B端口输入,通过ALU运算后将结果输出到Z
  • 在ALU运算时会产生各种状态保存在寄存器F中,例如,是否为负数,是否进位,是否溢出等
  • 运算器运算的数据是在存储器中读取的,为了提高效率就会设置一个临时存放数据的地方,这就是通用寄存器
  • 通用寄存器中有n个,通用寄存器中的数据来自于存储器也可以来自于其他通用寄存器或者ALU的输出
  • 可以在两个不同的寄存器间传递数据,也可以在ALU和通用寄存器间传递数据

# 内部总线

  • 内部总线用于在CPU各个部件间传递数据,如果CPU中的一个部件要把数据传递给另一个部件时就要通过内部总线

# 计算机执行指令的过程

计算机执行指令的过程

取指令: 控制器将指令的地址交给存储器,存储器按照给定的地址读出指令并送回控制器
  1. 首先,控制器发出信号将PC中预执行的指令地址通过内部总线传送到MAR
  2. CPU中MAR通过地址总线地址传送给存储器存储器的MAR就会收到该地址并保存下来。同时,控制电路发出控制信号告诉存储器此次访问要进行读取数据的操作,存储器的控制逻辑会收到控制总线传来的信号,得知这次访问要做的操作是读操作。
  3. 存储器通过地址译码器找到地址对应的内存空间中存放的内容
  4. 把找到的内容送到MDR
  5. 这时存储器的控制逻辑会向CPU反馈当前传输已经准备好了,同时MDR的内容通过数据总线传入CPU,随后CPU中的控制电路检测到存储器传送过来的信号,就知道当前数据总线上已经准备好了数据,因此MDR就会将当前传输过来的数据保存下来,这时CPU就获得了所要取的指令(现在获得的是指令编码,之后还需要翻译成指令)
  6. MDR中的指令传送到IR中,并把PC中的地址更新为下一条指令所对应的地址
译码:控制器分析指令的操作性质,并向有关部件发出指令所需的控制信号
  1. IR把指令编码送到指令译码部件中翻译成指令
  2. 根据指令,控制电路产生控制信号传送到相关部件中
执行指令:控制器从通用寄存器中或存储器中取出操作数,并命令运算器对操作数进行指令规定的运算
  1. 根据指令,需要取操作数,CPU的MAR获取操作数的地址。之后的步骤与取指阶段类似,从存储器中获取的数据保存到CPU的MDR

  2. 控制器MDR中的数据暂存到寄存器Y中,这时一个操作数已经准备好了。另一个操作数存放在其他的通用寄存器中,把这个操作数暂存在寄存器X

  3. 在控制电路的控制下ALU会对寄存器X寄存器Y中的操作数进行运算,计算出的结果存放在寄存器Z

回写:将运算结果写入到通用寄存器或存储器
  1. 寄存器Z中的结果通过内部总线传送到通用寄存器中(通用寄存器不是一个寄存器,而是多个寄存器的总称),如果存放的寄存器中有内容,则原来存放的数据会被新的数据覆盖掉
  • 指令执行完毕后,获取下一个指令,继续重复这样的步骤

# 计算机输入与输出

  • 常见的输出设备:显示器、打印机、投影仪、绘图仪、喇叭等
  • 常见的输入设备: 键盘、鼠标、触摸屏 、扫描仪、摄像头、手写板、麦克风等

在特殊情况下,一个设备既可以做输入设备,也可以做输出设备。 例如硬盘硬盘既可以输出数据,也可以写入数据,还可以保存数据。硬盘保存数据的磁片可以叫做外部记录介质,而硬盘中的电路和控制芯片可以认为是输入或输出设备的一部分

输入输出示意

假设CPU和存储器已经开始工作了,现在我们要通过调整这些开关来控制灯泡的亮暗。我们将输入输出设备地址为1111的单元连接到这些手动开关。这个单元有8个比特,每个比特连接一个开关,当开关拨动在上方时,对应的位为1,开关在下方时对应的位为0,另一个地址为1110单位连接到这8个灯泡,单位中的每个位对应一个灯泡,分别用0和1表示高低电平高电平时灯泡亮,低电平时灯泡灭。 现在计算机会执行一个指令,这个指令是读取输入设备中地址为1111的数据(这些手动开关的状态),具体如下:

输入:

CPU先将输入设备(手动开关)的地址(1111)发送到地址总线上,总线上的一些电路会识别这个地址,得知这个地址应该发送到输入设备,与此同时CPU会通过控制总线输入设备发出read信号,告诉输入设备目前是一个读操作。这时输入设备控制逻辑地址译码器就会从CPU发送过来的地址(1111)找到对应单元里的数据,然后通过数据总线将数据传回到CPU,这样就完成了输入信息的读取工作,(之后CPU可以对这个数据进行运算,处理或保存在存储器中,以便之后使用)

输出:

CPU先将输出设备(灯泡)的地址(1110)发送到地址总线上,总线上的一些电路会识别这个地址,得知这个地址应该发送到输出设备,与此同时CPU会通过控制总线输出设备发出write信号,告诉输出设备目前是一个写操作。然后通过数据总线要输出的数据传输给输出设备,这时输出设备就会根据总线传输过来的信息将要输出的数据写入输出设备地址(1110)所对应的单元,当数据写入后,根据数据小灯泡会受到高低不同的电压,这时1对应的灯泡亮,0对应的灯泡灭

通过以上方式,我们还可以加入不同的输入输出设备,制造出各种各样的电子产品

# 指令系统

# 简单的指令系统

现在,我们要设计一个计算机。一个基本的计算机要有软件硬件两个部分组成。我们要通过计算机的软件来操作计算机的硬件,这些软件都是用代码编写而成,如何用他们去操作计算机的硬件呢?这时候我们就需要设计一个计算机软件和硬件交流的“桥梁” —— 计算机指令系统

在计算机设计之初,软件和硬件之间就会商量一套指令系统,以便后续设计出的软件能够在硬件使用

根据计算机执行指令的过程,一个简单的指令系统通常要有这三种指令

  • 运算类指令 使计算机做运算的指令。例如,加法运算。
  • 传送类指令 使存储器和寄存器间传输数据的指令。
  • 转移类指令 用于更改取指令的位置。

简单指令系统示例

根据需求设计不同的指令,例如我们要做加法运算,那么就需要一个让两个数相加的指令ADD。要做运算就需要进行运算的数据,但数据和指令存放在存储器中,这时就需要一个从存储器获取数据的指令LOAD。结束运算后数据保存在寄存器中,如果要将运算结果保存在存储器中,还需要一个将寄存器中的数存入存储器的指令STORE。一般情况下,CPU会按照地址从内存中依次读取指令并执行,如果要改变取指令的位置时就需要再设计一个指令JMP,该指令可以无条件地转移到指令中所指示的目的地址

注意

由于指令和数据主要存放在存储器中,如果把两个存储器中的数直接相加会比较复杂,所以在设计指令系统时,加法指令会将一个寄存器中的数和一个存储器中的数相加,把结果存放在另一个寄存器中。(寄存器中的数也来自于存储器)

# 指令的格式

  • 每条指令等长,且均为2个字节
  • 第一个字节的前四位是操作码,最多可以有16条
  • 第一个字节的后四位是寄存器号,最多可以有16个
  • 第二个字节是存储单元的地址,最多可以有256个存储单元

指令的格式

# 运算任务示例

任务

  1. 存储单元地址M1中的数与存储单元地址M2中的数相加
  2. 把相加后的结果存入地址为M3存储单元
  3. 完成运算后,将程序转向存储单元地址L中的指令继续执行

程序设计思路

  1. 存储单元M1中的内容送入某个寄存器(R1)中
  2. 寄存器R1中的内容与存储单元M2中的内容相加,并把运算结果存入寄存器R2
  3. 寄存器R2中的内容送入存储单元M3
  4. 地址转向L,取出下一条指令继续执行

用指令实现

以下指令依次对应设计思路中的四个步骤

汇编语言               机器语言
LOAD R1,[5]           0000 0001  00000101
ADD R1,[6]            0001 0001  00000110
STORE [7],R2          0010 0010  00000111
JMP [18]              0011 0000  00010010          

注:M1=5, M2=6, M3=7, L=18

运算任务示例

注意

CPU中的PC寄存器在启动后会按照地址去取出第一条指令,然后开始执行程序。那么这个地址是什么?第一条指令要从哪个地址中取出?这些都是不一定的,需要软件和硬件在最开始就商量好

# 指令的发展

最开始,人类使用由0和1构成的机器码来操作计算机,他们把这些机器码通过在纸带上打孔的方式表示,并送入计算机中执行。随着技术进步,人们开始使用汇编语言编写程序,通过工具把汇编语言转换成机器码来执行。之后又诞生了高级语言,这些高级语言可以通过一些复杂的工具转化成一条条汇编语言指令,这些指令再通过工具转换成0和1构成的机器码,从而操作计算机

# X86体系结构

X86架构是一种计算机指令集(指令系统),使用这种架构的微处理器有很多,以Intel 8086为例:

  • 这是一款16位的CPU,运算部件支持16位数据的运算。运算时所需要的数据一般存放在通用寄存器中,由于通用寄存器位宽一般和运算单元的位宽相同,所以它的内部通用寄存器为16
  • 地址总线位宽为20位(有20根地址线),可寻址的内存空间为220Byte=1MB,1M可以表示0x100000个地址,所以寻址范围为00000-FFFFF(这里用十六进制表示)
  • 数据总线位宽为16位(有16根数据线)

提示

CPU的取址能力取决于地址总线能够传输多少种数据

X86体系结构

Intel 8086之后,英特尔又推出了Intel 80386,这是X86系列中第一款32位的处理器,支持32位的运算和32位的通用寄存器,地址总线也扩展到了32位,所以可以寻址232=4GB的内存空间。

  • 32位X86体系结构被称为IA-32
  • 在指令中使用64位寄存器时可以用RAX,如果要使用32位寄存器时用EAX,也可用AX来使用16位的寄存器,或者用AHAL来使用8位的寄存器
各寄存器部件说明

AX(Accumulator)(AH、AL)累加器,它是汇编编程中最常用的一个寄存器,主要用于乘除运算、BCD运算、换码、I/O操作、串操作和中断调用等。

BX(Base)(BH、BL)基址寄存器,主要用于存放地址和基址(默认相对于DS段)等。

CX(Counter)(CH、CL)计数器,主要用于循环计数、串操作计数和移位计数(CL)等。

DX(Data)(DH、DL)数据寄存器,主要用于16位乘除、间接I/O和中断调用等。

BP(Base Pointer)基址指针,主要用于存放地址和基址(默认相对于SS段)等。

SP(Stack Pointer)堆栈指针(栈顶指针),主要用于存放栈顶地址。

SI(Source Index)源变址寄存器,用于存放地址、变址和串操作源变址。

DI(Destination Index)目的变址寄存器,用于存放地址、变址和串操作目的变址。

CS(CodeSegment)代码段寄存器(代码段),用于存放正在或正待执行的程序段的起始地址的高16位二进制数据,即程序段的段地址。

DS(Data Segment)数据段寄存器(数据段),用于存放正在或正待处理的一般数据段的起始地址的高16位二进制数据,即一般数据段的段地址。

ES(Extra Segment)附加数据段寄存器(附加段),用于存放正在或正待处理的附加数据段的起始地址的高16位二进制数据,即附加数据段的段地址。

SS(Stack Segment)堆栈数据段寄存器(堆栈段),用于存放正在或正待处理的堆栈数据段的起始地址的高16位二进制数据,即堆栈数据段的段地址。

# 标志寄存器

FLAGS寄存器中包含若干标志位标志位分为两大类:状态标志控制标志

  • 状态标志反映CPU的工作状态,例如:执行加法运算时是否产生进位,运算结果是否为零
  • 控制标志对CPU的运行起特定控制作用,例如:以单步方式还是连续方式运行,是否允许响应外部中断请求
  • Intel 8086的标志寄存器有16位,在标志位中存储0或1表达该标志位的状态

标志寄存器

标志寄存器中各标志位说明

IF(Interrupt enable Flag)中断允许标志,用于控制CPU能否响应可屏蔽中断请求, IF=1能够响应,IF=0不能响应。

DF(Direction Flag)方向标志,用于指示串操作时源串的源变址和目的串的目的变址的变化方向,DF=1向减的方向变化,DF=0向加的方向变化。

TF(Trap Flag)陷阱标志(单步中断标志),TF=1程序执行当前指令后暂停,TF=0程序执行当前指令后不会暂停。

SF(Sign Flag)符号标志,指令执行结果的最高二进制位是0还是1,为0,则SF=0,代表正数;为1,则SF=1,代表负数。我们一般是用十六进制数表示,则可以看十六进制的最高位是落在0~7还是落在8~F之间,若落在0~7之间则SF=0,否则SF=1。

PF(Parity check Flag)奇偶校验标志,指令执行结果的低8位中1的个数是奇数个还是偶数个,若为奇数个则PF=0,若为偶数个则PF=1。

ZF(Zero Flag)零标志,指令执行结果是不是为0,若为0则ZF=1,否则ZF=0。

OF(Overflow Flag)有符号数的溢出标志,指令执行结果是否超出有符号数的表示范围,若超过则OF=1,否则OF=0.我们可以通过是否出现以下四种情况之一来判断:正加正得负,正减负得负,负加负得正,负减正得正。若出现则OF=1,否则OF=0。

CF(Carry Flag)进位/借位标志(无符号数的溢出标志),指令执行结果的最高位是否有向更高位进位或借位,若有则CF=1,同时也代表无符号数溢出;若无则CF=0,也代表无符号数未溢出。

AF(Auxiliary carry Flag)辅助进位/借位标志,低4位二进制是不是有向高位进位或借位,若有则AF=1,否则AF=0,其主要用于BCD修正运算。

# 指令指针寄存器

IP(Instruction Pointer)指令指针寄存器,与PC寄存器的作用相同。在Intel 8086中叫做IP寄存器

  • 保存一个内存地址,且该地址指向当前需要取出的指令
  • 当CPU从内存中取出一个指令后,IP寄存器地址会自动递增,指向下一指令的地址
  • 无法通过编写的程序直接修改IP寄存器,但转移指令、过程调用/返回指令等指令会改变IP寄存器中的地址
  • Intel 8086IP寄存器位宽为16位所以他的寻址能力为216=65536B=64KB,由于64kb实在太小,无法满足大部分程序的需求,所以8086采用了与四个段寄存器联合的方式生成存储器地址,将寻址能力达到了220=1MB

# 段寄存器

Intel 8086中有四个段寄存器:

  • CS(Code Segment)代码段寄存器
  • DS(Data Segment)数据段寄存器
  • ES(Extra Segment)附加段寄存器
  • SS(Stack Segment)堆栈段寄存器

以代码段寄存器为例,演示8086微处理器物理地址生成的过程

标志寄存器

代码段寄存器中现在存放着一个16位的值,用十六进制表示为0X2000,根据程序运行的状况,当前IP寄存器中的值为0X3000。然后通过移位器代码段寄存器中的值进行移位,(在8086中采用的是20位的物理地址,代码段寄存器地址为16位所以要向将该地址向左移4位)移位后新产生的值为0X20000,然后将这个值与IP寄存器中的值相加,得到一个20位物理地址,这时CPU就会将这个地址发送到存储器中取出下一条指令并执行。这也是地址总线位宽设计为20位的原因

  • X86体系结构中的指令长度不是固定的,它可以根据需要设定指令的长度(多少字节)
  • 丰富的指令让编写程序变得容易,但让CPU的设计变得非常复杂

# X86指令简介

通常一个指令系统主要包括这几类指令:

运算类指令:例如加,减,乘,除这种算数运算或者或,与,非这类逻辑运算

传送类指令:例如把数据存储器送到通用寄存器中或者从通用寄存器送到输入输出接口

有了这两类指令计算机就可以从外界获取数据,并在计算机中进行运算,然后将结果输出到外界,如果要编写像高级语言中if,while,for这样复杂点的程序就需要用到转移类指令

转移类指令:例如无条件转移,条件转移,过程调用等

控制类指令对CPU进行控制的指令,例如暂停处理器,清除标志位等

现在,通过以下任务示例简单介绍X86体系结构中各类指令在计算机中如何工作(只演示X86体系结构中众多指令的部分指令)

任务

  • 在存储器中,把在起始地址为2000H的数和起始地址为3000H的数相加。
  • 两数的长度存放在地址为2500H的存储单元中

注:结尾带H的数表示该数为十六进制

X86指令简介

  • MOV CL,[2500H] 将地址为2500H的内存单元中的内容传入CL寄存器

这个内存单元保存运算数的长度

  • MOV SI, 2000H 将2000H这个数传送到SI寄存器中

将第一个运算数的起始地址保存在SI寄存器

  • MOV DI, 3000H 将3000H这个数传送到DI寄存器中

将第二个运算数的起始地址保存在DI寄存器

  • CLC 将CF标志位清零

下面的ADC指令在进行加法运算时还会加上进位,但第一次两数相加时不应该进位,所以这里要将CF标志位清零

  • MOV AX,[SI] 将地址为2000H的存储单元中的第一个字(前两个字节)传送到AX寄存器当中
  • ADC AX,[DI] 将地址为3000H的存储单元中的第一个字与AX寄存器当中的数相加,并把结果存到AX寄存器中

这里之所以要使用ADC指令而不是ADD指令是因为ADC指令在运算时会加上CF标志位,两数相加可能会产生进位,ADC指令会让进位传递到下一次运算,以保证运算结果正确无误

  • MOV [SI], AX将AX寄存器中的内容传送到SI所指向的内存单元
  • INC SI 递增SI寄存器中的数
  • INC DI 递增DI寄存器中的数

SIDI寄存器之所以要递增两次是因为之前两数的第一个字(前两个字节)已经相加,下一次进行循环累加时应该加第二个字,由于一个字占两个字节,所以在SI寄存器DI寄存器中的内存地址要往后移两位

  • DEC CL 将CL寄存器中的内容减一

每运算一次CL寄存器中保存的运算数长度就减一,当运算数长度减为0时怎表示运算数的没一位都完成了运算,这时再执行下一条指令JNZ LOOP1时条件则不满足,循环累加的操作就会停止

  • JNZ LOOP1 如果前一条指令运算结果不为0则转移到LOOP1所指定位置开始执行,如果为0则跳过该指令,继续下一条指令

# 传送类指令

作用:把数据和地址传送到寄存器或存储器单元中

MOV指令

  • 格式:MOV DST, SRC (DST表示目的位置,SRC表示源位置或源操作数)
  • 作用:把一个操作数从源位置传送到目的位置,源操作数的内容不变

这条指令的格式有丰富的变化,例如:

指令示例 说明
MOV EBX, 40 将40这个数送到EBX寄存器当中(直接给出操作数)
MOV AL, BL 将BL寄存器中的内容传送到AL寄存器中(给出寄存器名称)
MOV ECX, [1000H] 将地址1000H的存储器单元的内容取出,传送到ECX寄存器中(给出存储器地址)
MOV [DI], AX 将AX寄存器中的内容传送到存储器的某个单元,这个单元的地址存放在DI寄存器中(给出存放"存放操作数的存储器地址"的寄存器名称)
MOV WORD PTR[BX+SI*2+200H], 01H 把01H这个数存放在某个内存单元中,这个内存单元的地址要通过计算获得。计算过程:从SI寄存器中取出数并乘2,再从BX寄存器中取出数,二者相加,之后再加上200H

# 运算类指令

计算机能够执行的基本数值计算,包括加法ADD、减法SUB、乘法MUL、除法DIV

ADD指令

  • 格式:ADD DST, SRC
  • 操作:将两个操作数相加并将结果存放在存放第一个操作数的内存单元中(DST←DST+SRC)

INC指令

  • 格式:INC OPR
  • 操作:将操作数+1(OPR←OPR+1)

DEC指令

  • 格式:DEC OPR
  • 操作:将操作数-1(OPR←OPR-1)

ADC指令

  • 格式:ADC DST, SRC (带进位的加)
  • 操作:将两个操作数相加,再加上CF标志位(DST←DST+SRC+CF)

注:如果运算器做两数相加的运算时产生了进位,计算机就会改写标志寄存器中的CF标志位,当下一次运算时使用了ADC指令CF标志位也会参与运算,这样前一次运算的结果就会影响后一次运算。ADC指令的进位也会影响CF标志位,ADDADC指令都会根据结果影响CF标志位

# 转移类指令

用于改变指令执行的顺序

JNZ指令

这是一条条件转移指令,根据条件执行

  • 格式: JNZ LOOP
  • 操作:检查前一条指令的运算结果是否为0,如果不为0或不相等时则转移到LOOP所指的位置

实际上是检查标志寄存器中的ZF标志位,如果运算结果为0,ZF标志位就会被设置为1,表示这次的运算结果为0,否则ZF标志位为0

# 控制类指令

作用:控制CPU的功能,对标志位进行操作

CLC指令

  • 格式:CLC
  • 作用:把进位标志位(CF)清零

# MIPS体系结构

MIPS架构是由斯坦福大学开发的一种RISC架构,