October 21, 2025- 次阅读
CO_P2(MIPS)

课下
易错的内容:
数组的地址
注意数组中具体存储的变量的地址是索引的4倍,例如a[2]实际的地址是a[8],一个word占4个字节
判断回文串
正确:
li $t0, 0 #i=0
srl $s1, $s0, 1 #s1=n/2
loop1:
beq $t0, $s1, loop1_end
lb $t2, s($t0) #t2=s[i]
subi $t3, $s0, 1
sub $t3, $t3, $t0 #t3=n-i-1
lb $t4, s($t3) #t4=s[n-i-1]
bne $t2, $t4, invalid
addi $t0, $t0, 1
j loop1
loop1_end:
...
错误:
li $t0, 0 #i=0
srl $s1, $s0, 1# s1=n/2
loop1:
lb $t2, s($t0) #t2=s[i]
subi $t3, $s0, 1
sub $t3, $t3, $t0 #t3=n-i-1
lb $t4, s($t3) #t4=s[n-i-1]
bne $t2, $t4, invalid
addi $t0, $t0, 1
bne $t0, $s1, loop1
如果n=1,第二种在t0=1的时候仍然会执行访问(因为这里n/2会等于0,当i=1之后仍然满足bne,就会被多错误执行),会尝试访问s[1-1-1]即s[-1]会有问题。
递归调用栈
调用函数的时候传递的参数要么修改之后进行传参然后返回之后进行复原,要么先传参然后在递归的内部进行修改参数
addi $a0, $a0, 1
jal FullArray#FullArray(index+1)
subi $a0, $a0, 1
这里执行函数f(x+1),如果是先对x进行加1操作,返回时需要复原不然会影响
更好的做法是在FullArray内部先让原本的a0入栈然后对a0进行加1操作然后一系列操作之后再让a0出栈
课上准备
上机前准备点宏,别把宏写错了
打印字符串
.macro print_string(%string)
li $v0, 4
la $a0, %string
syscall
.end_macro
打印int
.macro print_int(%des)
li $v0, 1
move $a0, %des
syscall
.end_macro
读int
.macro read_int(%des)
li $v0, 5
syscall
move %des, $v0
.end_macro
结束程序
.macro end
li $v0, 10
syscall
.end_macro
二维数组计算索引
.macro cal_addr(%des,%row,%col,%n) #计算a[i][j]的偏移地址,后面就可以用a(%des)了
mult %row, %n #n*i
mflo %des
add %des, %des, %col
sll %des, %des, 2 #don't forget to mult by 4
.end_macro
入栈
.macro push(%src)
addi $sp, $sp, -4
sw %src, 0($sp)
.end_macro
出栈
.macro pop(%des)
lw %des, 0($sp)
addi $sp, $sp, 4
.end_macro
for循环模板:
li $t0, 0 #i
li $t1, 0 #j
fori:
beq $t0, $s0, fori_end #s0: row
...
li $t1, 0 #注意要先初始化为0
forj:
beq $t1, $s1, forj_end #s1:col
...
addi $t1, $t1, 1
j forj
forj_end:
addi $t0, $t0, 1
j fori
fori_end: