functions and the mips calling convention 2 · lecture outline • recapping mips calling...
TRANSCRIPT
FunctionsandtheMIPSCallingConvention 2
CS64:ComputerOrganizationandDesignLogicLecture#11
ZiadMatni
Dept.ofComputerScience,UCSB
Administrative• Lab5dueendofdaytomorrow
• Midterm:toreview,seetheT.A.s– LastnamesAthruN:gotoJinjin– LastnamesOthruZ: gotoBay-Yuan
• Mid-quarterevaluations– LinksonthelastslideandwillputuponPiazzatoo– Optionaltodo,butveryappreciatedbyus!– There’sstilltheESCIevalsattheendofthequarter…
2/22/18 Matni,CS64,Wi18 2
LectureOutline
• RecappingMIPSCallingConvention
– Functioncallingfunctionexample
– Recursivefunctionexample
2/22/18 Matni,CS64,Wi18 3
POP!QUIZ!ConsiderthisC/C++code:voidthird(){}voidsecond(){third();}voidfirst(){second();exit()}AndconsiderthissupposedlyequivalentMIPScodeèèèèa) Arethereanyerrorsinit?
(i.e.willitrun?)b) DoesitfollowtheMIPSC.C.?
EXPLAINYOURANSWER2/22/18 Matni,CS64,Wi18 4
third:jr$ra
second:move$t0,$rajalthirdjr$t0
first:jalsecond
li$v0,10syscall
TheMIPSConventionInItsEssence• Remember:PreservedvsUnpreservedRegs• Preserved: $s0-$s7,and$sp• Unpreserved: $t0-$t9,$a0-$a3,and$v0-$v1
• ValuesheldinPreservedRegsimmediatelybeforeafunctioncallMUSTbethesameimmediatelyafterthefunctionreturns.
• ValuesheldinUnpreservedRegsmustalwaysbeassumedtochangeafterafunctioncallisperformed.– $a0-$a3areforpassingargumentsintoafunction– $v0-$v1areforpassingvaluesfromafunction
2/22/18 Matni,CS64,Wi18 5
Matni,CS64,Wi18 6
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.
2/22/18
Matni,CS64,Wi18 72/22/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
2/22/18 Matni,CS64,Wi18
AnotherExampleUsingRecursion
2/22/18 Matni,CS64,Wi18 12
RecursiveFunctions
• Thissamesetuphandlesnestedfunctioncallsandrecursion– i.e.Bysaving$ramethodicallyonthestack
• Example:recursive_fibonacci.asm
2/22/18 Matni,CS64,Wi18 13
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));
}
2/22/18 Matni,CS64,Wi18 14
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/cweneedtopreservethem
beyondthefunctioncall
2/22/18 Matni,CS64,Wi18 15
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,Wi18 16
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,Wi18 17
n fib(n-1)$s0 $s1
Orig.$s0
Orig.$s1
Orig.$ra
n$a0
stack
fib(n-1)$v0
$sp
Orig.ra$ra
Newra
recursive_fibonacci.asm• Next:calculatefib(n–1)
– Callrecursively,copyoutputin$s1• Next:calculatefib(n–2)
– Callrecursively,addoutputto$s1
Matni,CS64,Wi18 18
n$s0 $s1
Orig.$s0
Orig.$s1
Orig.$ra
n$a0
stack
fib(n-1)$v0
fib(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,Wi18 19
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)
intTRFac(intn,intaccum){
if(n==0) returnaccum;else returnTRFac(n–1,n*accum);
}
2/22/18 Matni,CS64,Wi18 20
Forexample,ifyousaid:TRFac(4,1)Thentheprogramwouldreturn:TRFac(3,4),thenreturnTRFac(2,12),thenreturnTRFac(1,24),thenreturnTRFac(0,24),then,sincen=0,24
YOURTO-DOs
• FinishLab#5byendofdayFriday
• Taketheonlinemid-termevaluationsbyMONDAY!J– TAs: https://goo.gl/forms/fK0VxzIQt09NG6iT2– Prof: https://goo.gl/forms/HJXe9b7f6ekfOSSR2
• Nextweek:DigitalLogic!
2/22/18 Matni,CS64,Wi18 21
2/22/18 Matni,CS64,Wi18 22