FunctionCallingConventions2
CS64:ComputerOrganizationandDesignLogicLecture#10
ZiadMatni
Dept.ofComputerScience,UCSB
LectureOutline
• MoreonMIPSCallingConvention
– Functionscallingfunctions
– Recursivefunctions
5/8/18 Matni,CS64,Sp18 2
Administrative
• Mid-quarterevaluationsforT.AsandforProf.– LinksonthelastslideandwillputuponPiazzatoo– Optionaltodo,butveryappreciatedbyusall!
5/8/18 Matni,CS64,Sp18 4
Is-Not-A-Quiz-But-You-Should-Think-About-It
ConsiderthisC/C++code:voidthird(){}voidsecond(){third();}voidfirst(){second();}intmain(){first();}AndconsiderthissupposedlyequivalentMIPScodeèèèèa) Arethereanyerrorsinit?
(i.e.willitrun?)
b) DoesitfollowtheMIPSC.C.?EXPLAINYOURANSWER
5/8/18 Matni,CS64,Sp18 6
third:jr$ra
second:move$t0,$rajalthirdjr$t0
first:move$t1,$rajalsecondjr$t1
main:jalfirstli$v0,10syscall
LectureOutline
• RecappingMIPSCallingConvention
– Functioncallingfunctionexample
– Recursivefunctionexample
5/8/18 Matni,CS64,Sp18 7
TheMIPSConventionInItsEssence• Remember:PreservedvsUnpreservedRegs• Preserved: $s0-$s7,and$sp• Unpreserved: $t0-$t9,$a0-$a3,and$v0-$v1
• ValuesheldinPreservedRegsimmediatelybeforeafunctioncallMUSTbethesameimmediatelyafterthefunctionreturns.
• ValuesheldinUnpreservedRegsmustalwaysbeassumedtochangeafterafunctioncallisperformed.– $a0-$a3areforpassingargumentsintoafunction– $v0-$v1areforpassingvaluesfromafunction
5/8/18 Matni,CS64,Sp18 8
Matni,CS64,Sp18 9
intsubTwo(inta,intb){intsub=a-b;returnsub;}intdoSomething(intx,inty){inta=subTwo(x,y);intb=subTwo(y,x);returna+b;}
AnIllustrativeExamplesubTwodoesn’tcallanythingWhatshouldImapaandbto?
$a0and$a1CanImapsubto$t0?
Yes,b/cIdon’tcareabout$t*Eventually,Ihavetohavesubbe$v0
doSomethingDOEScallafunctionWhatshouldImapxandyto?
SincewewanttopreservethemacrossthecalltosubTwo,weshouldmapthemto$s0and$s1WhatshouldImapaandbto?
“a+b”hastoeventuallybe$v0.Ishouldmakeatleastabeapreservedreg($s2).SinceIgetbbackfromacallandthere’snoothercallafterit,Icanlikelygetawaywithnotusingapreservedregforb.
5/8/18
Matni,CS64,Sp18 105/8/18
subTwo:sub$t0,$a0,$a1move$v0,$t0jr$radoSomething:addiu$sp,$sp,-16sw$s0,0($sp)sw$s1,4($sp)sw$s2,8($sp)sw$ra,12($sp)move$s0,$a0move$s1,$a1jalsubTwo
move$s2,$v0move$a0,$s1move$a1,$s0jalsubTwoadd$v0,$v0,$s2lw$ra,12($sp)lw$s2,8($sp)lw$s1,4($sp)lw$s0,0($sp)addiu$sp,$sp,16jr$ra
intsubTwo(inta,intb){intsub=a-b;returnsub;}intdoSomething(intx,inty){inta=subTwo(x,y);intb=subTwo(y,x);returna+b;}
intsubTwo(inta,intb){intsub=a-b;returnsub;}intdoSomething(intx,inty){inta=subTwo(x,y);intb=subTwo(y,x);…returna+b;}
subTwo:sub$t0,$a0,$a1move$v0,$t0jr$radoSomething:addiu$sp,$sp,-16sw$s0,0($sp)sw$s1,4($sp)sw$s2,8($sp)sw$ra,12($sp)move$s0,$a0move$s1,$a1jalsubTwo
move$s2,$v0move$a0,$s1move$a1,$s0jalsubTwoadd$v0,$v0,$s2lw$ra,12($sp)lw$s2,8($sp)lw$s1,4($sp)lw$s0,0($sp)addiu$sp,$sp,16jr$ra
a-b
inta intb
inta intb
$t0
$a0 $a1
$s0 $s1
Orig.$ra
Orig.$s2
Orig.$s1
stackOrig.$s0
Arguments
Preserved
Unpreserved
a–b$v0
ResultValue
$ra a–b$s2
subTwo:sub$t0,$a0,$a1move$v0,$t0jr$radoSomething:addiu$sp,$sp,-16sw$s0,0($sp)sw$s1,4($sp)sw$s2,8($sp)sw$ra,12($sp)move$s0,$a0move$s1,$a1jalsubTwo
move$s2,$v0move$a0,$s1move$a1,$s0jalsubTwoadd$v0,$v0,$s2lw$ra,12($sp)lw$s2,8($sp)lw$s1,4($sp)lw$s0,0($sp)addiu$sp,$sp,16jr$ra
intsubTwo(inta,intb){intsub=a-b;returnsub;}intdoSomething(intx,inty){inta=subTwo(x,y);intb=subTwo(y,x);…returna+b;}
b–a
intb inta
inta intb
$t0
$a0 $a1
$s0 $s1
Orig.$ra
Orig.$s2
Orig.$s1
stackOrig.$s0
Arguments
Preserved
Unpreserved
b–a$v0
ResultValue
$ra a–b$s2
0
subTwo:sub$t0,$a0,$a1move$v0,$t0jr$radoSomething:addiu$sp,$sp,-16sw$s0,0($sp)sw$s1,4($sp)sw$s2,8($sp)sw$ra,12($sp)move$s0,$a0move$s1,$a1jalsubTwo
move$s2,$v0move$a0,$s1move$a1,$s0jalsubTwoadd$v0,$v0,$s2lw$ra,12($sp)lw$s2,8($sp)lw$s1,4($sp)lw$s0,0($sp)addiu$sp,$sp,16jr$ra
intsubTwo(inta,intb){intsub=a-b;returnsub;}intdoSomething(intx,inty){inta=subTwo(x,y);intb=subTwo(y,x);…returna+b;}
b–a
intb inta
orig. orig.
$t0
$a0 $a1
$s0 $s1
Orig.$ra
Orig.$s2
Orig.$s1
stackOrig.$s0
Arguments
Preserved
Unpreserved
0$v0
ResultValue
$ra orig.$s2
Originalcaller$ra
b–a
intb inta
orig. orig.
$t0
$a0 $a1
$s0 $s1
Arguments
Preserved
Unpreserved
0$v0
ResultValue
orig.$s2
LessonsLearned• Wepassedargumentsintothefunctionsusing$a*
• Weused$s*toworkoutcalculationsinregistersthatwewantedtopreserve,sowemadesuretosavetheminthecallstack– ThesevarvaluesDOneedtolivebeyondacall– Intheend,theoriginalvalueswerereturnedback
• Weused$t*toworkoutcalcs.inregsthatwedidnotneedtopreserve– ThesevaluesDONOTneedtolivebeyond
afunctioncall
• Weused$v*asregs.toreturnthevalueofthefunction
5/8/18 Matni,CS64,Sp18
RecursiveFunctions
• Thissamesetuphandlesnestedfunctioncallsandrecursion– i.e.Bysaving$ramethodicallyonthestack
• Example:recursive_fibonacci.asm
5/8/18 Matni,CS64,Sp18 16
recursive_fibonacci.asmRecalltheFibonacciSeries:0,1,1,2,3,5,8,13,etc…
fib(n)=fib(n–1)+fib(n–2)
InC/C++,wemightwritetherecursivefunctionas:intfib(intn){
if(n==0) return(0);else if(n==1) return(1); else return(fib(n-1)+fib(n-2));
}
5/8/18 Matni,CS64,Sp18 17
Basecases
recursive_fibonacci.asm• We’llneedatleast3registerstokeeptrackof:
– The(single)inputtothecall,i.e.varn– Theoutput(orpartialoutput)tothecall– Thevalueof$ra(sincethisisarecursivefunction)
Ifwemake$s0=nand$s1=fib(n–1)• Thenweneedtosave$s0,$s1and$raonthestack
– Sothatwedonotcorrupt/losewhat’salreadyintheseregs
• We’lluse$s*registersb/cweneedtopreservethembeyondthefunctioncall
5/8/18 Matni,CS64,Sp18 18
recursive_fibonacci.asm• First:Checkforthebasecases– Isn($a0)equalto0or1?
• Next:3registerscontainingintegers,meansweneedtoplanfor3wordsinthestack– Push3wordsin(i.e.12bytes)– $sp–=12– Theorderbywhichyouputthemindoes
notstrictlymatter,butitmakesmore“organized”senseto push$s0,$s1,then$ra
Matni,CS64,Sp18 19
Orig.$s0
Orig.$s1
Orig.$ra
n$a0
stack
$sp
Orig.ra$ra
Orig.s0 Orig.s1$s0 $s1
recursive_fibonacci.asm• Next:calculatefib(n–1)
– Callrecursively,copyoutputin$s1• Next:calculatefib(n–2)
Matni,CS64,Sp18 20
n fib(n-1)$s0 $s1
Orig.$s0
Orig.$s1
Orig.$ra
n$a0
stack
fib(n-1)$v0
$sp
Orig.ra$raNewra
recursive_fibonacci.asm• Next:calculatefib(n–1)
– Callrecursively,copyoutputin$s1• Next:calculatefib(n–2)
– Callrecursively,addoutputto$s1
Matni,CS64,Sp18 21
n$s0 $s1
Orig.$s0
Orig.$s1
Orig.$ra
n$a0
stack
fib(n-1)$v0fib(n-2)fib(n-1)+f(n-2)
Orig.s1fib(n-1)
$sp
Newra$ra
recursive_fibonacci.asm• Next:calculatefib(n–1)
– Callrecursively,copyoutputin$s1• Next:calculatefib(n–2)
– Callrecursively,addoutputto$s1• Next:restoreregisters
– Popthe3wordsbackto$s0,$s1,and$ra
• Next:returntocaller– Issueajr$rainstruction
• Notehowwhenweleavethefunctionandgobacktothe“callee”,wedidnotdisturbwhatwasintheregisterspreviously
• Andnowwehaveouroutputwhereitshouldbe,in$v0 Matni,CS64,Sp18 22
n fib(n-1)$s0 $s1
Orig.$s0
Orig.$s1
Orig.$ra
n$a0
stack
$v0fib(n-1)+f(n-2)Orig.s1Orig.s0
$sp
$raNewraOrig.ra
TailRecursion• Checkoutthedemofiletail_recursive_factorial.asmathome• What’sspecialaboutthetailrecursivefunctions(seeexample)?
– Wheretherecursivecallistheverylastthinginthefunction.– Withtherightoptimization,itcanuseaconstantstackspace(noneedtokeepsaving$raoverandover–moreefficient)
intTRFac(intn,intaccum){
if(n==0) returnaccum;else returnTRFac(n–1,n*accum);
}
5/8/18 Matni,CS64,Sp18 23
Forexample,ifyousaid:TRFac(4,1)Thentheprogramwouldreturn:TRFac(3,4),thenreturnTRFac(2,12),thenreturnTRFac(1,24),thenreturnTRFac(0,24),then,sincen=0,Itwouldreturn24
YOURTO-DOs
• FinishLab#5byFriday!
• Taketheonlinemid-termevaluations– SeeupcomingannouncementonPiazza
• Nextlecture:DigitalLogic!
5/8/18 Matni,CS64,Sp18 24