VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > 编程开发 > 汇编语言 >
  • MIPS 汇编指令学习

  MIPS的系统结构及设计理念比较先进,其指令系统经过通用处理器指令体系MIPS I、MIPS II、MIPS III、MIPS IV、MIPS V,以及嵌入式指令体系MIPS16、MIPS32到MIPS64的发展。

  MIPS32的架构是一种基于固定长度的定期编码指令集,并采用导入/存储(load/store)数据模型。经改进,这种架构可支持高级语言的优化执行。在路由器中,经常使用的一种MIPS架构就是MIPS32。

 

MIPS寄存器

  RISC的一个显著特点就是大量使用寄存器。因为寄存器的存取可以在一个时钟周期内完成,同时简化了寻找方式,所以,MIPS32的指令中除了加载/存储指令以外,都使用寄存器或者立即数作为操作数,以便让编译器通过保持对寄存器内数据的频繁存取进一步优化代码的生成性能。

  MIPS32寄存器分为两类:通用寄存器(GPR)和特殊寄存器。

1、通用寄存器(GPR)

  在MIPS体系结构中有32个通用寄存器,在汇编程序中可以用编号$0~$31表示,也可以用寄存器的名字表示,如$sp、$t1、$ta等,如图,堆栈是从内存的高地址方向向低地址方向增长的。

编号 寄存器名称 寄存器描述
0  zero 第0号寄存器,其值始终为0
1 $at 保留寄存器
2~3 $v0~v1 values, 保存表达式或函数返回结果
4-7 $a0~a3 aruments, 作为函数的前4个参数
8~15 $t0~$t7 temporaries,供汇编程序使用的临时寄存器
16~23 $s0~$s7 saved values,子函数使用时需要先保存原寄存器的值
24~25 $t8~t9 temporaries, 供汇编程序的临时寄存器,补充$t0~t7
26~27 $k0~$k1 保留,中断处理函数使用
28 $gp global pointer,全局指针
29 $sp stack pointer, 堆栈指针,指向堆栈的栈顶
30 $fp frame pointer, 保存栈指针
31 $ra return address, 返回地址
  • $0:即$zero,该寄存器总是返回0,为0这个有用常数提供了一个简洁的编码形式。在MIPS处理器的通用寄存器中,没有任何帮助运算判断的标志寄存器,要实现相应的功能时,都是通过测试两个寄存器是否相等完成的。MIPS编译器常常会使用slt、beq、bne等指令和由寄存器$0获得0值产生比较所有的比较条件,如相等、不等、小于等于、大于、大于等于。还可以用add指令创建move伪指令,如"move $t0, $t1; $t0=$t1"实际为“add $t0,$0,$t1; $t0= $t1 + 0"。使用MIPS伪指令可以简化任务。
  • $1 ($at) : 该寄存器为汇编保留,用做汇编器的暂时变量。
  • $2~$3($v0~$v1): 用于存放子程序的返回值或非浮点结果。当这两个寄存器不够存放返回值时,编译器通过内存来完成。
  • $4~$7($a0~$a3):用于将前4个参数传递给子程序,不够的用堆栈处理。$a0~$a3、$v0~$v1和$ra 一起完成子程序函数调用过程,分别用以传递参数、返回结果和存放返回地址。当需要使用更多的寄存器时就需要堆栈了。MIPS编译器总是为参数在堆栈中留有空间,以防有参数需要存储。
  • $8~$15($t0~$t7): 一个子函数可以不用保存并随意使用这些寄存器。在进行表达式计算时,这些寄存器是非常好的临时变量。在使用时需要注意,当调用一个子函数时,这些寄存器的值有可能被子函数破坏。
  • $16~$23($s0~$s7): 子函数必须保证当函数返回时这些寄存器的内容将恢复到函数调用以前的值,或者子函数里不使用这些寄存器或把它们保存在堆栈上并保存在函数退出时恢复。这种约定使这些寄存器非常适合作为寄存器变量,或者用于存放一些函数调用期间必须保存的原值。
  • $24~$25($t8~$t9): 同$t0~$t7,作为$t0~$t7寄存器补充。
  • $26~$27($k0~$k1): 通常被中断或异常处理程序使用,以保存一些系统参数。
  • $28($gp): C语言中有两种存储类型,分别是自动型和静态型。自动变量是一个函数中的局部变量。静态变量在进入和退出一个函数时都是存在的。为了简化静态数据的访问,MIPS保留了一个寄存器作为全局指针gp在编译时,数据需要在以gp为基指针的64KB范围内。
  • $29($sp): MIPS硬件并不直接支持堆栈,X86有单独的PUSH和POP指令,而MIPS没有单独的栈操作指令,所有对栈的操作都是统一的内存访问方式,单这并非不影响MIPS使用堆栈。在发生函数调用时,调用者把函数调用之后要用的寄存器压入堆栈,被调用者把返回地址寄存器$ra(并非任何时候都保存$ra)和保留寄存器压入堆栈。同时,调整堆栈指针,并在返回时从堆栈中恢复寄存器。
  • $30($fp): 不同编译器可能对该寄存器使用方法不同。GNU MIPS C编译器使用了栈指针(Frame Pointer)。SGI的C编译器则没有使用栈指针,只是把这个寄存器当成保存寄存器使用($s8),这虽然节省了调用和返回开销,但增加了代码生成的复杂度性。
  • $31 ($ra): 存放返回地址。MIPS有一个jar(jump-and-link,跳转并链接)指令,在跳转到某个地址时可把下一条指令的地址放到$ra中,用于支持子程序。例如,调用程序把参数放到$a0~$a3中,“jar X"指令跳到X过程,被调用时需要保存的寄存器为$a0~$a3、$s0~$s7、$gp、$sp、$fp、$ra。

2、特殊寄存器

  MIPS32架构中定义了3个特殊寄存器。分别为PC(程序计数器)、HI(乘除结果高位寄存器)和LO(乘除结果低位寄存器)。在进行乘法运算时,HI和LO保存乘法的运算结果,其中HI存储高32位,LO存储低32位;而在进行除法运算时,HI保存余数,LO存储商。

MIPS 指令

 

MIPS 指令

 

指令

功能

应用实例

LB

从存储器中读取一个字节的数据到寄存器中

LB R1, 0(R2)

LH

从存储器中读取半个字的数据到寄存器中

LH R1, 0(R2)

LW

从存储器中读取一个字的数据到寄存器中

LW R1, 0(R2)

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

把一个字节的数据从寄存器存储到存储器中

SB R1, 0(R2)

SH

把半个字节的数据从寄存器存储到存储器中

SH R1,0(R2)

SW

把一个字的数据从寄存器存储到存储器中

SW R1, 0(R2)

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

BEQZ

条件转移指令,当寄存器中内容为0时转移发生

BEQZ R1,0

BENZ

条件转移指令,当寄存器中内容不为0时转移发生

BNEZ R1,0

BEQ

条件转移指令,当两个寄存器内容相等时转移发生

BEQ R1,R2

BNE

条件转移指令,当两个寄存器中内容不等时转移发生

BNE R1,R2

J

直接跳转指令,跳转的地址在指令中

J name

JR

使用寄存器的跳转指令,跳转地址在寄存器中

JR R1

JAL

直接跳转指令,并带有链接功能,指令的跳转地址在指令中,跳转发生时要把返回地址存放到R31这个寄存器中

JAL R1 name

JALR

使用寄存器的跳转指令,并且带有链接功能,指令的跳转地址在寄存器中,跳转发生时指令的放回地址放在R31这个寄存器中

JALR R1

MOV.S

把一个单精度浮点数从一个浮点寄存器复制到另一个浮点寄存器

MOV.S F0,F1

MOV.D

把一个双精度浮点数从一个浮点寄存器复制到另一个浮点寄存器

MOV.D F0,F1

MFC0

把一个数据从通用寄存器复制到特殊寄存器

MFC0 R1,R2

MTC0

把一个数据从特殊寄存器复制到通用寄存器

MTC0 R1,R2

MFC1

把一个数据从定点寄存器复制到浮点寄存器

MFC1 R1,F1

MTC1

把一个数据从浮点寄存器复制到定点寄存器

MTC1 R1,F1

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的值为0

SLT R1,R2,R3

SLTI

如果寄存器R2的值小于立即数,那么设置R1的值为1,否则设置寄存器R1的值为0

SLTI 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

两个单精度浮点数相乘加,结果为单精度

 
出  处:https://www.cnblogs.com/CoBrAMG/p/9237609.html


相关教程