路由器中经常使用的一种MIPS架构是MIPS32,该部分主要介绍MIPS32

MIPS32是一种基于固定长度的定期编码指令集,并且采用导入/存储(load/store)数据模型。

函数

MIPS架构中函数被分为叶子函数和非叶子函数,顾名思义,叶子函数就是在在该函数中不再调用其他函数
例:

  1. void A()
  2. {
  3. int a = 0;
  4. }
  5. void B()
  6. {
  7. int b = 0;
  8. A();
  9. }

其中A是叶子函数,B是非叶子函数

A函数返回时,因为是叶子函数,所以直接调用jr $ra返回

B函数返回时,因为是非叶子函数,所以先从堆栈中取出返回值,存到$ra中,再返回(非叶子函数的返回地址存放在栈上 ,在函数开头有如下操作: sw $ra,xxx)

寄存器

MIPS32中除了加载/存储指令以外,都是用寄存器或者立即数为操作数

普通寄存器

编号 寄存器名称 寄存器描述
0 zero 其值始终为0
1 $at 保留寄存器
2~3 $v0~$v1 保存表达式或函数返回结果
4~7 $a0~$a3 函数的前4个参数,其他保存在栈中
8~15 $t0~$t7 供汇编程序使用的临时寄存器
16~23 $s0~$s7 子函数使用时需要先保存原寄存器的值
24~25 $t8~$t9 供汇编程序使用的临时寄存器
26~27 $k0~$k1 保留,中断处理函数使用
28 $gp global pointer,全局指针;全局变量数据在gp为基地址的64kb范围内
29 $sp 堆栈指针,指向栈顶
30 $fp 保存栈指针
31 $ra 返回地址;jal X跳转到X,执行完毕后jr $ra返回

特殊寄存器

PC(程序计数器)、HI(乘除结果高位寄存器)、LO(乘除结果低位寄存器)

乘法运算:HI和LO保存乘法运算结果

除法运算:HI保存余数,LO保存商

字节序

大端模式(MSB)以及小端模式(LSB)均有

MIPS寻址方式

有寄存器寻址、立即数寻址、寄存器相对寻址和PC相对寻址4种

  • 寄存器相对寻址:主要被加载/存储指令使用,对一个16位的立即数进行符号扩展,然后与指定通用寄存器的值相加,从而得到有效地址
  • PC相对寻址:主要被转移指令使用,在转移指令中有一个16位的立即数,将其左移2位进行符号扩展,然后与程序计数寄存器PC相加,从而得到有效地址

    MIPS指令集

  1. 特点:
    • MIPS固定4字节的指令长度
    • 内存中的数据访问(load/store)必须严格对齐
    • 跳转指令只有26位目标地址,加上2位对齐位,可寻址28位的空间,即256mb
    • 条件分支指令只有18位寻址空间,即256kb
    • 流水线效应(最重要的是分支延迟效应),即在程序执行到分支语句时,刚要把跳转的地址填充到代码计数器里,还没有完成本条指令时,分支语句后面的那个指令就已经执行了——原因是几条指令同时执行,只是处于不同阶段

例:

  1. mov $a0,$s2
  2. jalr strchr
  3. move $a0,$s0

在执行第二行时,第三行的move已经执行完了,因此,strchr函数的参数来自第三行的$s0

  1. 指令格式

在MIPS架构中,指令的最高6位均为Opcode码,剩下的24位可以将指令分为R、I、J三种类型

  1. 汇编常用指令

($Rd表示目标寄存器,$Rs表示源寄存器,$Rt表示作中间缓存的寄存器,imm表示立即数,offset表示偏移量)

  • Load/store指令

a $Rd,Label将一个地址或标签存入一个寄存器
li $Rd,imm指令将一个立即数存入一个通用寄存器
lw $Rt,offset($Rs)指令取$Rs寄存器中地址在offset偏移处word长度的值到$Rt中
sw $Rt,offset($Rs)指令将$Rt寄存器中的值存入$Rs寄存器中地址在offset偏移处($sp为源寄存器时自动抬栈)
move $Rt,$Rs寄存器间值的传递

  • 算数运算指令

算数运算指令所有操作数都是寄存器,操作数大小都为4字节image.png

  • 类比较指令

MIPS寄存器中没有标志寄存器,用SLT系列指令与分支跳转指令联合使用
slt $Rd,$Rs,$Rt 如果$Rs小于(有符号比较)$Rt,设置$Rd为1,否则为0
slti $Rt,$Rs,imm 如果$Rs小于(有符号比较)立即数imm,设置$Rt为1,否则为0
sltu $Rd,$Rs,$Rt 如果$Rs小于(无符号比较)$Rt,设置$Rd为1,否则为0
sltiu $Rt,$Rs,imm 如果$Rt小于(无符号比较)立即数imm,设置$Rt为1,否则为0

  • SYSCALL

产生软中断,系统调用号存放在$v0中,如果系统调用出错,则会在$a3中返回一个错误号

  • 分支跳转指令image.png
  • 跳转指令

j target跳转到target处
jal target跳转到target处,并保存返回地址到$ra中
jr $R跳转到$R寄存器中的地址

ctf-wiki上在mips程序函数调用时的栈结构
MIPS架构 - 图3