本文主要是介绍MIPS指令,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
MIPS有三种指令格式:(所有指令都是32 位长)
- R格式
功能 | 操作码6bit | 1源操作数寄存器5bit | 2源操作数寄存器5bit | 目标操作数寄存器(放结果)5bit | 偏移量5bit | 函数码6bit | 说明 |
---|---|---|---|---|---|---|---|
标记/指令 | opcode | rs | rt | rd | shamt | funct | |
位数 | 31-26 | 25-21 | 20-16 | 15-11 | 10-6 | 5-0 | |
例:add | 000000 | rs | rt | rd | 00000 | 100000 | rd=rs+rt |
例: jr | 000000 | rs | 00000 | 00000 | 00000 | 001000 | PC=rs |
算数类指令
逻辑类指令
位移类指令
跳转指令
- I格式
功能 | 操作码6bit | 源操作数寄存器5bit | 目标寄存器(放结果)5bit | 地址相对基址偏移量(立即数)16bit | 说明 |
---|---|---|---|---|---|
标记/指令 | opcode | rs | rd | address | |
位数 | 31-26 | 25-21 | 20-16 | 15-0 | |
算数 addi | 001000 | rs | rd | im | rd=rs+im |
逻辑 andi | 001100 | rs | rd | im | rd=rs&im |
载入 lui | 001111 | 00000 | rd | im | rt=im*65536 |
跳转 beq | 000100 | rs | rd | im | PC=(rs==rt)?PC+4+im<<2:PC |
- J格式
功能 | 操作码6bit | 目标地址26bit | 说明 |
---|---|---|---|
标记 | opcode | target address | |
j | 000010 | addr | PC={(PC+4)[31,28],addr,00} |
jal | 000011 | addr | $31=PC;PC={(PC+4)[31,28],addr,00} |
MIPS指令
指令
功能
应用实例
.align n
将以2的n次方的对齐方式编译代码,这个位置就基于开始位置偏移,实现对二进制的指定位置编译
dla
用来加载程序中某些带标号的位置或者变量的地址的宏指令,双字
la
(load address)用来加载程序中某些带标号的位置或者变量的地址的宏指令la $t0, var1
拷贝var1 内存地址到t0;
dli
装入双字立即数常数
li
(load immediate)装入立即数常数li register_destination, value
lui
把立即数加载到寄存器高位;
jal
绝对跳转指令,直接寻址方式 MIPS文档中描述为not PC-relative,即PC无关寻址。基地址+偏移
bal
相对跳转指令,相对寻址以程序计数器PC的当前值(R15中的值)为基地址,进行偏移;MIPS文档中描述为PC-relative,即PC相关寻址
cache
操作指令
I格式:cache op,offset(base)
执行op制定的cace操作,16位的offset经符号位扩展,添加到base寄存器以形成有效地址;
cache指令中的op字段低两位[17:16]表示操作的是哪个cache
2‘b00 I-L1(primary instruction)
2'b01 D-L1(primary data or unified primary)
2'b10 L3Cache(Tertiary)
2'b11 L2Cache(secondary)
cache指令中的op字段高三位[20:18]表示的是cache操作模式
addi
加立即数指令,支持溢出检测,具体表现为:遇到溢出时,溢出错误标志变为高电平,传送到控制器cu中,导致此时的寄存器写使能信号regwr无效,最终结果为不将运算结果写入目的寄存器
addiu
是加立即数指令,不受溢出限制,具体表现为:遇到溢出时,对溢出的结果进行32bit求模,将求模结果写入目的寄存器中,因而不受溢出限制。
忽略溢出,addi与addiu等价
Add
是将rs与rt中的值相加,结果存储在rd寄存器中。检测溢出。如果不溢出,将结果存储在rd寄存器中,如果溢出,抛出溢出异常,不改变rd中的值。
Addu
是将rs与rt中的值相加,结果存储在rd寄存器中。不检测溢出,如果溢出,不会抛出异常。
忽略溢出,add与addu等价
add是有符号数加法,addu是"无符号数"加法,但是对于cpu来说,都是一样的,不管有没有符号位,都是从最低位加,进位,一直到最高位。
LB
( load byte)从存储器中读取一个字节的数据到寄存器中LB R1, 0(R2)
lb register_destination, RAM_source
LH
从存储器中读取半个字的数据到寄存器中LH R1, 0(R2)
LW
(Load Word)从存储器中读取一个字的数据到寄存器中LW R1, 0(R2)
数字是偏移量,可以正负
从内存中 复制 RAM_source 的内容到 对应的寄存器中,'l’加载‘Load’ ‘w’意为’word’,即该数据大小为4个字节
lw register_destination, RAM_source
LD
从存储器中读取双字的数据到寄存器中LD R1, 0(R2)
L.S
从存储器中读取单精度浮点数到寄存器中L.S R1, 0(R2)
L.D
从存储器中读取双精度浮点数到寄存器中L.D R1, 0(R2)
LBU
功能与LB指令相同,但读出的是不带符号的数据
LBU R1, 0(R2)
LHU
功能与LH指令相同,但读出的是不带符号的数据
LHU R1, 0(R2)
LWU
功能与LW指令相同,但读出的是不带符号的数据
LWU R1, 0(R2)
SB
(store byte (low-order))把一个字节的数据从寄存器存储到存储器中SB R1, 0(R2)
sb register_source, RAM_destination
SH
把半个字节的数据从寄存器存储到存储器中
SH R1,0(R2)
SW
(store word存储一个字) 把一个字的数据从寄存器存储到存储器中SW R1, 0(R2)
数字是偏移量,可以正负
sw register_source, RAM_destination
SD
把两个字节的数据从寄存器存储到存储器中SD R1, 0(R2)
S.S
把单精度浮点数从寄存器存储到存储器中
S.S R1, 0(R2)
S.D
把双精度数据从存储器存储到存储器中
S.D R1, 0(R2)
DADD
把两个定点寄存器的内容相加,也就是定点加
DADD R1,R2,R3
DADDI
把一个寄存器的内容加上一个立即数
DADDI R1,R2,#3
DADDU
不带符号的加
DADDU R1,R2,R3
DADDIU
把一个寄存器的内容加上一个无符号的立即数
DADDIU R1,R2,#3
ADD.S
把一个单精度浮点数加上一个双精度浮点数,结果是单精度浮点数
ADD.S F0,F1,F2
ADD.D
把一个双精度浮点数加上一个单精度浮点数,结果是双精度浮点数
ADD.D F0,F1,F2
ADD.PS
两个单精度浮点数相加,结果是单精度浮点数
ADD.PS F0,F1,F2
DSUB
两个寄存器的内容相减,也就是定点数的减
DSUB R1,R2,R3
DSUBU
不带符号的减
DSUBU R1,R2,R3
SUB.S
一个双精度浮点数减去一个单精度浮点数,结果为单精度
SUB.S F1,F2,F3
SUB.D
一个双精度浮点数减去一个单精度浮点数,结果为双精度浮点数
SUB.D F1,F2,F3
SUB.PS
两个单精度浮点数相减
SUB.SP F1,F2,F3
DDIV
两个定点寄存器的内容相除,也就是定点除
DDIV R1,R2,R3
DDIVU
不带符号的除法运算
DDIVU R1,R2,R3
DIV.S
一个双精度浮点数除以一个单精度浮点数,结果为单精度浮点数
DIV.S F1,F2,F3
DIV.D
一个双精度浮点数除以一个单精度浮点数,结果为双精度浮点数
DIV.D F1,F2,F3
DIV.PS
两个单精度浮点数相除,结果为单精度
DIV.PS F1,F2,F3
DMUL
两个定点寄存器的内容相乘,也就是定点乘
DMUL R1,R2,R3
DMULU
不带符号的乘法运算
DMULU R1,R2,R3
MUL.S
一个双精度浮点数乘以一个单精度浮点数,结果为单精度浮点数
DMUL.S F1,F2,F3
MUL.D
一个双精度浮点数乘以一个单精度浮点数,结果为双精度浮点数
DMUL.D F1,F2,F3
MUL.PS
两个单精度浮点数相乘,结果为单精度浮点数
DMUL.PS F1,F2,F3
AND
与运算,两个寄存器中的内容相与
ANDR1,R2,R3
ANDI
一个寄存器中的内容与一个立即数相与
ANDIR1,R2,#3
OR
或运算,两个寄存器中的内容相或
ORR1,R2,R3
ORI
一个寄存器中的内容与一个立即数相或
ORIR1,R2,#3
XOR
异或运算,两个寄存器中的内容相异或
XORR1,R2,R3
XORI
一个寄存器中的内容与一个立即数异或
XORIR1,R2,#3
‘b’ (Branches) 流控制,分支(if else系列)
b target # unconditional branch to program label target
beq $t0,$t1,target # branch to target if $t0 = $t1
blt $t0,$t1,target # branch to target if $t0 < $t1
ble $t0,$t1,target # branch to target if $t0 <= $t1
bgt $t0,$t1,target # branch to target if $t0 > $t1
bge $t0,$t1,target # branch to target if $t0 >= $t1
bne $t0,$t1,target # branch to target if $t0 <> $t1
BEQZ
条件转移指令,当寄存器中内容为0时转移发生BEQZ R1,target
BNEZ
条件转移指令,当寄存器中内容不为0时转移发生BNEZ R1, target
BEQ
条件转移指令,当两个寄存器内容相等时转移发生BEQ R1,R2 target
if(R1==R2) 跳转到target,target=PC <- PC+4 + (sign-extend)immediate<<2
BNE
条件转移指令,当两个寄存器中内容不等时转移发生BNE R1,R2 target
if(R1!=R2) 跳转到target,target=PC <- PC+4 + (sign-extend)immediate<<2
汇编中的while1
1:b 1bnop
0~9
的数字为局部标签。局部标签可以重复使用,语法为:
xf
:往前跳的意思,就是还未执行的程序,x代表0~9的某个标签,f代表forward的意思。
xb
:往后跳的意思,回到原来已经执行过的语句,x代表0~9的某个标签,b代表backward的意思。
1: ;A
#cmp r0, #0
beqz r0, 1f ; @ r0==0那么向前跳转到B处执行
nopbnez r0,1b ; @ 否则向后跳转到A处执行
nop
1: ;B
J
(Jumps)直接跳转指令,跳转的地址在指令中,跳转(while, for, goto系列)jtarget
JR
(jump and link)使用寄存器的跳转指令,跳转地址在寄存器中JR R1
JAL
直接跳转指令,并带有链接功能,指令的跳转地址在指令中,跳转发生时要把返回地址存放到R31这个寄存器中
JAL R1 name
JALR
使用寄存器的跳转指令,并且带有链接功能,指令的跳转地址在寄存器中,跳转发生时指令的放回地址放在R31这个寄存器中
JALR R1
move
寄存器复制到另一个寄存器move t 2 , t2, t2,t3 --> $t2 = $t3
MOV.S
把一个单精度浮点数从一个浮点寄存器复制到另一个浮点寄存器MOV.S F0,F1
MOV.D
把一个双精度浮点数从一个浮点寄存器复制到另一个浮点寄存器
MOV.D F0,F1
- MFC0 把一个数据从特殊寄存器复制到通用寄存器 MFC0 R1,R2
mfc0 rt, rd
将CP0中的rd寄存器内容传输到rt通用寄存器; - MTC0把一个数据从通用寄存器复制到特殊寄存器 MTC0 R1,R2
mtc0 rt, rd
将rt通用寄存器中内容传输到CP0中寄存器rd; - MFC1 把一个数据从定点寄存器复制到浮点寄存器 MFC1 R1,F1
- MTC1 把一个数据从浮点寄存器复制到定点寄存器MTC1 R1,F1
mfhi/mflo rt
将CP0的hi/lo寄存器内容传输到rt通用寄存器中;
mthi/mtlo rt
将rt通用寄存器内容传输到CP0的hi/lo寄存器中;
当MIPS体系结构演进到MIPS IV的64位架构后,新增了两条指令dmfc0和dmtc0,向CP0的寄存器中读/写一个64bit的数据。
LUI
把一个16位的立即数填入到寄存器的高16位,低16位补零
LUI R1,#42
DSLL
双字逻辑左移
DSLL R1,R2,#2
DSRL
双字逻辑右移
DSRL R1,R2,#2
DSRA
双字算术右移
DSRA R1,R2,#2
DSLLV
可变的双字逻辑左移
DSLLV R1,R2,#2
DSRLV
可变的双字罗伊右移DSRLV R1,R2,#2
DSRAV
可变的双字算术右移DSRAV R1,R2,#2
SLT
如果R2的值小于R3,那么设置R1的值为1,否则设置R1的值为0SLT R1,R2,R3
SLTI
如果寄存器R2的值小于立即数,那么设置R1的值为1,否则设置寄存器R1的值为0SLTI R1,R2,#23
SLTU
功能与SLT一致,但是带符号的SLTU R1,R2,R3
SLTUI
功能与SLT一致,但不带符号SLTUI R1,R2,R3
MOVN
如果第三个寄存器的内容为负,那么复制一个寄存器的内容到另外一个寄存器MOVN R1,R2,R3
MOVZ
如果第三个寄存器的内容为0,那么复制一个寄存器的内容到另外一个寄存器MOVZ R1,R2,R3
TRAP
根据地址向量转入管态
ERET
从异常中返回到用户态
MADD.S
一个双精度浮点数与单精度浮点数相乘加,结果为单精度
MADD.D
一个双精度浮点数与单精度浮点数相乘加,结果为双精度
MADD.PS
两个单精度浮点数相乘加,结果为单精度
这篇关于MIPS指令的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!