MIPS指令集的常用指令分类和相关解释
MIPS
MIPS(Microprocessor without Interlocked Pipeline Stages)是一种基于精简指令集(Reduced Instruction Set Computing,RISC)架构的32位微处理器。
MIPS指令集由约60条指令组成,支持基本的算术和逻辑运算、存储器访问、分支和跳转等操作,同时也支持异常处理和中断。MIPS架构的寄存器文件包含32个32位寄存器,其中0号寄存器始终为0,另外26个寄存器用于存储临时数据,而6个寄存器则用于存储函数调用和返回的地址。
一些基本概念
1.立即数(immediate value)是指在指令中直接给出的数值,而不是从寄存器或内存中读取的数据。立即数通常用于作为操作数参与运算或者用于分支指令中给出跳转的偏移量。在MIPS指令集中,立即数通常是16位的有符号整数,可以表示范围从-32768到32767的数值。
2.offset:表示偏移量,是一个16位的有符号整数,表示要存储的地址相对于寄存器$s所指向的地址的偏移量。
MIPS指令集的六种指令格式
R型指令:
R型指令用于寄存器之间的操作,如加减乘除等,指令格式中的操作码为000000。
这种指令涉及到寄存器之间的操作,使用3个寄存器进行操作。这些指令的操作码字段为6位,rs、rt、rd、shamt和funct字段的长度为5位。
其中,rs、rt分别表示源寄存器1和源寄存器2,rd表示目标寄存器,shamt字段用于移位操作,funct字段指定具体的操作类型。
例如,add $d, $s, $t指令就是一种R型指令。
I型计算类指令
其中,操作码表示指令的具体操作,第一个操作数寄存器和目标寄存器表示指令中涉及的寄存器编号,立即数表示指令中涉及的立即数的值。在MIPS指令集中,I型计算类指令的操作码通常为6位,rs和rt字段各占5位,imm字段占16位。
I型计算类指令是指立即数计算类指令,其操作码为6位,rs字段代表第一个操作数寄存器,rt字段代表第二个操作数寄存器,立即数字段表示立即数操作数。这类指令执行时,先将第一个操作数从寄存器中取出,再将立即数或者第二个操作数从寄存器中取出,经过计算后将结果存储到目标寄存器中。
I型取数类指令:
I型指令用于取数和存数操作,立即数可以是有符号数或无符号数,操作码根据不同指令而不同。
这种指令涉及到立即数的操作,使用2个寄存器和一个立即数进行操作。这些指令的操作码字段为6位,rs、rt字段的长度为5位,immediate字段的长度为16位。
其中,rs表示源寄存器,rt表示目标寄存器,immediate表示立即数。
例如,addi $t, $s, imm指令就是一种I型计算类指令。
I型条件判断类指令:
这种指令涉及到条件分支的操作,使用1个寄存器和一个偏移量进行操作。这些指令的操作码字段为6位,rs、rt字段的长度为5位,offset字段的长度为16位。
其中,rs表示源寄存器,offset表示偏移量,根据rs中的值进行条件分支操作。
例如,beq $s, $t, offset指令就是一种I型条件判断类指令。
J型指令:
直接跳转指令,如j、jal等。
MIPS指令集的常用指令
1.算术和逻辑指令
算术和逻辑指令是MIPS指令集中最基本的指令之一,用于执行加、减、乘、除、与、或、异或等基本算术和逻辑运算。其中一些常用的指令如下:
ADD $rd, $rs, $rt:
将寄存器 r s 和 rs和 rs和rt的值相加,结果存入寄存器 r d 。具体步骤为:将 rd。具体步骤为:将 rd。具体步骤为:将rs和 r t 中的值视为有符号整数,将它们相加,将结果写入 rt中的值视为有符号整数,将它们相加,将结果写入 rt中的值视为有符号整数,将它们相加,将结果写入rd。例如,若 r s = − 5 , rs = -5, rs=−5,rt = 3,则$rd = $rs + $rt = -2。
SUB $rd, $rs, $rt:
将寄存器 r s 和 rs和 rs和rt的值相减,结果存入寄存器 r d 。具体步骤为:将 rd。具体步骤为:将 rd。具体步骤为:将rs和 r t 中的值视为有符号整数,将 rt中的值视为有符号整数,将 rt中的值视为有符号整数,将rt的值取反(即将其每一位取反再加1),然后将 r s 和 rs和 rs和rt取反后的值相加,最后将结果取反(即将其每一位取反再加1),将结果写入 r d 。例如,若 rd。例如,若 rd。例如,若rs = -5, r t = 3 ,则 rt = 3,则 rt=3,则rd = $rs - $rt = -8。
ADDI $rt, $rs, imm:
将寄存器 r s 和立即数 i m m 相加,结果存入寄存器 rs和立即数imm相加,结果存入寄存器 rs和立即数imm相加,结果存入寄存器rt。具体步骤为:将 r s 的值视为有符号整数,将其与立即数 i m m 相加,将结果写入 rs的值视为有符号整数,将其与立即数imm相加,将结果写入 rs的值视为有符号整数,将其与立即数imm相加,将结果写入rt。例如,若 r s = − 5 , i m m = 10 ,则 rs = -5,imm = 10,则 rs=−5,imm=10,则rt = $rs + imm = 5。
ADDIU $rt, $rs, imm:
将寄存器 r s 和立即数 i m m 相加,结果存入寄存器 rs和立即数imm相加,结果存入寄存器 rs和立即数imm相加,结果存入寄存器rt。与ADDI的区别在于,ADDIU对立即数的符号不做特殊处理,而是视为无符号整数相加。具体步骤为:将 r s 的值视为无符号整数,将其与立即数 i m m 相加,将结果写入 rs的值视为无符号整数,将其与立即数imm相加,将结果写入 rs的值视为无符号整数,将其与立即数imm相加,将结果写入rt。例如,若 r s = 2 3 1 − 1 rs = 2^31-1 rs=231−1(即最大的有符号整数),imm = 10,则$rt = r s + i m m = 2 3 1 − 1 + 10 = − 2 31 + 9 。注意,由于 rs + imm = 2^31-1 + 10 = -2^{31} + 9。注意,由于 rs+imm=231−1+10=−231+9。注意,由于rt是一个32位寄存器,因此结果在存入$rt时会自动截断为32位。AND $rd, $rs, r t :将寄存器 rt:将寄存器 rt:将寄存器rs和 r t 的值进行按位与运算,并将结果存入寄存器 rt的值进行按位与运算,并将结果存入寄存器 rt的值进行按位与运算,并将结果存入寄存器rd。具体步骤为:将 r s 和 rs和 rs和rt中每一位进行逻辑与运算,将结果写入 r d 。例如,若 rd。例如,若 rd。例如,若rs = 10101100, r t = 01101011 ,则 rt = 01101011,则 rt=01101011,则rd = $rs & $rt = 00101000。
OR $rd, $rs, $rt:
将寄存器 r s 和 rs和 rs和rt的值进行按位或运算,并将结果存入寄存器 r d 。具体步骤为:将 rd。具体步骤为:将 rd。具体步骤为:将rs和 r t 中每一位进行逻辑或运算,将结果写入 rt中每一位进行逻辑或运算,将结果写入 rt中每一位进行逻辑或运算,将结果写入rd。例如,若 r s = 10101100 , rs = 10101100, rs=10101100,rt = 01101011,则$rd = $rs | $rt = 11101111。
XOR $rd, $rs, $rt:
将寄存器 r s 和 rs和 rs和rt的值进行按位异或运算,并将结果存入寄存器 r d 。具体步骤为:将 rd。具体步骤为:将 rd。具体步骤为:将rs和 r t 中每一位进行逻辑异或运算,将结果写入 rt中每一位进行逻辑异或运算,将结果写入 rt中每一位进行逻辑异或运算,将结果写入rd。例如,若 r s = 10101100 , rs = 10101100, rs=10101100,rt = 01101011,则$rd = $rs ^ $rt = 11000111。
SLT $rd, $rs, $rt:
将寄存器 r s 和 rs和 rs和rt的值进行比较,如果$rs < r t ,则将寄存器 rt,则将寄存器 rt,则将寄存器rd的值设为1,否则设为0。具体步骤为:将 r s 和 rs和 rs和rt中的值视为有符号整数,比较它们的大小,如果$rs < r t ,将 rt,将 rt,将rd的值设为1,否则设为0。例如,若 r s = − 5 , rs = -5, rs=−5,rt = 3,则$rd = $rs < $rt = 1,因为-5小于3。
2.存储器指令
存储器指令是MIPS指令集中用于读取和写入存储器中的数据的指令。这些指令包括加载(load)和存储(store)指令,其中加载指令用于从存储器中读取数据并将其存储到寄存器中,而存储指令则用于将寄存器中的数据写入存储器中。以下是一些常用的存储器指令:
lw t , o f f s e t ( t, offset( t,offset(s):
加载字(Load Word)指令,从内存中读取一个32位字(word)的数据,存储到寄存器 t 中。其中, t中。其中, t中。其中,s指定了内存地址的基地址,offset是一个16位的有符号立即数,表示相对于基地址的偏移量
sw t , o f f s e t ( t, offset( t,offset(s):
存储字(Store Word)指令,将寄存器 t 中的 32 位数据存储到内存中。其中, t中的32位数据存储到内存中。其中, t中的32位数据存储到内存中。其中,s指定了内存地址的基地址,offset是一个16位的有符号立即数,表示相对于基地址的偏移量。例如,sw t 0 , 8 ( t0, 8( t0,8(s2)表示将 t 0 中的一个字的数据存储到内存地址 t0中的一个字的数据存储到内存地址 t0中的一个字的数据存储到内存地址s2+8处。lb:从存储器中加载一个8位的字节(byte)并将其存储到寄存器中。
sb t , o f f s e t ( t, offset( t,offset(s):
该指令将寄存器 t 中的 8 位数据存储到以寄存器 t中的8位数据存储到以寄存器 t中的8位数据存储到以寄存器s的值加上偏移量offset所表示的内存地址中的一个字节中。例如sb t 0 , 0 x 20 ( t0, 0x20( t0,0x20(s3), t 0 的值为 0 x 34 , t0的值为0x34, t0的值为0x34,s3的值为0x100,要将$t0的值存储到地址0x120中。
3.分支和跳转指令
分支和跳转指令是MIPS指令集中用于控制程序流程的指令。其中分支指令根据特定的条件改变程序的执行路径,而跳转指令则直接将程序转移到一个新的地址。以下是一些常用的分支和跳转指令:
BEQ $rs, $rt, offset:
如果寄存器 r s 和 rs和 rs和rt的值相等,则跳转到当前指令地址+ 4 + 4 × o f f s e t 处执行。具体步骤为:将 4+4×offset处执行。具体步骤为:将 4+4×offset处执行。具体步骤为:将rs和$rt的值进行比较,如果相等,则将程序计数器(PC)加上当前指令的地址+4+4×offset,跳转到该地址执行下一条指令。否则,执行下一条指令。offset是一个有符号的立即数,用于表示跳转的偏移量。
BNE $rs, $rt, offset:
如果寄存器 r s 和 rs和 rs和rt的值不相等,则跳转到当前指令地址+ 4 + 4 × o f f s e t 处执行。具体步骤为:将 4+4×offset处执行。具体步骤为:将 4+4×offset处执行。具体步骤为:将rs和$rt的值进行比较,如果不相等,则将PC加上当前指令的地址+4+4×offset,跳转到该地址执行下一条指令。否则,执行下一条指令。offset是一个有符号的立即数,用于表示跳转的偏移量。
J target:
无条件跳转到目标地址执行。具体步骤为:将PC的高4位设置为当前指令的地址的高4位,将PC的低28位设置为目标地址的高4位×4,跳转到该地址执行下一条指令。目标地址是一个32位的地址,但只有高28位有效,低4位会被忽略。
JALR $rd, $rs:
将寄存器 r s 中的值作为目标地址跳转,并将下一条指令的地址存入寄存器 rs中的值作为目标地址跳转,并将下一条指令的地址存入寄存器 rs中的值作为目标地址跳转,并将下一条指令的地址存入寄存器rd。具体步骤为:将PC的值存入 r d ,将 rd,将 rd,将rs中的值设置为目标地址,跳转到该地址执行下一条指令。注意,$rs中的值必须是一个有效的地址,即它的低2位必须为0,因为跳转时会将最低的两位强制设置为0。
4.特权指令
特权指令是MIPS指令集中用于操作特权级别的指令。这些指令只能由特权级别较高的程序执行,并且可以用于访问系统资源或执行特定的操作。以下是一些常用的特权指令:
SYSCALL:
用于在用户程序中发起系统调用(system call)。该指令没有任何操作数。执行SYSCALL指令时,CPU将会进入内核态,并跳转到一个特定的系统调用处理函数,通过该函数执行需要的操作。一般来说,系统调用是由操作系统提供的接口,用于实现进程管理、文件管理、网络通信等功能。
MFC0 $rt, $rd:
用于将协处理器0(CP0)的寄存器 r d 的值传送到通用寄存器 rd的值传送到通用寄存器 rd的值传送到通用寄存器rt中。CP0是MIPS体系结构中的一个特殊寄存器集合,用于实现对异常处理、中断控制、虚拟内存等方面的支持。MFC0指令的操作数中, r d 是一个 5 位的 C P 0 寄存器编号, rd是一个5位的CP0寄存器编号, rd是一个5位的CP0寄存器编号,rt是一个通用寄存器编号。执行MFC0指令时,CPU将会将指定的CP0寄存器的值传送到指定的通用寄存器中。
MTC0 $rt, $rd:
用于将通用寄存器 r t 的值传送到协处理器 0 ( C P 0 )的寄存器 rt的值传送到协处理器0(CP0)的寄存器 rt的值传送到协处理器0(CP0)的寄存器rd中。MTC0指令的操作数与MFC0指令相似, r d 和 rd和 rd和rt分别是CP0寄存器和通用寄存器的编号。执行MTC0指令时,CPU将会将指定的通用寄存器的值传送到指定的CP0寄存器中。通常,使用MTC0指令来配置CP0寄存器的值,例如配置异常处理向量表的基地址等。
5.浮点指令
MIPS指令集还提供了一组用于执行浮点运算的指令,这些指令用于对单精度浮点数和双精度浮点数执行基本算术和逻辑运算。以下是一些常用的浮点指令:
ADD.S $fd, $fs, $ft:
将单精度浮点寄存器 f s 和 fs和 fs和ft的值相加,将结果存储到单精度浮点寄存器 f d 中。具体步骤为:将 fd中。具体步骤为:将 fd中。具体步骤为:将fs和 f t 中的单精度浮点数进行加法运算,将结果写入 ft中的单精度浮点数进行加法运算,将结果写入 ft中的单精度浮点数进行加法运算,将结果写入fd中。例如,若 f s 表示 3.5 , fs表示3.5, fs表示3.5,ft表示1.25,则$fd = $fs + $ft = 4.75。
SUB.S $fd, $fs, $ft:
将单精度浮点寄存器 f s 和 fs和 fs和ft的值相减,将结果存储到单精度浮点寄存器 f d 中。具体步骤为:将 fd中。具体步骤为:将 fd中。具体步骤为:将fs和 f t 中的单精度浮点数进行减法运算,将结果写入 ft中的单精度浮点数进行减法运算,将结果写入 ft中的单精度浮点数进行减法运算,将结果写入fd中。例如,若 f s 表示 3.5 , fs表示3.5, fs表示3.5,ft表示1.25,则$fd = $fs - $ft = 2.25。
MUL.S $fd, $fs, $ft:
将单精度浮点寄存器 f s 和 fs和 fs和ft的值相乘,将结果存储到单精度浮点寄存器 f d 中。具体步骤为:将 fd中。具体步骤为:将 fd中。具体步骤为:将fs和 f t 中的单精度浮点数进行乘法运算,将结果写入 ft中的单精度浮点数进行乘法运算,将结果写入 ft中的单精度浮点数进行乘法运算,将结果写入fd中。例如,若 f s 表示 3.5 , fs表示3.5, fs表示3.5,ft表示1.25,则$fd = $fs * $ft = 4.375。
DIV.S $fd, $fs, $ft:
将单精度浮点寄存器 f s 的值除以 fs的值除以 fs的值除以ft的值,将结果存储到单精度浮点寄存器 f d 中。具体步骤为:将 fd中。具体步骤为:将 fd中。具体步骤为:将fs和 f t 中的单精度浮点数进行除法运算,将结果写入 ft中的单精度浮点数进行除法运算,将结果写入 ft中的单精度浮点数进行除法运算,将结果写入fd中。例如,若 f s 表示 3.5 , fs表示3.5, fs表示3.5,ft表示1.25,则$fd = $fs / $ft = 2.8。需要注意的是,如果除数为0,则结果为正无穷大或负无穷大。