MIPS

二、MIPS操作数之32个寄存器

寄存器名字 寄存器编号 寄存器功能
$zero $0 恒等于零
$at $1 被汇编器保留,用于处理大的常数
$v0 – $v1 $2-$3 存放函数返回值
$a0 – $a3 $4-$7 传递函数参数
$t0 – $t7 $8-$15 存放临时变量
$s0 – $s7 $16-$23 存放需要保存的临时值
$t8 – $t9 $24-$25 额外的存放临时变量
$k0 – $k1 $26-$27 用于操作系统内核
$gp $28 指向全局变量的指针
$sp $29 指向栈顶的指针
$fp $30 指向栈帧[^footnote2]的指针
$ra $31 返回地址,用于函数调用

三、MIPS汇编语言指令类型及寻址方式

image-20201016100110436
image-20201016100254039

不调用其他过程的过程称为叶过程(leaf procedure)

编译一个不调用其他过程的C过程

思考步骤:

  1. 保存调用过程之后,还需要使用的寄存器$t0~$t7$a0~$a1$v0~$v1
  2. 保存用到的参数($a0~$a1
  3. 保存返回地址$ra
1
2
3
4
5
int leaf_example(int g, int h, int i, int j){
int f;
f = (g+h)-(i+j);
return f
}

MIPS:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
leaf_example:
addi $sp, $sp, -12 #在栈中分配3个空间
sw $t1, 8($sp) #push $t1
sw $t0, 4($sp) #push $t0
sw $s0, 0($sp) #push $s0

add $t0, $a0, $a1 #t0 = g + h
add $t1, $a2, $a3 #t1 = i + j
sub $s0, $t0, $t1 #f = g + h - (i + j)
add $v0, $s0, $zero #将f放入一个返回值寄存器v0中

lw $s0, 0($sp) #弹出s0
lw $t0, 4($sp) #弹出t0
lw $t1, 8($sp) #弹出t1
addi $sp, $sp, 12 #恢复

jr $ra #根据返回地址跳转
编译一个递归C过程
1
2
3
4
5
6
int fact(int n){
if(n<1)
return 1;
else
return (n*fact(n-1));
}

MIPS:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
fact:
addi $sp, $sp, -8 #在栈中分配两个空间
sw $ra, 4($sp) #push ra, 如果没有这一步就回不来了
sw $a0, 0($sp) #push n

slti $t0, $a0, 1
beq $t0, $zero, L1 #if(n>=1),goto L1

addi $v0, $zero, 1 #return 1
addi $sp, $sp, 8 #弹出
jr $ra

L1:
addi $a0, $a0, -1 # n = n - 1
jal fact # 递归调用fact,此时v0= fact(n-1)

lw $a0, 0($sp) #取出a0
lw $ra, 4($sp) #取出ra
addi $sp, $sp, 8 #栈弹出两个空间

mul $v0, $a0, $v0 #return n*fact(n-1)

jr $ra

未完待续……

参考资料

[1]https://blog.csdn.net/qq_32146369/article/details/79006728


MIPS
https://wuhlan3.github.io/2020/10/16/MIPS/
Author
Wuhlan3
Posted on
October 16, 2020
Licensed under