# 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