# P2 课下学习
UPD:2021/11/1、
几天之前就已经把 P2 课下给做完了,但是鸽了好长时间才写的总结,答辩加作业太忙了...
# Mars 的使用技巧
上来记得调字体,调成 Console 或者 Couriers New 才好看
记得改一下 Tab 的格数,调成 4 个空格合适
Mars 运行的时候貌似不能复制粘贴,可以采用
cmd
+ 输入重定向的方式来做java -jar mars.jar mc CompactDataAtZero nc <文件名>.asm < in.txt
就把
in.txt
中的文件重定向到了输入里面如果限制执行步数不超过 200000 的话,可以用
java -jar mars.jar mc CompactDataAtZero nc 200000 <文件名>.asm < in.txt
记不住的命令,特别是
syscall
,记得去看 help 里面的文档,syscall
赋值是给$v0
不是$a0
# MIPS 汇编常用模板
上机考试开考之前可以直接敲上去
# 计算数组地址
(TA 给的,可以自定义数组大小,放在 %rank
里面)
.macro calc_addr(%dst, %row, %column, %rank)
multu %row, %rank
mflo %dst
addu %dst, %dst, %column
sll %dst, %dst, 2
.end_macro
(我自己写的,数组的列数必须是 2 的整数次幂,但是用到了临时寄存器 $t9
,用之前要考虑保护,直接读和修改数组的值)
.macro get(%addr, %i, %j, %target)
sll $t9, %i, 4
add $t9, $t9, %j
sll $t9, $t9, 2
lw %target, %addr($t9)
.end_macro
.macro set(%addr, %i, %j, %source)
sll $t9, %i, 4
add $t9, $t9, %j
sll $t9, $t9, 2
sw %source, %addr($t9)
.end_macro
# 输入输出
用到了 $a0
和 $v0
,用之前记得保护,或者也可以在宏里面自行压栈弹栈
.macro input(%in)
li $v0, 5
syscall
move %in, $v0
.end_macro
.macro print(%out)
li $v0, 1
move $a0, %out
syscall
.end_macro
.macro println()
li $v0, 11
li $a0, '\n'
syscall
.end_macro
.macro printspace()
li $v0, 11
li $a0, ' '
syscall
.end_macro
.macro printwords(%addr)
li $v0, 4
la $a0, %addr
syscall
.end_macro
# 保护和读取寄存器
搬运,没用过,这个要用必须让储存和恢复顺序相反
.macro LOAD_LOCAL(%var)
addi $sp, $sp, 4
lw %var 0($sp)
.end_macro
.macro SAVE_LOCAL(%var)
sw %var 0($sp)
subi $sp, $sp, 4
.end_macro
# 常见问题
- 数据类型的大小:
int: 1word, 4byte
, 用lw/sw
, 记得sll $t0, $t0, 2
;char: 1byte
, 用lb/sb
- 使用宏也要保护必要的寄存器
- 把
.data
段定义的地址赋给寄存器要用la