下一节:https://lixu.cc/major/mips-pre-2.html
基本操作
赋值
ori指令:将t2寄存器的值赋值为100,其实际含义是给$t2赋值为100或上0后的结果。
ori $t2,100li伪指令:伪指令的意思是不是原生MIPS硬件指令,汇编器会把它翻译成一条或多条真正的指令,其实际含义是将$t1寄存器赋值为100。
li $t1,100传值
move指令:这条指令的意思,就是将t2寄存器的值传给t1寄存器,同时t2寄存器中的值不变,与C语言中b=a的含义基本一致。
move $t1,$t2运算
加法:
add $d, $s, $t:将寄存器$s和$t的值相加,结果存到$daddi $d, $s, imm:将寄存器$s的值和立即数imm相加,结果存到$d
举例:
t1寄存器的值为t2寄存器的值加上t3寄存器的值:
add $t1,$t2,$t3如果加法的公式中存在数字,即不全是变量,使用下面的公式,含义为t1寄存器的值为t2寄存器的值加上100,这里100的值可以为负数:
addi $t1,$t2,100减法:
sub $d, $s, $t:将寄存器$s的值减去$t的值,结果存到$d
举例:
sub $t0, $t1, $t2 # $t0 = $t1 - $t2乘法:
mul $d, $s, $t(MIPS32标准,有些MIPS汇编器支持)mult $s, $t和mflo $d(纯MIPS指令集):mult将$s和$t相乘,结果存到特殊寄存器HI(高位)和LO(低位),32位整数一般用mflo提取低32位。
mul $t0, $t1, $t2 # $t0 = $t1 * $t2 (较新指令,推荐用法)
# 兼容性强的传统做法
mult $t1, $t2 # $t1 * $t2 -> HI/LO
mflo $t0 # $t0 = 结果的低32位除法:
div $d, $s, $t,直接就可以使用div $s, $t和mflo $d/mfhi $d:div将$s除以$t,商存入LO,余数存入HI。

举例:
li $t1,5 #被除数为5
li $t2,2 #除数为2
div $t1,$t2 #计算5/2,其中商存放在LO寄存器,而余数存放在HI寄存器
mfhi $t3 #将hi寄存器中的值取出放到t3寄存器(值为1)
mflo $t4 #将lo寄存器中的值取出放到t4寄存器(值为2)输入输出
v0寄存器的值与syscall(系统调用)是紧密联系在一起的,如果用非常非常非常大白话的方式来讲,就是v0的值决定了syscall是输入还是输出,输入(输出)字符串还是数字,如下代码:
li $v0,5
syscallv0寄存器为5决定了syscall为读入一个整数,并将读入的值存储在V0寄存器中。

判断
ble指令:其含义是若t1寄存器的值小于等于6,则跳转到lable1处,否则,执行ble下一条指令:
ble $t1,6,lable1举例:
li $t1,5
li $v0,1 #确立syscall为输出a0的值
ble $t1,5,lable1
li $a0,5 #若t1不是小于等于5,继续执行该语句
syscall #输出5
lable1: #若t1小于等于5,跳转至此处
li $a0,6
syscall #输出6循环
没有单独是指令,使用上面的ble判断指令完成,设置一个loop的lable,在循环体最底下写一个判断条件,判断是否满足条件而返回loop处。
举例:
li $t1,0
li $a0,0
loop:
addi $a0,$a0,1
addi $t1,$t1,1
ble $t1,3,loop
li $v0,1
syscall终止程序
li $v0,10
syscall寄存器
| 名称 | 编号 | 用途 | 常见说明 |
|---|---|---|---|
| $zero | $0 | 常数零 | 总是0,不能修改 |
| $at | $1 | - | 汇编器临时用 |
| $v0 | $2 | syscall号/返回值1 | 系统调用及函数返回结果 |
| $v1 | $3 | 返回值2 | 第二返回值(很少用) |
| $a0~\$a3 | $4~\$7 | 函数/系统调用参数 | 传递前四个参数 |
| $t0~\$t9 | $8~$15, $24~$25 | 临时变量 | 用来存放临时值,自己保管好 |
| $s0~\$s7 | $16~\$23 | 需要保存的变量 | 调用时要保证内容不变 |
| $k0~\$k1 | $26~\$27 | - | 内核保留 |
| $gp | $28 | - | 全局指针 |
| $sp | $29 | 栈顶指针 | 管理栈空间用 |
| $fp | $30 | 当前帧指针 | 复杂数据和函数帧 |
| $ra | $31 | 函数返回地址 | 子程序返回必用 |
预习题
T1
li $v0,5
syscall
move $a0,$v0
li $v0,5
syscall
move $t1,$v0
li $v0,5
syscall
move $t2,$v0
ble $t2,0,jia
ble $t2,1,jian
ble $t2,2,cheng
ble $t2,3,chu
jia:
add $a0,$a0,$t1
li $v0,1
syscall
li $v0,10
syscall
jian:
sub $a0,$a0,$t1
li $v0,1
syscall
li $v0,10
syscall
cheng:
mul $a0,$a0,$t1
li $v0,1
syscall
li $v0,10
syscall
chu:
div $a0,$a0,$t1
li $v0,1
syscall
li $v0,10
syscallT2
li $v0, 5
syscall
move $t0, $v0
li $t1, 2
li $a0, 0
ble $t0, 1, answer1
ble $t0, 2, answer2
loop:
div $t0, $t1
mfhi $t2
ble $t2, 0, answer1
addi $t1, $t1, 1
mul $t3, $t1, $t1
ble $t3, $t0, loop
answer2:
li $a0, 1
li $v0, 1
syscall
li $v0, 10
syscall
answer1:
li $v0, 1
syscall
li $v0, 10
syscallT3
li $v0, 5
syscall
move $t0, $v0
li $a0, 0
li $t5, 4
div $t0, $t5
mfhi $t1
li $t5, 100
div $t0, $t5
mfhi $t2
li $t5, 400
div $t0, $t5
mfhi $t3
ble $t1, 0, w1
w2:
li $v0, 1
syscall
li $v0, 10
syscall
w1:
ble $t2, 0, w3
li $a0, 1
li $v0, 1
syscall
li $v0, 10
syscall
w3:
ble $t3, 0, w4
li $v0 1
syscall
li $v0, 10
syscall
w4:
li $a0, 1
li $v0, 1
syscall
li $v0, 10
syscallT4
li $v0, 5
syscall
move $t0, $v0
li $v0, 5
syscall
move $t1, $v0
li $t6 101
li $t4 1
li $t5 0
li $a0 0
loop:
li $v0, 5
syscall
move $t2, $v0
mul $t3, $t4, $t2
div $t3, $t6
mfhi $t3
add $a0, $a0, $t3
mul $t4, $t1, $t4
div $t4, $t6
mfhi $t4
addi $t5, $t5, 1
div $a0, $t6
mfhi $a0
ble $t5, $t0, loop
li $v0, 1
syscall
li $v0, 10
syscall
1 条评论