Re: [理工] 计组 第一章

楼主: mistel (Mistel)   2019-07-15 09:58:50
※ 引述 《skyHuan (Huan)》 之铭言:
:  
: ※ 引述《AAQ8 ()》之铭言:
: : https://i.imgur.com/RJjsPLH.jpg
:  
:  
: 看懂这段程式前我们要先有两个概念
:  
: 1. 原函式(caller)与被呼叫函式(callee)的关系
: 呼叫函式前因为callee会用到暂存器
: 所以要先将暂存器的变量存到stack中
: 以免原来在暂存器中的值被盖掉
: 导致callee return之后caller无法继续执行
: 一般储存变量到stack的工作由caller跟callee分工
: caller负责存a开头跟t开头的暂存器
: 而ra跟s开头的暂存器交由callee负责存
: 原因是如果callee没有用到这些暂存器就可以不用花时间去存
:  
: 2. 这个程式可以想成是这样运作的:
:

: 所以是main呼叫f (此时main是caller、f是callee)
: 然后f呼叫func (此时f是caller、func是callee)
:  
:  
: 有了这两个概念后我们就来看这段程式
:

: 因为f是main的callee又要当caller呼叫func
: 所以要store ra跟s开头的暂存器到stack中
: 以免等等被func改一改f回不去main
: 等callee return之后再load回来
: 这就是L1~L3跟L9~L11做的事情
: 而这边为什么要存s0我们等等再讨论
:  
: 存完stack之后就可以呼叫func了
: 注意此时f是caller、func是callee
: 呼叫前应该要设定引数a0=a, a1=b
: 但原本的a0, a1里面就已经分别是a, b了
: 所以这里就不再多设定一次
: 而L4那行move s0 a2是在做什么的呢?
: 呼叫callee前caller应该要把等等callee return后
: 还要用的a开头暂存器存起来(就是a2=c这个值)
: 因为我们不知道func的运作
: (func可能还要再call其他函式会用到很多引数)
: 照理来说存到stack是最简单的做法
: (sp-4之后store到stack中等return后再load回来)
: 但这里用了另一个做法就是把a2暂存到s0之中
: 所以等callee return之后要用a2就直接去s0找即可
: 所以L4就是在把a2存到s0中
:  
: 这就是为什么刚刚L1~L3在存stack的时候L3要多存一个s0
: 因为main跟f之间是caller跟callee的关系
: 而f (callee)这个函式要用到s0这个暂存器
: 所以在开始前要负责把main (caller)的s0内容先存起来
: 同理,当L5呼叫func函式之后
: 如果func中有要用到s0这个暂存器
: 也要在func开始前把s0存到stack中
: (不过这就是func的事了跟我们现在在写f无关)
:  
: 了解L4之后应该就海阔天空了
: L5跳到func去执行函式return之后
: 回传值又要当作引数再呼叫一次func
: L6, L7就是在做呼叫前的引数设定
: L7这里就用到刚刚被我们存到s0的a2=c
: L8这里一样引数设定完跳到func去执行函式
不好意思挖一下sky大大曾经回答过的古文来再问一下
move $s0, $a2
作者: skyHuan (Huan)   2019-07-15 14:23:00
ax是用来存引数给呼叫的函式用的,通常一进到函式就会被使用。而tx是用来存运算过程中暂时的结果,通常没有保留的必要,所以呼叫callee的时候不会特别让callee去存他,如果caller本身在return之后有使用需求,就要在呼叫函式前自己先存好,return回来之后才有办法使用。这个例子a0,a1已经使用完不会再用了但a2还没,所以才先存起来return后才有办法使用他
楼主: mistel (Mistel)   2019-07-15 14:58:00
所以你的意思是,从这题来看因为a0,a1的引数在呼叫funct时就已经用掉且之后不会再用了,所以不用存起来看,但a2在return后因为我之后还要用且不知道funct的功能是什么所以我要把他存起来,这样子对吗?
作者: jls16457 (只是路过)   2019-07-15 21:37:00
我觉得不是这个意思欸,应该是说a,b还要继续作为arguments被使用,所以不用存到saved去,但是c因为不会用到,而且不确定a3会不会被funct用掉,所以才把a3的内容存到s0让funct把他存到stack里
楼主: mistel (Mistel)   2019-07-16 00:46:00
我觉得我应该是对的耶,因为caller确定c之后会被使用到,但是a,b丢给funct后就已经不会用到了,所以caller就不再特地存下a,b我的意思是caller在第一轮呼叫funct的时候确定不会用到c但之后会用到,又不确定funct功能,所以存下来,但a,b再第一次呼叫后就不会用到了,所以不存“如果caller在return之后还会用$ax的值,那caller就要自己存下来” 这句话是关键
作者: skyHuan (Huan)   2019-07-16 02:10:00
对喔m大说的是对的~
楼主: mistel (Mistel)   2019-07-16 13:47:00
感谢sky大!

Links booklink

Contact Us: admin [ a t ] ucptt.com