MIPS汇编基础
简介
MIPS是世界上很流行的一种RISC处理器。MIPS的意思是“无内部互锁流水级的微处理器”(Microprocessor without interlocked piped stages),其机制是尽量利用软件办法避免流水线中的数据相关问题。和英特尔采用的复杂指令系统计算结构(CISC)相比,RISC具有设计更简单、设计周期更短等优点,并可以应用更多先进的技术,开发更快的下一代处理器。
MIPS21架构是一种基于固定长度的定期编码指令集,并采用导入/存储数据模型。在路由器中经常使用的一种MIPS架构就是MIPS32。
寄存器
通用寄存器
在MIPS体系结构中有32个通用寄存器,在汇编程序中可以用编号$0-$31表示,也就可以用寄存器的名字表示。
特殊寄存器
PC(程序计数器)、HI(乘除结果高位寄存器)、LO(乘除结果低位寄存器)。在除法计算中HI保存余数,LO保存商。
字节序
有大端模式(MSB)和小端模式(LSB)
MIPS指令集
MIPS指令的特点
-
固定4字节指令长度。
-
内存中的数据访问(load/store)必须严格对齐(至少4字节对齐)。
-
跳转指令只有26位目标地址,加上2位对齐位,可寻址28位空间,即256MB。
-
MIPS默认不把子函数的返回地址存放到栈中,而是存放到$31($ra)寄存器中,如果遇到嵌套子函数,则把返回地址存放到栈中,$31用来存嵌套子函数的返回地址。
-
流水线效应:MIPS采用高度的流水线,其中一个最重要的效应就是分支延迟效应。在分支跳转语句后面的那条语句叫做分支盐池曹。实际上,在程序执行到分支语句时,当它刚把要跳转到的地址填充好(填充到代码计数器里),还没有完成本条指令时,分支语句后面的那个指令就已经执行了,其原因就是流水线效应——几条指令同时执行,只是处于不同的阶段。
如下面的代码:寄存器$a0存的是调用函数的参数,根据流水线效应,在执行第二句跳转分支时,第三行的move指令已经完成,也就是说实际传入strrchr函数的参数时$s0而不是$s2。
mov $a0,$s2
jalr strrchr
move $a0,$s0
指令格式
所有的MIPS指令的长度都为32位,设计者将所有指令定长,但不同的指令有不同的格式。在MIPS架构中指令最高6位均为6位的Opcode码,剩下的24位可以将指令分为3种类型,分别时R型、I型和J型。
-
R型指令连续3个5位二进制码表示3个寄存器的地址,然后用1个5位二进制码表示移位的位数(如果未使用移位操作则全为0),最后6位地Function码(它与Opcode码共同决定R型指令地具体操作方式)。
-
I型指令连续2个5位二进制码表示2个寄存器地地址,然后是由1个16位二进制码表示1个立即数二进制码。
-
J型指令用26位二进制码表示跳转目标地指令地址(实际地指令地址应为32位,其中最低2位为“00”,最高4为由PC当前地址决定)。
各字段含义:
-
Opcode:指令基本操作,操作码。
-
Rs:第一个源操作数寄存器。
-
Rt:第二个源操作数寄存器。
-
Shamt:位移量。
-
Funct:函数,这个字段选择Opcode操作地某个特定变体。
汇编常用命令
LOAD/STORE指令
LOAD/STORE指令一共有14条la、lb、lbu、lhu、li、lw、lwl、lwr、sb、sc、sh、sw、swl、swr。以“l”开头的是加载,以“s”开头的是存储。
例子:
算术运算指令
特点:
-
算术运算指令的所有操作码都是寄存器,不能直接使用RAM地址或间接寻址。
-
操作数的大小都为word(4Byte)
算术运算指令一共21条,实现了加、减、比较、乘、乘累加、除等运算。
例:
类比较指令
在MIPS寄存器种没有标志位寄存器,但有SLT系列指令,可以通过比较设置某个寄存器后与分支跳转指令联合使用。
例:
li $v1,1
beq $v0,$v1,loc_41A394
slti $v0,$s2,2
beq是分支跳转语句,所以需要注意流水线效应,上面的代码实现的功能相当于“if($s2<2)goto loc_41A394”。
SYSCALL(SYStem CALL)
SYSCALL可以产生一个软中断,从而实现系统调用。系统调用号存放在$v0中,参数存放在$a0-$a3中,系统返回值放在$v0中,如果系统出错,会在$a3中返回一个错误号。
分支跳转语句
跳转指令
参考链接
《揭秘家用路由器0day漏洞挖掘技术》
https://www.cnblogs.com/tkid/p/3873272.html
https://www.cnblogs.com/thoupin/p/4018455.html