【P2】MARS使用/MIPS汇编

课上

T1 在n位数中删除N个数使剩下的(n-N)位数最大

写得似乎过于谨慎而慢了,没出现寄存器打错的问题,一遍过了

T2 拆分数字

将输入整数N拆分为几个数相加的形式,按拆分项数降序排列,每项按数字大小升序排列(giao记不清了)

输入

5

输出

1+1+1+1+1
1+1+1+2
1+1+3
1+2+2
1+4

 

递归js+函数调用print。总体写得顺畅,质量也不错。然而一个致命小bug玩崩了心态
讲真算法没看懂,就硬敲

bug1

print:执行完后忘记jal $ra返回

  • 运行一下就能看出

bug2

自认为jal print调用规避了已用寄存器而没进行变量维护 -> $ra被覆盖 -> 返回地址错误,js反复退出回收栈,却不分配栈 -> $sp不断增大,最终指向.text段导致错误跳出

  • 从报错信息和$sp异常容易看出

bug3

自认为给print传参时将t-1值存入了$a0,且之后从if块跳出后进入for块内并没有更改$a0,因而为了省指令数在产生a[t-1]地址时直接用了sll $t1, $a0, 2,殊不知if块未必每次都能进入!加上存在多次递归传参后$a0未必是t-1 -> 样例的输出变成

1+1+1+1+1
1+1+1+2
1+1+2+1
1+1+3 //这里开始记不清了
1+3+1
1+2+2
1+4

在不理解算法的情况下,遇到这个输出属实是丈二和尚摸不着脑袋。

  • 单步调试点下来,定位到了输出1+1+2+1时a数组地址内容就是1 1 2 1 1
  • 回退确定该步具体运行位置,确认问题出在for循环中;
  • 然后发现a[3]被从1改为2(本该改为3);
  • 查看循环变量i(存在$t0)的值,确实有过3出现,又因为i>=t(t为2,存在$s2)而跳出循环;
  • 想不通,有点怀疑代码本身问题,心例纠结是去尝试看懂算法从还是直接检查翻译;
  • 心急火燎下这种递归C代码看不懂了。。转而检查翻译,压根没有翻译错误(自己写的那么谨慎,质量可高了xs);
  • 慌了手脚乱提交了这份问题代码,竟然还过了两个点,似乎说明问题不在主要逻辑上,可能出现在旁支寄存器覆盖上
  • 突然想道当时偷懒用了$a0似乎很可能出漏洞,和错误的相性很高。改后就对了

前后花了1h不到一点,人已经冒烟

即将21:00,急忙交卷;然而发现这次P2结束时间是21:30,人傻了

T3 双关键字排序

回头看了眼题目,虽然C代码要自己写,但就常用排序多加个判断条件罢了。没有递归,完全可以不用栈维护。30min大概率足够。

总之就是亏大了,信息接收要全面啊,长个记性吧

posted @ 2021-11-04 12:55  Xlucidator  阅读(319)  评论(0编辑  收藏  举报