手撸MIPS32——MIPS32指令集
(MIPS32 Release1指令集的子集MiniMIPS32)
通用寄存器命名和使用约定
运算指令
ALU立即数指令
在立即数这里,rt相当于目的寄存器,rs相当于源寄存器,imm立即数
ADDI 加立即数可触发溢出异常
ADDI rt,rs,imm
将rs与imm相加,结果存到rt
rt<-(rs+imm)(有符号扩展32位)
ADDIU 加立即数,不触发溢出异常
ADDIU rt,rs,imm
rt<-(rs+imm)(有符号扩展32位)
SLTI 有符号小于立即数置1
SLTI rt,ts,imm
if rs<imm(有符号扩展32位)
rt=1
else rt=0
SLTIU 无符号小于立即数置1
SLTIU rt,ts,imm
if rs<imm(有符号扩展32位)
rt=1
else rt=0
ANDI 按位与立即数
ANDI rt,rs,imm
rt<-rs&imm
ORI 按位或立即数
ORI rt,rs,imm
rt<- rs|imm
XORI 按位异或立即数
XORI rt,rs,imm
rt<-rs XOR imm
LUI 寄存器高半字置立即数
LUI rt,imm
将立即数写入寄存器rt高16位
ALU寄存器指令
在寄存器这里,rd相当于目的寄存器,rs,rt相当于源寄存器
ADD 加可触发溢出异常
ADD rd,rs,rt
rs与rt的值相加存入rd
rd<- rs+rt
ADDU 加,不触发溢出异常
ADDU rd,rs,rt
rd<- rs+rt
SUB 减,触发溢出异常
SUB rd,rs,rt
rd<- rs-rt
SUBU 减,不触发溢出异常
SUBU rd,rs,rt
rd<- rs-rt
SLT 有符号小于置1
SLT rd,rs,rt
if rs<rt
rd=1
else rd=0
SLTU 无符号小于置1
SLTU rd,rs,rt
if rs<rt
rd=1
else rd=0
AND 按位与
AND rd,rs,rt
rd<- rs&rt
OR 按位或
OR rd,rs,rt
rd<- rs|rt
NOR 按位或非
NOR rd,rs,rt
rd<- rs NOR rt
XOR 按位异或
XOR rd,rs,rt
rd<- rs NOR rt
移位指令
SLL 逻辑左移,移位位数来自于sa
SLL rd,rt,sa
将寄存器rt的值逻辑左移sa位,结果存入寄存器rd
rd<- rt<<sa
SRL 逻辑右移,移位位数来自于sa
SRL rd,rt,sa
rd<- rt>>sa
SLLV 逻辑左移,移位位数来自于寄存器
SLLV rd,rt,rs
rs低5位指定移位位数(rs共32位),将rt进行逻辑左移,结果存入rd
rd<- rt<<(rs|11111)
SRLV 逻辑右移,移位位数来自于寄存器
SRLV rd,rt,rs
rd<- rt>>(rs|11111)
SRAV 算术右移,移位位数来自于寄存器
SRAV rd,rt,rs
rd<- rt>>(rs|11111) (高位补符号位)
乘除指令
MULT 有符号乘法
MULT rs,rt
有符号乘法,将rs的值乘以rt,结果低32位保存到LO,高32位保存到HI
HI,LO<- rs*rt
MULTU 无符号乘法
MULTU rs,rt
HI,LO<- rs*rt
DIV 有符号除法
DIV rs,rt
HI<-rs%rt,LO<-rs/rt
DIVU 无符号除法
DIVU rs,rt
HI<-rs%rt,LO<-rs/rt
MFHI HI寄存器至通用寄存器
HFHI rd
将寄存器HI的值存入通用寄存器rd
rd<-HI
MFLO LO寄存器至通用寄存器
HFLO rd
将寄存器LO的值存入通用寄存器rd
rd<-LO
MTHI 通用寄存器至HI
MTHI rs
将通用寄存器rs值存入HI
HI<-rs
MTLO 通用寄存器至LO
MTLO rs
将通用寄存器rs值存入LO
LO<-rs
访存指令
加载指令
LB 加载有符号字节
LB rt,offset(base)
将寄存器bsae的值与立即数offset进行符号扩展后的值相加得到访存地址,根据此访存地址从存储器读出1字节并进行符号扩展存入寄存器rt
LBU 加载无符号字节
LBU rt,offset(base)
将寄存器bsae的值与立即数offset进行符号扩展后的值相加得到访存地址,根据此访存地址从存储器读出1字节并进行无符号扩展存入寄存器rt
LH 加载有符号半字
LH rt,offset(base)
将寄存器bsae的值与立即数offset进行符号扩展后的值相加得到访存地址。如果地址不是2的整数倍,触发地址错误异常,否则从此存放地址读出2字节并进行有符号扩展存入寄存器rt
LHU 加载有符号半字
LHU rt,offset(base)
将寄存器bsae的值与立即数offset进行符号扩展后的值相加得到访存地址。如果地址不是2的整数倍,触发地址错误异常,否则从此存放地址读出2字节并进行无符号扩展存入寄存器rt
LW 加载字
LW rt,offset(base)
将寄存器bsae的值与立即数offset进行符号扩展后的值相加得到访存地址。如果地址不是4的整数倍,触发地址错误异常,否则从此存放地址读出4字节存入寄存器rt
存储指令
SB 存储字节
SB rt,offset(base)
将寄存器bsae的值与立即数offset进行符号扩展后的值相加得到访存地址。根据此存放地址将寄存器rt的最低字节存入存储器
SH 存储字节
SH rt,offset(base)
将寄存器bsae的值与立即数offset进行符号扩展后的值相加得到访存地址。如果地址不是2的整数倍,触发地址错误异常,否则根据此存放地址将寄存器rt的低半字存入存储器
SW 存储字
SW rt,offset(base)
将寄存器bsae的值与立即数offset进行符号扩展后的值相加得到访存地址。如果地址不是4的整数倍,触发地址错误异常,否则根据此存放地址将寄存器rt的值存入存储器
转移指令
分支指令
BEQ 相等转移
BEQ rs,rt,offset
如果rs=rt这程序发生跳转否则顺序执行。转移目标地址由16位立即数字段offset左移两位(32位系统,一个相当于4字节所以要乘4相当于左移2位)并进行符号扩展后的值与该分支指令的下一条指令地址相加(PC+4)所得。
BNE 不相等转移
BNE rs,rt,offset
如果rs!=rt这程序发生跳转否则顺序执行。转移目标地址由16位立即数字段offset左移两位(32位系统,一个相当于4字节所以要乘4相当于左移2位)并进行符号扩展后的值与该分支指令的下一条指令地址相加(PC+4)所得。
BGEZ 大于等于0转移
BGEZ rs,offset
如果寄存器rs的值大于等于0,则程序发生转移,否则顺序执行。转移目标地址由16位立即数字段offset左移两位(32位系统,一个相当于4字节所以要乘4相当于左移2位)并进行符号扩展后的值与该分支指令的下一条指令地址相加(PC+4)所得。
BGTZ 大于0转移
BGTZ rs,offset
如果寄存器rs的值大于0,则程序发生转移,否则顺序执行。转移目标地址由16位立即数字段offset左移两位(32位系统,一个相当于4字节所以要乘4相当于左移2位)并进行符号扩展后的值与该分支指令的下一条指令地址相加(PC+4)所得。
BLEZ 小于等于0转移
BLEZ rs,offset
如果寄存器rs的值小于等于0,则程序发生转移,否则顺序执行。转移目标地址由16位立即数字段offset左移两位(32位系统,一个相当于4字节所以要乘4相当于左移2位)并进行符号扩展后的值与该分支指令的下一条指令地址相加(PC+4)所得。
BLTZ 小于0转移
BLTZ rs,offset
如果寄存器rs的值小于0,则程序发生转移,否则顺序执行。转移目标地址由16位立即数字段offset左移两位(32位系统,一个相当于4字节所以要乘4相当于左移2位)并进行符号扩展后的值与该分支指令的下一条指令地址相加(PC+4)所得。
BGEZAL 大于等于0转移到子程序并保存返回地址
BGEZAL rs,offset
如果寄存器rs的值大于等于0,则程序发生转移,否则顺序执行。转移目标地址由16位立即数字段offset左移两位(32位系统,一个相当于4字节所以要乘4相当于左移2位)并进行符号扩展后的值与该分支指令的下一条指令地址相加(PC+4)所得。无论转移与否,需要将该分支指令后的第二条指令地址(PC+8)作为返回地址存入$ra 寄存器
BLTZAL 小于0转移到子程序并保存返回地址
BLTZAL rs,offset
如果寄存器rs的值小于0,则程序发生转移,否则顺序执行。转移目标地址由16位立即数字段offset左移两位(32位系统,一个相当于4字节所以要乘4相当于左移2位)并进行符号扩展后的值与该分支指令的下一条指令地址相加(PC+4)所得。无论转移与否,需要将该分支指令后的第二条指令地址(PC+8)作为返回地址存入$ra 寄存器
跳转指令
J 无条件转移
J instr_index
无条件转移,转移目标地址由该跳转指令的下一条指令的OC值得高4位与instr_index(26位)左移两位后的值拼接得到
JAL 子程序调用
JAL instr_index
无条件转移到子程序执行。转移目标地址由该跳转指令的下一条指令的OC值得高4位与instr_index(26位)左移两位后的值拼接得到。同时,该跳转指令后的第二条指令地址(PC+8)作为返回地址存入$ra
JR 无条件寄存器转移
JR rs
无条件转移。转移目标地址为寄存器rs的值。
JALR 无条件寄存器跳转到子程序并保存返回地址
JALR rd,rs或JALR rs(默认rd为$ra)
无条件转移至子程序执行。转移目标地址为寄存器rs的值。同时,该跳转指令后的第二条指令地址(PC+8)作为返回地址存入rd,如果不指定rd,则默认存入 $ra。
协处理器指令
MFC0 读CP0中的寄存器
MFC0 rt,rd
将CP0协处理器中的寄存器rd的值存入通用寄存器tr
MTC0 写CP0中的寄存器
MTC0 rt,rd
将通用寄存器rt的值存入CP0协处理器中的寄存器rd中
异常相关指令
SYSCALL 系统调用
SYSCALL
触发系统异常,无条件的转向异常处理程序,并进入内核模式
ERET 异常处理返回
ERET
将CP0协处理器中的14号寄存器(EPC)的值送入PC寄存器,从异常处理程序返回主程序,并将CP0协处理器中的12号寄存器(Status)的EXL清0.