作者KWire (Zbra)
看板Grad-ProbAsk
标题Re: [理工] 计组MIPS assembly code
时间Wed Sep 26 15:16:32 2018
※ 引述《LinoYo (Lino)》之铭言:
: 不好意思,请教一下大家有关於下面这张图片
: https://imgur.com/a/ufbOMwC
: 第一个问题是在问说错的地方在哪里,以及如何修正
: 请问一下须修正的地方是哪里?
: 是否为第6、7行的$v0、$v1来存,为了给call funtion f的caller用吗
: 还有第2行及第9行的lw、sw似乎可以不必要?
: 第二个问题问说此assembly code转成C code写出来且funtion f是什麽意思
: 有看没有懂。
: 麻烦各位指点指点,谢谢!
手机排版请见谅。有点久没念计算机组织,有错的话还请鞭小力一点
MIPS 不同字母开头的暂存器有不同使用惯例,比如有一些暂存器的数值要 caller 自己保管,不然 callee 可能会把它用掉。有些则是 callee 有责任要维护好。我目前发现的问题有:
1. sp 不应该存在 ra:因为使用 jal 指令呼叫 f 时,会自动把呼叫完 f 之後的下个指令存在 ra ,你把它用 sp 盖掉, jr ra 後就会把废弃的 stack 里面的东西当指令用(但那里面存的是垃圾)。
2. 但 sp 也是 callee 要维护的暂存器。所以应该要把 sp 在记忆体里,而不是 ra 中。在 epilogue 的时候从记忆体里面回复到 sp。
2. 但 sp 也是 callee 要维护的暂存器。所以应该要把 sp 在记忆体里,而不是 ra 中。在 epilogue 的时候从记忆体里面回复到 sp。
3. callee 有责任维护 $s0 ~ $s7 暂存器,使 caller 看到的 $s 暂存器们的内容呼叫前後是一样的,但 f 并没有做到这件事(他直接去改 $s0 跟 $s1)所以还少了「 prologue 时把 $s 们的内容塞进记忆体, epilogue 时
第二个问题问「什麽样的 C 程式会被组译成上面那段组合语言」。但这个问题变数有点多,因为不太能斩钉截铁地说编译器一定会编出什麽东西来。但我会猜 function body 是这样:
f(...){return foo(foo(a,b), c+d);}
其中一个想法是里面并没有区域变数,如果随便宣告一个整数暂存 c + d 的话,可能就会需要对 stack 做一些事。但显然组译结果里面没有任何对 stack 的动作。
但这还是有一个问题,C99 规格书中并没有指定 function parameter 的计算顺序,所以编译出来的结果也可能会是先算 foo(a,b), 再算 c + d。所以也许有比这个更好的作法啦。
--
※ 发信站: 批踢踢实业坊(ptt.cc), 来自: 140.112.252.222
※ 文章网址: https://webptt.com/cn.aspx?n=bbs/Grad-ProbAsk/M.1537946195.A.757.html
※ 编辑: KWire (140.112.252.222), 09/26/2018 15:19:04
1F:推 LinoYo: 谢谢帮忙,先把$ra $s存放到记忆体在做callee的执行工作 09/26 18:46