MIPS指令集:运算指令、访存指令、分支和跳转、协处理器0指令

您所在的位置:网站首页 调用和返回指令属于转移指令 MIPS指令集:运算指令、访存指令、分支和跳转、协处理器0指令

MIPS指令集:运算指令、访存指令、分支和跳转、协处理器0指令

#MIPS指令集:运算指令、访存指令、分支和跳转、协处理器0指令| 来源: 网络整理| 查看: 265

       计算机指令就是指挥机器工作的指示和命令,程序就是一系列按一定顺序排列的指令,执行程序的过程就是计算机的工作过程。通常一条指令包括两方面的内容: 操作码和操作数,操作码决定要完成的操作,操作数指参加运算的数据及其所在的单元地址。MIPS所有指令都是32位的,操作码占用高6位(bit31-bit26)表示,低26位按格式划分为R型、I型和J型。但是按mips指令的功能划分,分别介绍运算指令、访存指令、分支和跳转指令、原子指令等。

同时在学习MIPS指令时,需要了解64位处理器中,CPU一次可以从主存加载的操作数有1字节、2字节、4字节和8字节。在c语言和汇编中的对应关系如下表:

c语言

MIPS名称

大小(字节)

汇编助记符

char

byte

1

lb中的“b”

short

halfword

2

lh中的“h”

int

word

4

lw中的“w”

long(long long)

dword

8

ld中的“d”

                                     表1 c语言数据类型大小和汇编助记符

 

理解了表1中,在接下来的汇编语言学习中,当加载数据时就能清楚的知道该使用那种指令。

1 运算指令

运算型指令完成寄存器值的算术、逻辑、移位、乘法和除法等操作。运算型指令包含了寄存器指令格式(R型)和立即数指令格式(I型),运算方式有三目运算和两目运算。 下面我们详细介绍:

1.1 加减运算

mips中和加法运算相关的指令如下:

指令

格式

功能概述

ADD

ADD  rd,rs,rt

加法

ADDU

ADDU rd, rs, rt

无溢出检测加法

ADDI

ADDI  rd,rs,immediate

带立即数的加法

ADDIU

ADDIU rt, rs, immediate

无溢出检测的带立即数的加法

DADD

DADD rd, rs, rt

64位加法

DADDU

DADDU rd, rs, rt

64位无溢出检测加法

DADDI

DADDI rt, rs, immediate

64位带立即数加法

DADDIU

DADDIU rt, rs, immediate

64位无溢出检测立即数加法

SUB

SUB rd, rs, rt

减法

SUBU

SUBU rd, rs, rt

无溢出检测的减法

DSUB

DSUB rd, rs, rt

64位减法

DSUBU

DSUBU rd, rs, rt

64位无溢出检测的减

                                                                                表2 加法/减法指令

 

从上表可以看出,MIPS加法指令可以完成两个寄存器的加法运算、寄存器和立即数的运算。运算可以是32位的也可以是64位的(带D标识的)。其中rd、rs、rt是通用寄存器的任意一个。这里有“U”的代表“无溢出检测”,否则就是有溢出检测。比如下面例子:

                         add t0,a0,a1    # t0=a0+a1

                         addu t0,a0,a1  # t0=a0+a1

这两句都实现的是a0+a1,结果存入t0。但是add 指令对加结果有溢出检测(仅支持有符号运算),如果a0+a1结果有溢出的话,那么t0不会被改变,程序会报“整型溢出异常”。而addu指令表示“无溢出检测”,a0+a1的结果直接存入t0。

c和c++语言不支持“整型溢出异常”,所以总是使用带”U”的指令。

这里的“I”代表立即数。立即数就是嵌入在指令中的常数。加法运算中的立即数都占用16位,所以都需要有符号扩展到32位或者64位,然后再参与加法运算,比如下面的指令:

                     addiu t0,a0,0x3           # t0=a0+sign_extend(0x3)

                     daddiu t0,a0,0x3         #t0=a0+sign_extend(0x3)

同样是实现寄存器a0和立即数0x3的加法运算,但是addiu首先把立即数0x3进行有符号扩展(sign_extend)到32位,然后和寄存器a0进行加法操作,正确结果被存入t0。而daddiu实现的是64位加法运算,所以需要先把立即数0x3进行有符号扩展(sign_extend)到64位,然后和寄存器a0进行加法操作,正确结果被存入t0。

这里解释一下为何要对立即数进行有符号扩展。下图是addiu指令的具体格式:

                                                           图2 addiu指令格式

从上图可以看出,addiu是I型指令,立即数占用16位。而addiu实现的是32位加法操作,所以需要把立即数进行符号扩展到32位,然后和rs(a0)进行加法操作,结果存入rt。

再介绍一下符号扩展。符号扩展是指计算机对于小字节转换成大字节的规则。比如要16个字节的数转换成32字节,多出来的16个字节到底怎么填充?mips指令集中会经常需要将其中的立即数进行符号扩展。符号扩展分无符号扩展和有符号扩展,区别如下:

16位立即数

0x8000

0xe000

有符号扩展到32位

0xffff8000

0x0000e000

无符号扩展到32

0x00008000

0x0000e000

                                                                   表3 符号扩展方式

从上表可以看出,有符号扩展就是高位填充的值取决于这个数扩展前的最高位。扩展前的数高位为1,那么扩展出来的高位就都是1,扩展前的数高位为0,那么扩展出来的高位就都是0。而无符号扩展就是无论扩展前的数是多少,扩展出来的高位都是0。

减法指令中没有带立即数的操作,只区别是32位和64位减法,减法是否有溢出。比如:

            sub t0,a0,a1 # t0 = a0-a1

             dsubu t0,a0,a1 # t0 = a0-a1

都是实现a0减a1,结果存入t0操作。dsubu支持64位的减法,而且没有整数溢出异常。

  1.2 乘除运算

MIPS中乘法和除法指令如下表:

指令

格式

功能简述

MUL

MUL rd, rs, rt

乘法运算

MULT

MULT rs, rt

乘法运算,结果低32位存入LO,高32位存入HI

MULTU

MULTU rs, rt

无符号乘法运算,结果低32位存入LO,高32位存入HI

DMULT

DMULT rs, rt

64位乘法运算,结果低64位存入LO,高64位存入HI

DMULTU

DMULTU rs, rt

64位无符号乘法运算,结果低64位存入LO,高64位存入HI

MADD

MADD rs, rt

乘加运算,(HI,LO) ← (HI,LO) + (GPR[rs] × GPR[rt])

MADDU

MADDU rs, rt

无符号的乘加运算

MSUB

MSUB rs, rt

乘减运算,(HI,LO) ← (HI,LO) - (GPR[rs] × GPR[rt])

MSUBU

MSUBU rs, rt

无符号乘减运算

DIV

DIV rs, rt

除法运算,商存入LO,余数存入HI

DDIV

DDIV rs, rt

64位除法运算,商存入LO,余数存入HI

DIVU

DIVU rs, rt

无符号除法运算,商存入LO,余数存入HI

DDIVU

DDIVU rs, rt

64位无符号除法运算,商存入LO,余数存入HI

MFHI

MFHI rd

拷贝HI到rd

MTHI

MTHI rs

拷贝rs到HI

MFLO

MFLO rd

拷贝LO到rd

MTLO

MTLO rs

拷贝rs到LO

                                                                                       表4 乘法/除法指令

上表中完成了和乘法/除法相关的算术运算。运算过程中,操作数(rs,rt)默认按有符号计算,如需完成无符号数的乘法/除法操作,指令里面要带“U”,所以这张表里面的“U”意为”无符号”。”T”代表”结果临时存储“,也就是需要特殊寄存器HI/LO存储运算结果。下面举例说明:

               mul t0,a0,a1      #t0 = a0*a1

                mult a0,a1      # (HI,LO) ← (a0*a1)

               multu a0,a1      # (HI,LO) ← (a0*a1)   a0和a1均为无符号数

               dmult a0,a1       # (HI,LO) ← (a0*a1) 64位运算

mul 实现了2个32位有符号数乘法运算,得出可以是64位的结果并存入t0。

mult 也实现两个32位有符号数乘法运算,得出可以是64位的结果,但是结果的低32位有符号扩展到64位后存入寄存器LO,高32位有符号扩展到64位后存入寄存器HI。multu 同mult指令,区别是a0和a1按32位无符号数运算。

dmult 实现的是两个64位有符号数乘法运算,可以得出一个128位的结果。结果的低64位存入LO。高64位存入HI。

接下来在看另一组运算:

             madd a0,a1            #  (HI,LO) ← (HI,LO) + (a0*a1)

             maddu a0,a1         #  (HI,LO) ← (HI,LO) + (a0*a1)  a0和a1均为无符号数

             msub a0,a1            #  (HI,LO) ← (HI,LO) - (a0*a1)

             msubu a0,a1          #   (HI,LO) ← (HI,LO) - (a0*a1) a0和a1均为无符号数

madd实现了两个32位寄存器的有符号乘法运算后,结果的低32位累加到LO寄存器,高32位累加到HI寄存器。maddu功能同madd,区别是操作数a0和a1为无符号数。

msub实现了两个32位寄存器的有符号乘法运算后,结果的低32位累减到LO寄存器,高32位累减到HI寄存器。msubu功能同msub,区别是操作数a0和a1为无符号数。

下面在看除法运算:

              div a0,a1             # (HI, LO) ← a0 / a1

              divu a0,a1            # (HI, LO) ← a0 / a1 ,a0和a1均为无符号数

              ddiv  a0,a1          # (HI, LO) ← a0 / a1

              ddivu a0,a1         # (HI, LO) ← a0 / a1 ,a0和a1均为无符号数

div实现两个有符号32位寄存器的除法运算,商有符号扩展到64位存放在LO寄存器,余数有符号扩展到64位后存放在HI寄存器。divu功能同div,区别是操作数a0和a1为无符号数。

ddiv实现两个有符号64位寄存器的除法运算,商存放在LO寄存器,余数存放在HI寄存器。ddivu功能同ddiv,区别是操作数a0和a1为无符号数。

上面介绍的和乘法/除法相关的运算时涉及到两个寄存器HI、LO。这两个寄存器不是通用寄存器。所以需要把里面的结果复制到通用寄存器才可以使用。下面介绍和HI、LO寄存器相关的指令:

             mfhi t0        #t0 ← HI

             mflo t0          #t0 ← LO

              mthi t0        #HI ← t0

             mtlo t0          #LO ← t0

上面4条指令完成了HI、LO和通用寄存器的互拷贝操作。指令中“f”意为from,“t”意为to 。mfhi实现把HI寄存器值拷贝到t0;mflo 实现把LO寄存器值拷贝到t0。mthi实现把t0拷贝到HI寄存器,mtlo实现把t0拷贝到LO寄存器。

 

1.3 逻辑运算

MIPS中逻辑运算指令包括与、或、非、条件设置等,具体如下表所示:

指令

格式

功能简述

SLT

SLT rd, rs, rt

小于设置 if GPR[rs] < GPR[rt] then GPR[rd]=1 else GPR[rd]=0

SLTI

SLTI rt, rs, immediate

小于设置 if GPR[rs] < immed then GPR[rd]=1 else GPR[rd]=0

SLTU

SLTU rd, rs, rt

无符号小于设置

SLTIU

SLTIU rt, rs, immediate

无符号小于立即数设置

AND

AND rd, rs, rt

与运算  rd = rs and rt

ANDI

ANDI rt, rs, immediate

与立即数 rt = rs and immediate

OR

OR rd, rs, rt

或运算 rd = rs or rt

ORI

ORI rt, rs, immediate

或立即数 rt = rs or immediate

XOR

XOR rd, rs, rt

异或  rd = rs ^ rt

XORI

XORI rt, rs, immediate

异或立即数 rt = rs ^ immediate

NOR

NOR rd, rs, rt

或非 rd = rs nor rt

LI

LI rt, immediate

取立即数到寄存器 。

LUI

LUI rt, immediate

取立即数到高位GPR[rt] ← sign_extend(immediate || 0 16 )

CLO

CLO rd, rs

字前导1个数

DCLO

DCLO rd, rs

双字前导1个数

CLZ

CLZ rd, rs

字前导0个数

DCLZ

DCLZ rd, rs

双字前导0个数

WSBH

WSBH rd, rt

半字中字节交换

DSHD

DSHD rd, rt

字中半字交换

DSBH

DSBH rd, rt

双字中的半字中字节交换

SEB

SEB rd, rt

字节符号扩展

SEH

SEH rd, rt

半字符号扩展

INS

INS rt, rs, pos, size

位插入 ,

pos取值0-31 size取值1-32 。pos+size取值(1-32)

DINS

DINS rt, rs, pos, size

双字位插入

pos取值0-31 size取值1-32 pos+size取值(1-32)

DINSM

DINSM rt, rs, pos, size

双字位插入

pos取值0-31 size取值2-64,pos+size取值(33-64)

DINSU

DINSU rt, rs, pos, size

双字位插入

pos取值32-63, size取值1-32,pos+sizee取值(33-64)

EXT

EXT rt, rs, pos, size

位提取

pos取值0-31, size取值1-32,pos+size取值(1-32)

DEXT

DEXT rt, rs, pos, size

双字位提取

pos取值0-31, size取值1-32,pos+size取值(1-63)

DEXTM

DEXTM rt, rs, pos, size

双字位提取

pos取值0-31, size取值33-64,pos+size取值(33-64)

DEXTU

DEXTU rt, rs, pos, size

双字位提取

pos取值32-63, size取值1-32,pos+size取值(33-64)

                                                                          表4 逻辑运算

这张表中的U代表无符号数。具体举例如下:

             slt a3,t0,t1                  #if(t0



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3