MIPS指令集:运算指令、访存指令、分支和跳转、协处理器0指令 |
您所在的位置:网站首页 › 调用和返回指令属于转移指令 › MIPS指令集:运算指令、访存指令、分支和跳转、协处理器0指令 |
计算机指令就是指挥机器工作的指示和命令,程序就是一系列按一定顺序排列的指令,执行程序的过程就是计算机的工作过程。通常一条指令包括两方面的内容: 操作码和操作数,操作码决定要完成的操作,操作数指参加运算的数据及其所在的单元地址。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指令的具体格式:
从上图可以看出,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 |