路由器中经常使用的一种MIPS架构是MIPS32,该部分主要介绍MIPS32
MIPS32是一种基于固定长度的定期编码指令集,并且采用导入/存储(load/store)数据模型。
函数
MIPS架构中函数被分为叶子函数和非叶子函数,顾名思义,叶子函数就是在在该函数中不再调用其他函数
例:
void A()
{
int a = 0;
}
void B()
{
int b = 0;
A();
}
其中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保存乘法运算结果
字节序
MIPS寻址方式
有寄存器寻址、立即数寻址、寄存器相对寻址和PC相对寻址4种
- 寄存器相对寻址:主要被加载/存储指令使用,对一个16位的立即数进行符号扩展,然后与指定通用寄存器的值相加,从而得到有效地址
- PC相对寻址:主要被转移指令使用,在转移指令中有一个16位的立即数,将其左移2位进行符号扩展,然后与程序计数寄存器PC相加,从而得到有效地址
MIPS指令集
- 特点:
- MIPS固定4字节的指令长度
- 内存中的数据访问(load/store)必须严格对齐
- 跳转指令只有26位目标地址,加上2位对齐位,可寻址28位的空间,即256mb
- 条件分支指令只有18位寻址空间,即256kb
- 流水线效应(最重要的是分支延迟效应),即在程序执行到分支语句时,刚要把跳转的地址填充到代码计数器里,还没有完成本条指令时,分支语句后面的那个指令就已经执行了——原因是几条指令同时执行,只是处于不同阶段
例:
mov $a0,$s2
jalr strchr
move $a0,$s0
在执行第二行时,第三行的move已经执行完了,因此,strchr函数的参数来自第三行的$s0
- 指令格式
在MIPS架构中,指令的最高6位均为Opcode码,剩下的24位可以将指令分为R、I、J三种类型
- 汇编常用指令
($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字节
- 类比较指令
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中返回一个错误号
- 分支跳转指令
- 跳转指令
j target跳转到target处
jal target跳转到target处,并保存返回地址到$ra中
jr $R跳转到$R寄存器中的地址
ctf-wiki上在mips程序函数调用时的栈结构