精华内容
下载资源
问答
  • MIPS32位单周期CPU 32MIPS单周期CPU 可以实现16条指令
  • mips32位CPU Mars软件

    2019-02-12 12:12:43
    mips32位CPU Mars软件 重庆大学黄仁课程project,能实现基本指令
  • MIPS 32位CPU中ALU的实现

    2012-03-27 20:34:04
    组成原理实验设计,MIPS 32位CPU中ALU的实现。
  • mips32位ABI标准

    2017-11-09 11:37:31
    mips架构规定的进制ABI标准规范。 对于汇编以及底层的驱动必备
  • mips32位的32个寄存器组成的寄存器组

    热门讨论 2011-03-28 18:08:38
    【寄存器组设计实验】 mips32位字长的32个寄存器组成的寄存器组 用verilog HDL语言描述
  • 基于MIPS32位的ALU设计

    2012-04-26 00:06:33
    包含基于32位mips的ALU的实验代码。
  • MIPS32位单周期CPU

    2012-04-14 11:16:25
    32位MIPS单周期CPU 可以实现16条指令
  • MIPS 32位多周期CPU

    2012-04-23 10:39:34
    MPIS 32位多周期CPU,使用模块设计,简单易懂。
  • 用Verilog HDL 设计的MIPS32位CPU

    热门讨论 2011-07-09 11:49:20
    这是一个学生用Verilog HDL设计的一个完整的MIPS CPU,结构清晰,设计思想非常专业,具有较高的学习参考价值。
  • MIPS32位单周期CPU 32MIPS单周期CPU 可以实现16条指令
  • mips32 一个32Mips处理器,带有一些用Verilog用Altera Quartus II编写的独特指令。
  • MIPS32 Instruction Set

    2012-05-28 12:39:10
    MIPS 32位指令集详细介绍。包含所有32位MIPS指令格式,功能,用途和注意事项。
  • 龙芯32处理器的mips32核结构,适用于龙芯1号系列芯片(1a、1b)。
  • 32位mips处理器

    2015-04-18 20:35:53
    32位mips处理器的rtl级代码.可以实现各种指令功能
  • MIPS32指令集

    2012-12-13 20:14:37
    mips32位指令集,各种指令很全了
  • sshpass_1.06_mips_mips32.ipk

    2019-11-26 14:50:17
    sshpass_1.06_mips_mips32.ipk 支持openwrt固件,CPU类型为mips架构的32处理器架构
  • 32位mips指令说明

    万次阅读 多人点赞 2019-04-27 21:45:32
    从其最高开始向最低方向检查,直到遇到值为“0”的,将该之前“1”的个数保存到地址为rd的通用寄存器中,如果地址为rs的通用寄存器的所有都为1(即OxFFFFFFFF),那么将32保存到地址为rd的通用寄存器中。...

                                 空指令(1条)

    nop指令

                                 逻辑运算指令(8条)

    and、or、xor、nor指令

    • 当功能码是6b100100时,表示是and指令,逻辑“与”运算。

    指令用法为:and  rd,rs,rt。

    指令作用为:rd ← rs AND rt,将地址为rs的通用寄存器的值与地址为rt的通用寄存器的值进行逻辑“与”运算,运算结果保存到地址为rd的通用寄存器中。

    • 当功能码是6b100101时,表示是or指令,逻辑“或”运算

    指令用法为:or  rd,rs,rt。

    指令作用为:rd ← rs OR rt,将地址为rs的通用寄存器的值与地址为rt的通用寄存器的值进行逻辑“或”运算,运算结果保存到地址为rd的通用寄存器中。

    • 当功能码是6b100110时,表示是xor指令,异或运算。

    指令用法为:xor rd,rs,rt。

    指令作用为:rd ← rs XOR rt,将地址为rs的通用寄存器的值与地址为rt的通用寄存器的值进行逻辑“异或”运算,运算结果保存到地址为rd的通用寄存器中。

    • 当功能码是6b100111时,表示是nor指令,或非运算。

    指令用法为:nor rd,rs,rt。

    指令作用为:rd ← rs NOR rt,将地址为rs的通用寄存器的值,与地址为rt的通用寄存器的值进行逻辑“或非”运算,运算结果保存到地址为rd的通用寄存器中。

    andi、xori、ori指令

    • 当指令码是6b001100,表示是andi指令,逻辑“与”运算。

    指令用法为:andi rt,rs,immediate。

    指令作用为:rt ← rs AND zero extended(immediate),将地址为rs的通用寄存器的值与指令中立即数进行零扩展后的值进行逻辑“与”运算,运算结果保存到地址为rt的通用寄存器中。

    • 当指令码是6b001110,表示是xori指令,异或运算。

    指令用法为:xori rt,rs,immediate。

    指令作用为:rt ← rs XOR zero_extended(immediate),将地址为rs的通用寄存器的值与指令中立即数进行零扩展后的值进行逻辑“异或”运算,运算结果保存到地址为rt的通用寄存器中。

    • 当指令码是6b001101,表示是ori指令,或运算。

    指令用法为:ori rs,rt,immediate,作用是将指令中的16位立即数进行无符

    号扩展至32位,然后与索引为rs的通用寄存器的值进行逻辑“或”运算,运算结果保存到索引为rt的通用寄存器中。

    lui指令

    • 指令用法为:lui rt,immediate。

    指令作用为:rt ← immediate ll 016,将指令中的16bit立即数保存到地址为rt的通用寄存器的高16位。另外,地址为rt的通用寄存器的低16位使用0填充。

     

                                 移位指令(6条)

    sll、sllv,sra、srav、srl、srlv 指令

    • 当功能码是6b000000,表示是sll指令,逻辑左移。

    指令用法为:sll rd,rt,sa。

    指令作用为:rd ← rt << sa(logic),将地址为rt的通用寄存器的值向左移sa位,空出来的位置使用0填充,结果保存到地址为rd的通用寄存器中。

    • 当功能码是6b000010,表示是srl指令,逻辑右移。

    指令用法为:srl rd,rt,sa。

    指令作用为:rd ← rt >> sa(logic),将地址为rt的通用寄存器的值向右移sa位,空出来的位置使用0填充,结果保存到地址为rd的通用寄存器中。

    • 当功能码是6b000011,表示是sra指令,算术右移。

    指令用法为:sra rd,rt,sa。

    指令作用为:rd ← rt >> sa(arithmetic),将地址为rt的通用寄存器的值向右移sa位,空出来的位置使用r[31]的值填充,结果保存到地址为rd的通用寄存器中。

    • 当功能码是6b000100,表示是sllv指令,逻辑左移。

    指令用法为:sllv rd,rt,rs。

    指令作用为:rd ← rt << rs[4:0](logic),将地址为rt的通用寄存器的值向左移位,空出来的位置使用0填充,结果保存到地址为rd的通用寄存器中。移位位数由地址为rs的寄存器值的第0-4bit确定。

    • 当功能码是6b000110,表示是srlv指令,逻辑右移。

    指令用法为:srlv rd,rt,rs。

    指令作用为:rd ← rt >> rs[4:0](logic),将地址为rt的通用寄存器的值向右移位,空出来的位置使用0填充,结果保存到地址为rd的通用寄存器中。移位位数由地址为rs的寄存器值的第0-4bit确定。

    • 当功能码是6b000111,表示是srav指令,算术右移。

    指令用法为:srav rd,rt,rs。

    指令作用为:rd ← rt >> rs[4:0](arithmetic),将地址为rt的通用寄存器的值向右移位,空出来的位置使用rt[31]填充,结果保存到地址为rd的通用寄存器中。移位位数由地址为rs的寄存器值的第0-4bit确定。

    总结来说,这6条移位操作指令可以分为两种情况:sllv、srav、srlv这3条指令的助记符最后有“v”,表示移位位数是通过寄存器的值确定的,sl、sra、srl这3条指令的助记符最后没有“v”,表示移位位数就是指令中第6-10bit的sa值。

                              移动操作指令(6条)

    movn、movz、mfhi、mthi、mflo、mtlo指令

    • 当功能码为6b001011时,表示是movn指令。

    指令用法为:movn rd,rs,rt。

    指令作用为:if rt ≠ 0 then rd ← rs,判断地址为rt的通用寄存器的值。如果不为零,那么将地址为rs的通用寄存器的值赋给地址为rd的通用寄存器;反之,保持地址为rd的通用寄存器不变。movn是Move Conditional on Not Zero的意思。

    • 当功能码为6b001010时,表示是movz指令。

    指令用法为:movz rd,rs,rt。

    指令作用为:if rt = 0 then rd ← rs,与上面movn指令的作用正好相反,判断地址为rt的通用寄存器的值。如果为零,那么将地址为rs的通用寄存器的值赋给地址为rd的通用寄存器;反之,保持地址为rd的通用寄存器不变。movz是Move Conditional on Zero的意思。

    • 当功能码为6b010000时,表示是mfhi指令。

    指令用法为:mfhi rd。

    指令作用为:rd ← hi,将特殊寄存器HI的值赋给地址为rd的通用寄存器。

    • 当功能码为6b010010时,表示是mflo指令。

    指令用法为:mflo rd。

    指令作用为:rd ← lo,将特殊寄存器LO的值赋给地址为rd的通用寄存器。

    • 当功能码为6b010001时,表示是mthi指令。

    指令用法为:mthi rs。

    指令作用为;hi ← rs,将地址为rs的通用寄存器的值赋给特殊寄存器HI。

    • 当功能码为6b010011时,表示是mtlo指令。

    指令用法为:mtlo rs。

    指令作用为:lo ← rs,将地址为rs的通用寄存器的值赋给特殊寄存器LO。

                             算术操作指令(21条)

    add、addu、sub、subu、slt,sltu 指令

    • 当功能码是6b100000时,表示add指令,加法运算。

    指令用法为:add rd,rs,rt。

    指令作用为:rd ← rs+rt,将地址为rs的通用寄存器的值与地址为rt的通用寄存器的值进行加法运算,结果保存到地址为rd的通用寄存器中。但是有一种特殊情况:如果加法运算溢出,那么会产生溢出异常,同时不保存结果。

    • 当功能码是6b100001时,表示addu指令,加法运算。

    指令用法为:addu rd,rs,rt。

    指令作用为:rd ← rs+rt,将地址为rs的通用寄存器的值与地址为rt的通用寄存器的值进行加法运算,结果保存到地址为rd的通用寄存器中。add指令的不同之处在于addu指令不进行溢出检查,总是将结果保存到目的寄存器。

    • 当功能码是6b100010时,表示sub指令,减法运算。

    指令用法为:sub rd,rs,rt。

    指令作用为:rd ← rs-rt,将地址为rs的通用寄存器的值与地址为rt的通用寄存器的值进行减法运算,结果保存到地址为rd的通用寄存器中。但是有一种特殊情况:如果减法运算溢出,那么产生溢出异常,同时不保存结果。

    • 当功能码是6b100011时,表示subu指令,减法运算。

    指令用法为:subu rd,rs,rt。

    指令作用为:rd ← rs-rt,将地址为rs的通用寄存器的值与地址为rt的通用寄存器的值进行减法运算,结果保存到地址为rd的通用寄存器中。与sub指令的不同之处在于:subu指令不进行溢出检查,总是将结果保存到目的寄存器。

    • 当功能码是6b101010时,表示slt指令,比较运算。

    指令用法为:slt rd,rs,rt。

    指令作用为:rd ←(rs<rt),将地址为rs的通用寄存器的值与地址为rt的通用寄存器的值按照有符号数进行比较,如果前者小于后者,那么将1保存到地址为rd的通用寄存器中;反之,将0保存到地址为rd的通用寄存器中。

    • 当功能码是6b101011时,表示sltu指令,比较运算。

    指令用法为:sltu rd,rs,rt。

    指令作用为:rd ←(rs<rt),将地址为rs的通用寄存器的值与地址为rt的通用寄存器的值按照无符号数进行比较,如果前者小于后者,那么将1保存到地址为rd的通用寄存器中;反之,将0保存到地址为rd的通用寄存器中。

    addi,addiu、slti、sltiu 指令

    • 当指令码是6b001000时,表示addi指令,加法运算。

    指令用法为:addi rt,rs,immediate。

    指令作用为:rt ← rs+(sign_extended)immediate,将指令中的16位立即数进行符号扩展,与地址为rs的通用寄存器的值进行加法运算,结果保存到地址为rt的通用寄存器中。但是有一个特殊情况:如果加法运算溢出,那么产生溢出异常,同时不保存结果。

    • 当指令码是6b001001时,表示addiu指令,加法运算。

    指令用法为:addiu rt,rs,immediate。

    指令作用为:rt ← rs+(sign_extended)immediate,将指令中的16位立即数进行符号扩展,与地址为rs的通用寄存器的值进行加法运算,结果保存到地址为rt的通用寄存器中。与addi指令的区别在于:addiu指令不进行溢出检查,总是将结果保存到目的寄存器。

    • 当指令码是6b001010时,表示slti指令,比较运算。

    指令用法为:slti rt,rs,immediate。

    指令作用为:rt ←(rs <(sign_extended)immediate),将指令中的16位立即数进行符号扩展,与地址为rs的通用寄存器的值按照有符号数进行比较,如果前者大于后者,那么将1保存到地址为rt的通用寄存器中;反之,将0保存到地址为rt的通用寄存器中。

    • 当指令码是6b001011时,表示sltiu指令,比较运算。

    指令用法为:sltiu rt,rs,immediate。

    指令作用为:rt ←(rs <(sign_extended)immediate),将指令中的16位立即数进行符号扩展,与地址为rs的通用寄存器的值按照无符号数进行比较,如果前者大于后者,那么将1保存到地址为rt的通用寄存器中;反之,将0保存到地址为rt的通用寄存器中。

    clo、clz指令

    • 当功能码是6b100000时,表示clz指令,计数运算。

    指令用法为:clz rd,rs。

    指令作用为:rd ← count_leading_zeros rs,对地址为rs的通用寄存器的值,从其最高位开始同最低位方向检查,直到遇到值为“1”的位,将该位之前“0”的个数保存到地址为rd的通用寄存器中,如果地址为rs的通用寄存器的所有位都为0(即0x00000000),那么将32保存到地址为rd的通用寄存器中。

    • 当功能码是6b100001时,表示clo指令,计数运算。

    指令用法为:clo rd,rs。

    指令作用为:rd ← count_leading_ones rs,对地址为rs的通用寄存器的值,从其最高位开始向最低位方向检查,直到遇到值为“0”的位,将该位之前“1”的个数保存到地址为rd的通用寄存器中,如果地址为rs的通用寄存器的所有位都为1(即OxFFFFFFFF),那么将32保存到地址为rd的通用寄存器中。

    multu、mult,mul 指令

    • 当指令码为SPECIAL2,功能码为6b000010时,表示mul指令,乘法运算

    指令用法为:mul rd,rs,st。

    指令作用为:rd ← rs×rt,将地址为rs的通用寄存器的值与地址为rt的通用寄存器的值作为有符号数相乘,乘法结果的低32bit保存到地址为rd的通用寄存器中。

    • 当指令码为SPECIAL,功能码为6b011000时,表示mult指令,乘法运算

    指令用法为:mult rs,st。

    指令作用为:{hi,lo} ← rs×rt,将地址为rs的通用寄存器的值与地址为rt的通用寄存器的值作为有符号数相乘,乘法结果的低32bit保存到LO寄存器中,高32bit保存到HI寄存器中。

    • 当指令码为SPECIAL,功能码为6b011001时,表示multu指令,乘法运算

    指令用法为:multu rs,st。

    指令作用为:{hi,lo} ← rs×rt,将地址为rs的通用寄存器的值与地址为rt的通用寄存器的值作为无符号数相乘,乘法结果的低32bit保存到LO寄存器中,高32bit保存到HI寄存器中。与mult指令的区别在于:multu指令执行中将操作数作为无符号数进行运算。

    madd、maddu、msub、msubu指令(复杂)

     

    • 当功能码是6b000000时,表示是madd指令,有符号乘累加运算。

    指令用法为:madd rs,rt。

    指令作用为:{HL,LO} ← {HI,LO}+rs×rt,将地址为rs的通用寄存器的值与地址为rt的通用寄存器的值作为有符号数进行乘法运算,运算结果与{HI,LO}相加,相加的结果保存到{HI,LO}中。此处{HI,LO}表示HI、LO寄存器连接形成的64位数,HI是高32位,LO是低32位。

    • 当功能码是6b000001时,表示是maddu指令,无符号乘累加运算。

    指令用法为:maddu rs,rt。

    指令作用为:{HI,LO} ← {HI,LO}+rs×rt,将地址为rs的通用寄存器的值与地址为rt的通用寄存器的值作为无符号数进行乘法运算,运算结果与{HI,LO}相加,相加的结果保存到{HI,LO}中。

    • 当功能码是6b000100时,表示是msub指令,有符号乘累减运算。

    指令用法为:msub rs,rt。

    指令作用为:{HI,LO} ← {HI,LO}-rs×t,将地址为rs的通用寄存器的值与地址为rt的通用寄存器的值作为有符号数进行乘法运算。然后使用{HI,LO}减去乘法结果,相减的结果保存到{HI,LO}中。

    • 当功能码是6b000101时,表示是msubu指令,无符号乘累减运算。

    指令用法为:msubu rs,rt。

    指令作用为:{HI,LO} ← {Hl,LO}-rs×rt,将地址为rs的通用寄存器的值与地址为rt的通用寄存器的值作为无符号数进行乘法运算。然后使用{HI,LO}减去乘法结果,相减的结果保存到{H1,LO}中。

    div、divu指令

    • 当功能码是6b011010时,表示是div指令,有符号除法运算。

    指令用法为:div rs,rt。

    指令作用为:{HI,LO} ← rs/rt,将地址为rs的通用寄存器的值,与地址为rt的通用寄存器的值,作为有符号数进行除法运算,将商保存到寄存器LO,余数保存到寄存器HI。

    • 当功能码是6b011011时,表示是divu指令,无符号除法运算。

    指令用法为:divu rs,rt。

    指令作用为:{HI,LO} ← rs/rt,将地址为rs的通用寄存器的值,与地址为rt的通用寄存器的值,作为无符号数进行除法运算,将商保存到寄存器LO,余数保存到寄存器HI。

                            转移指令(14条)

    jr、jalr、j、jal(跳转指令)

    • 当指令中的指令码为SPECIAL,功能码为6b001000时,表示jr指令。

    指令用法为:jr rs。

    指令作用为:pc ← rs,将地址为rs的通用寄存器的值赋给寄存器PC,作为新的指令地址。

    • 当指令中的指令码为SPECIAL,功能码为6b001001时,表示jalr指令。

    指令用法为:jalr rs或者jalr rd,rs。

    指令作用为:rd ← return address,pe ← rs,将地址为rs的通用寄存器的值赋给寄存器PC,作为新的指令地址,同时将跳转指令后面第2条指令的地址作为返回地址保存到地址为rd的通用寄存器,如果没有在指令中指明rd,那么默认将返回地址保存到寄存器$31。

    • 当指令中的指令码为6b000010时,表示j指令。

    指令用法为:j target。

    指令作用为:pc ←(pc+4)[31,28]|| target || ‘00',转移到新的指令地址,其中新指令地址的低28位是指令中的target(也就是上图中的instr_index)左移两位的值,新指令地址的高4位是跳转指令后面延迟槽指令的地址高4位。

    • 当指令中的指令码为6b000011时,表示jal指令。

    指令用法为:jal target。

    指令作用为:pc ←(pc+4)[31,28]||target||‘00’,转移到新的指令地址,新指令地址与指令j相同,不再解释。但是,指令jal还要将跳转指令后面第2条指令的地址作为返回地址保存到寄存器$31。

    b、bal、beq、bgez、bgezal、bgtz、blez、bltz、bltzal、bne(分支指令)

    从图中可知,前5条指令beq、b、bgtz、blez、bne可以直接依据指令中的指令码进行判断,确定是哪一条指令,而后5条指令bltz、bltzal、bgez、bgezal、bal的指令码都是REGIMM,这是一个宏定义,值为6b000001,需要根据指令中16-20bit的值进一步判断,从而确定是哪一条指令。

    从图中还可知,所有分支指令的第0-15bit存储的都是offset,如果发生转移,那么将offset左移2位,并符号扩展至32位,然后与延迟槽指令的地址相加,加法的结果就是转移目的地址,从该地址取指令。

                                  转移目标地址=(signed_extend)(offset ||“00”)+(pc+4)

    • 当指令中的指令码为6b000100时,表示beq指令。

    指令用法为:beq rs,rt,offset。

    指令作用为:if rs=rt then branch,将地址为rs的通用寄存器的值与地址为rt的通用寄存器的值进行比较,如果相等,那么发生转移。

    • 当指令中的指令码为6b000100,且16-25bit为0时,表示b指令。

    指令用法为:b offset。

    指令作用为:无条件转移,从图中可知,b指令可以认为是beq指令的特殊情况,当beq指令的rs、rt都等于0时,即为b指令,所以在实现的时候不需要特意实现b指令,只需要实现beq指令即可。

    • 当指令中的指令码为6b000111时,表示bgtz指令。

    指令用法为:bgtz rs,offset。

    指令作用为:if rs>0 then branch,如果地址为rs的通用寄存器的值大于零,那么发生转移。

    • 当指令中的指令码为6b000110时,表示blez指令。

    指令用法为:blez rs,offset。

    指令作用为:if rs≤0 then branch,如果地址为rs的通用寄存器的值小于等于零,那么发生转移。

    • 当指令中的指令码为6b000101时,表示bne指令。

    指令用法为:bne rs,rt,offset。

    指令作用为:if rs≠rt then branch,如果地址为rs的通用寄存器的值不等于地址为rt的通用寄存器的值,那么发生转移。

    • 当指令中的指令码为REGIMM,且第16-20bit为5b00000时,表示bltz指令。

    指令用法为:bltz rs,offset。

    指令作用为:if rs<0 then branch,如果地址为rs的通用寄存器的值小于0,那么发生转移。

    • 当指令中的指令码为REGIMM,且第16-20bit为5b10000时,表示bltzal指令。

    指令用法为:bltzal rs,offset。

    指令作用为:if rs<0 then branch,如果地址为rs的通用寄存器的值小于0,那么发生转移,并且将转移指令后面第2条指令的地址作为返回地址,保存到通用寄存器$31。

    • 当指令中的指令码为REGIMM,且第16-20bit为5b00001时,表示bgez指令。

    指令用法为:bgez rs,offset。

    指令作用为:if rs≥0 then branch,如果地址为rs的通用寄存器的值大于等于0,那么发生转移。

    • 当指令中的指令码为REGIMM,且第16-20bit为5b10001时,表示bgezal指令。

    指令用法为:bgezal rs,offset。

    指令作用为:if rs≥0 then branch,如果地址为rs的通用寄存器的值大于等于0,那么发生转移,并且将转移指令后面第2条指令的地址作为返回地址,保存到通用寄存器$31。

    • 当指令中的指令码为REGIMM,且第21-25bit为0,第16-20bit为5b10001时,表示bal指令。

    指令用法为:bal offset。

    指令作用为:无条件转移,并且将转移指令后面第2条指令的地址作为返回地址,保存到通用寄存器$31。从上图的指令格式可知,bal指令是bgezal指令的特殊情况,当bgezal指令的rs为0时,就是bal指令,所以在实现时,不用特意考虑bal指令,只要实现bgezal指令即可。

    综上,b、bal指令不用单独实现,需要实现的分支指令只有8条。

                            加载存储指令(14条)

    加载指令lb、lbu、Ih、Ihu、lw说明

    从图9-1可知,这5条加载指令可以根据指令中26-31bit的指令码加以区分,另外,加载指令的第0-15bit是offset、第21-15bit是base,加载地址的计算方法如下,先将16位的offset符号扩展至32位,然后与地址为base的通用寄存器的值相加,即可得到加载地址。

         加载地址=signed_extended(offset)+GPR[base]

    下面分别介绍各个加载指令的作用。

    • 当指令中的指令码为6b100000时,是lb指令,字节加载指令。

    指令用法为:lbrt,offset(base)。

    指令作用为:从内存中指定的加载地址处,读取一个字节,然后符号扩展至32位,保存到地址为rt的通用寄存器中。

    • 当指令中的指令码为6b100100时,是lbu指令,无符号字节加载指令。

    指令用法为:lbu rt,offset(base)。

    指令作用为:从内存中指定的加载地址处,读取一个字节,然后无符号扩展至32位,保存到地址为rt的通用寄存器中。

    • 当指令中的指令码为6bl00001时,是lh指令,半字加载指令。

    指令用法为:lh rt,offset(base)。

    指令作用为:从内存中指定的加载地址处,读取一个半字,然后符号扩展至32位,保存到地址为rt的通用寄存器中。该指令有地址对齐要求,要求加载地址的最低位为0。

    • 当指令中的指令码为6'b100101时,是lhu指令,无符号半字加载指令。

    指令用法为:lhu rt,offset(base)。

    指令作用为:从内存中指定的加载地址处,读取一个半字,然后无符号扩展至32位,保存到地址为rt的通用寄存器中。该指令有地址对齐要求,要求加载地址的最低位为0。

    • 当指令中的指令码为6b100011时,是lw指令,字加载指令。

    指令用法为:lw rt,offset(base)。

    指令作用为:从内存中指定的加载地址处,读取一个字,保存到地址为rt的通用寄存器中。该指令有地址对齐要求,要求加载地址的最低两位为00。

    存储指令sb、sh、sw说明

    从上图可知,这3条存储指令可以根据指令中26-31bit的指令码加以区分,另外,存储指令的第0-15bit是ofset、第21-15bit是base,存储地址的计算方法如下,先将16位的offset符号扩展至32位,然后与地址为base的通用寄存器的值相加,即可得到存储地址。

     存储地址=signed_extended(ofset)+GPR[base]

    下面分别介绍各个存储指令的作用。

    • 当指令中的指令码为6b101000时,是sb指令,字节存储指令。

    指令用法为:sb rt,offset(base)。

    指令作用为:将地址为rt的通用寄存器的最低字节存储到内存中的指定地址。

    • 当指令中的指令码为6b101001时,是sh指令,半字存储指令。

    指令用法为:sh rt,offset(base)。

    指令作用为:将地址为rt的通用寄存器的最低两个字节存储到内存中的指定地址。该指令有地址对齐要求,要求计算出来的存储地址的最低位为0。

    • 当指令中的指令码为6b101011时,是sw指令,字存储指令。

    指令用法为:sw rt,offset(base)。

    指令作用为:将地址为rt的通用寄存器的值存储到内存中的指定地址。该指令有地址对齐要求,要求计算出来的存储地址的最低两位为00。

    加载指令lwl、lwr说明

    • 当指令中的指令码为6b100010时,是lwl指令,非对齐加载指令,向左加载。

    指令用法为:lwl rt,offset(base)。

    指令作用为:从内存中指定的加载地址处,加载一个字的最高有效部分。lwl指令对加载地址没有要求,从而允许地址非对齐加载,这是与前面介绍的lh、lhu、lw指令的不同之处。在大端模式、小端模式下,lwl指令的效果不同,因为OpenMIPS是大端模式,所以此处只介绍在大端模式下lwl指令的效果。假设计算出来的加载地址是loadaddr,loadaddr的最低两位的值为n,将loadaddr最低两位设为0后的值称为loadaddr_align,如下。

      加载地址loadaddr=signed_extended(ofset)+GPR[base]

      n=loadaddr{1:0]

      loadaddr_align=loadaddr-n

    例如:假设计算出来的加载地址是5,lwl指令要从地址5加载数据,那么loadaddr就等于5,n等于1,loadaddr_align等于4。

    lwl指令的作用是从地址为loadaddr align处加载一个字,也就是4个字节,然后将这个字的最低4-n个字节保存到地址为rt的通用寄存器的高位,并且保持低位不变。

    继续上例,此时loadaddr_align为4,所以从地址4处加载一个字,对应的是地址为4、5、6、7的字节,因为n等于1,所以将加载到的字的最低3个字节保存到地址rt的通用寄存器的高3个字节。如下图所示。一个更加通用的描述如下图所示。

     

    • 当指令中的指令码为6b100110时,是lwr指令,非对齐加载指令,向右加载。

    指令用法为:lwr rt,offset(base)。

    指令作用为:从内存中指定的加载地址处,加载一个字的最低有效部分。还是假设计算出来的加载地址是loadaddr,loadaddr的最低两位的值为n,将loadaddr最低两位设为0后的值称为loadaddr_align,如下。

                          加载地址loadaddr=signed_extended(offset)+GPR[base]

                           n=loadaddr[1:0]

                           loadaddr_align=loadaddr-n

    例如:假设计算出来的加载地址是9,lwr指令要从地址9加载数据,那么loadaddr就等于9,n等于1,loadaddr_align等于8。lwr 指令的作用是从地址为loadaddr_align处加载一个字,也就是4个字节,然后将这个字的最高n+l个字节保存到地址为rt的通用寄存器的低位,并且保持高位不变。继续上例,此时loadaddr_align为8,所以从地址8处加载一个字,对应的是地址为8、9、10、11的字节,因为n等于1,所以将加载到的字的最高2个字节保存到地址rt的通用寄存器的低2个字节。如下图所示。一个更加通用的描述如下图所示。lwl与lwr指令配合可以实现从一个非对齐地址加载一个字,而且只需要使用2条指令,提高了效率。例如:使用一般指令从地址7处加载一个字,那么可以使用以下代码实现,共5条指令。

    lw  $1,4($0)   #取得地址0x4处的字,保存在$1中

    lw  $2,8($0)   #取得地址0x8处的字,保存在$2中

    sll $1,$1,24     #$1左移24位

    slr $2,$2,8       #$2右移8位

    or  $1,S1,$2    #$1与$2进行逻辑“或”运算,得到最终结果

    存储指令swl、swr说明

    • 当指令中的指令码为6b101010时,是swl指令,非对齐存储指令,向左存储。

    指令用法为:swl rt,offset(base)。

    • 当指令中的指令码为6b101110时,是swr指令,非对齐存储指令,向右存储。

    指令用法为:swr rt,offset(base)。

    存储地址storeaddr = signed_extended(offset)+GPR[base]

    n=storeaddr[1:0]

    storeaddr_align = storeaddr – n

     

    展开全文
  • 用gdb-7.11编译的gdbserver,...ELF 32-bit MSB executable, MIPS, MIPS32 rel2 version 1 (SYSV), statically linked, for GNU/Linux 3.2.0, BuildID[sha1]=062b51edc22a5ae78fc1f31debbc534c6accce84, not stripped
  • 基于MIPS指令集的32位CPU设计与VHDL实现基于MIPS指令集的32位CPU设计与VHDL实现基于MIPS指令集的32位CPU设计与VHDL实现基于MIPS指令集的32位CPU设计与VHDL实现基于MIPS指令集的32位CPU设计与VHDL实现基于MIPS指令集...
  • MIPs32寄存器

    2019-12-07 16:47:08
    description: Mips 32MIPs寄存器的作用 一. 简介  MIPS32个通用寄存器($0-$31),各寄存器的功能及汇编程序中使用约定如下:  下表描述32个通用寄存器的别名和用途 REGISTER NAME USAGE ...

    title: Mips-register
    date: 2019-12-07 14:54:25
    description: Mips 32个MIPs寄存器的作用

    一. 简介

     MIPS有32个通用寄存器($0-$31),各寄存器的功能及汇编程序中使用约定如下:

     下表描述32个通用寄存器的别名和用途

    REGISTERNAMEUSAGE
    $0$zero常量0(constant value 0)
    $1$at保留给汇编器(Reserved for assembler)
    $2-$3 v 0 − v0- v0v1函数调用返回值(values for results and expression evaluation)
    $4-$7 a 0 − a0- a0a3函数调用参数(arguments)
    $8-$15 t 0 − t0- t0t7暂时的(或随便用的)
    $16-$23 s 0 − s0- s0s7保存的(或如果用,需要SAVE/RESTORE的)(saved)
    $24-$25 t 8 − t8- t8t9暂时的(或随便用的)
    $28$gp全局指针(Global Pointer)
    $29$sp堆栈指针(Stack Pointer)
    $30$fp帧指针(Frame Pointer)
    $31$ra返回地址(return address)

    二. 详细说明

    $0: 即$zero,该寄存器总是返回零,为0这个有用常数提供了一个简洁的编码形式。

    move $t0,$t1
    

    实际为

    add $t0,$0,$t1
    

    使用伪指令可以简化任务,汇编程序提供了比硬件更丰富的指令集。

    $1: 即$at,该寄存器为汇编保留,由于I型指令的立即数字段只有16位,在加载大常数时,编译器或汇编程序需要把大常数拆开,然后重新组合到寄存器里。比如加载一个32位立即数需要 lui(装入高位立即数)和addi两条指令。像MIPS程序拆散和重装大常数由汇编程序来完成,汇编程序必需一个临时寄存器来重组大常数,这也是为汇编 保留$at的原因之一。

    $2…$3: ($v0-$v1)用于子程序的非浮点结果或返回值,对于子程序如何传递参数及如何返回,MIPS范围有一套约定,堆栈中少数几个位置处的内容装入CPU寄存器,其相应内存位置保留未做定义,当这两个寄存器不够存放返回值时,编译器通过内存来完成。

    $4…$7: ($a0-$a3)用来传递前四个参数给子程序,不够的用堆栈。a0-a3和v0-v1以及ra一起来支持子程序/过程调用,分别用以传递参数,返回结果和存放返回地址。当需要使用更多的寄存器时,就需要堆栈(stack)了,MIPS编译器总是为参数在堆栈中留有空间以防有参数需要存储。

    $8…$15: ($t0-$t7)临时寄存器,子程序可以使用它们而不用保留。

    $16…$23: ($s0-$s7)保存寄存器,在过程调用过程中需要保留(被调用者保存和恢复,还包括$fp和$ra),MIPS提供了临时寄存器和保存寄存器,这样就减少了寄存器溢出(spilling,即将不常用的变量放到存储器的过程),编译器在编译一个叶(leaf)过程(不调用其它过程的过程)的时候,总是在临时寄存器分配完了才使用需要保存的寄存器。

    $24…$25: ($t8-$t9)同($t0-$t7)

    $26…$27: ($k0,$k1)为操作系统/异常处理保留,至少要预留一个。 异常(或中断)是一种不需要在程序中显示调用的过程。MIPS有个叫异常程序计数器(exception program counter,EPC)的寄存器,属于CP0寄存器,用于保存造成异常的那条指令的地址。查看控制寄存器的唯一方法是把它复制到通用寄存器里,指令mfc0(move from system control)可以将EPC中的地址复制到某个通用寄存器中,通过跳转语句(jr),程序可以返回到造成异常的那条指令处继续执行。MIPS程序员都必须保留两个寄存器$k0和$k1,供操作系统使用。

     发生异常时,这两个寄存器的值不会被恢复,编译器也不使用k0和k1,异常处理函数可以将返回地址放到这两个中的任何一个,然后使用jr跳转到造成异常的指令处继续执行。

    $28: ($gp)为了简化静态数据的访问,MIPS软件保留了一个寄存器:全局指针gp(global pointer,$gp),全局指针只想静态数据区中的运行时决定的地址,在存取位于gp值上下32KB范围内的数据时,只需要一条以gp为基指针的指令即可。在编译时,数据须在以gp为基指针的64KB范围内。

    $29: ($sp)MIPS硬件并不直接支持堆栈,你可以把它用于别的目的,但为了使用别人的程序或让别人使用你的程序, 还是要遵守这个约定的,但这和硬件没有关系。

    $30: ($fp)GNU MIPS C编译器使用了帧指针(frame pointer),而SGI的C编译器没有使用,而把这个寄存器当作保存寄存器使用($s8),这节省了调用和返回开销,但增加了代码生成的复杂性。

    $31: ($ra)存放返回地址,MIPS有个jal(jump-and-link,跳转并 链接)指令,在跳转到某个地址时,把下一条指令的地址放到$ra中。用于支持子程序,例如调用程序把参数放到$a0~$a3,然后jal X跳到X过程,被调过程完成后把结果放到$v0,$v1,然后使用jr $ra返回。

    展开全文
  • 为数字消费、家庭网络、无线、通信和商业应用提供业界标准处理器架构与内核的领导厂商 MIPS 科技(MIPS Technologies, Inc)宣布,Altera 公司已获得MIPS32TM 架构授权,此举标志 MIPSTM 架构正式进入 FPGA 领域。...
  • 用ISE开发的基于31条MIPS指令(Minisys)的RISC架构的CPU
  • MIPS 科技宣布,意法半导体... MIPS64 架构为强大、高性能的 MIPS:registered: 处理器提供了重要基础,并为 MIPS32:registered: 架构带来了向上兼容性。MIPS 科技于几年前开发 64 处理器架构,当时由 MIPS 的创始
  • 本设计实现了一个具有标准的32位5级流水线架构的MIPS指令兼容CPU系统。具备常用的五余条指令,解决了大部分数据相关,结构相关,乘除法的流水化处理等问题
  • MIPS32-单周期仿真器 内置于C中的MIPS32单周期模拟器
  • 32位mips CPU verilog代码实现
  • The MIPS32 Instruction Set 详细介绍了MIPS指令
  • 手撸MIPS32——1、MIPS32指令集

    千次阅读 2020-05-18 12:33:01
    (MIPS32 Release1指令集的子集MiniMIPS32) 通用寄存器命名和使用约定 运算指令 ALU立即数指令 在立即数这里,rt相当于目的寄存器,rs相当于源寄存器,imm立即数 ADDI 加立即数可触发溢出异常 ADDI rt,rs,imm 将rs与...

    (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.

    展开全文

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 30,205
精华内容 12,082
关键字:

mips32位