28
Using the MIPS Calling Convention Recursive Functions in Assembly CS 64: Computer Organization and Design Logic Lecture #10 Fall 2018 Ziad Matni, Ph.D. Dept. of Computer Science, UCSB

Using the MIPS Calling Convention Recursive Functions in ... · Using the MIPS Calling Convention Recursive Functions in Assembly CS 64: Computer Organization and Design Logic Lecture

  • Upload
    others

  • View
    16

  • Download
    0

Embed Size (px)

Citation preview

UsingtheMIPSCallingConvention

RecursiveFunctionsinAssembly

CS64:ComputerOrganizationandDesignLogicLecture#10Fall2018

ZiadMatni,Ph.D.

Dept.ofComputerScience,UCSB

Administrative•  Lab#5thisweek–dueonFriday

•  GradeswillbeuponGauchoSpacetodaybynoon!–  Ifyouwanttoreviewyourexams,seeyourTAs:

LASTNAMESAthruQ SeeBay-Yuan (Th.12:30–2:30pm)LASTNAMESRthruZ SeeHarmeet (Th.9:30–11:30am)

•  Mid-quarterevaluationsforT.As–  LinksonthelastslideandwillputuponPiazzatoo–  Optionaltodo,butveryappreciatedbyusall!

•  Remember:NOCLASSESONMONDAY!–  Universityholiday!Remembertothankaveteran!

11/7/18 Matni,CS64,Fa18 2

AnyQuestionsFromLastLecture?

11/7/18 Matni,CS64,Fa18 3

5MinutePopQuiz!ConsiderthisC/C++code:voidthird(){}voidsecond(){third();}voidfirst(){second();}intmain(){first();}AndconsiderthissupposedlyequivalentMIPScodeèèèèa)  Arethereanyerrorsinit?

(i.e.willitrun?)

b)  DoesitfollowtheMIPSC.C.?EXPLAINYOURANSWER

11/7/18 Matni,CS64,Fa18 4

third:jr$ra

second:move$t0,$rajalthirdjr$t0

first:move$t1,$rajalsecondjr$t1

main:jalfirstli$v0,10syscall

LectureOutline

•  RecappingMIPSCallingConvention

– Functioncallingfunctionexample

– Recursivefunctionexample

11/7/18 Matni,CS64,Fa18 5

TheMIPSConventionInItsEssence•  Remember:PreservedvsUnpreservedRegs•  Preserved: $s0-$s7,and$sp,$ra•  Unpreserved: $t0-$t9,$a0-$a3,and$v0-$v1

•  ValuesheldinPreservedRegsimmediatelybeforeafunctioncallMUSTbethesameimmediatelyafterthefunctionreturns.

•  ValuesheldinUnpreservedRegsmustalwaysbeassumedtochangeafterafunctioncallisperformed.–  $a0-$a3areforpassingargumentsintoafunction–  $v0-$v1areforpassingvaluesfromafunction

11/7/18 Matni,CS64,Fa18 6

HowtheStackWorks

11/7/18 Matni,CS64,Fa18 7

•  Uponreset,$sppointstothe“bottomofthestack”– thelargestaddressforthestack•  (0x7FFFFFFC,seeMIPSRefCard)

•  Asyoumove$sp,itgoesfromhightolowaddress

•  The“topofthestack”isthestacklimit•  (0x10008000,seeMIPSRefCard)

HowtheStackWorks

11/7/18 Matni,CS64,Fa18 8

•  WhenyouwanttostoresomeNregistersintothestack,theconventionsaysyoumust:

A.  Makeroominthestack(i.e.move$sp4xNplaces)

B.  Thenstorewordsaccordingly

HowtheStackWorks

11/7/18 Matni,CS64,Fa18 9

Example:Youwanttostore$s0,$s1,and$s2:addiu$sp,$sp,-12 #‘cuz3x4=12sw$s0,8($sp)sw$s1,4($sp)sw$s2,0($sp)

$s0

$s1

$s2$sp

Bottomofstack

Matni,CS64,Fa18 10

……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?

Ok,b/cIdon’tcareabout$t*(notthebesttactic,tho…)Eventually,Ihavetohavesubbe$v0

doSomethingDOEScallafunctionWhatshouldImapxandyto?

SincewewanttopreservethemacrossthecalltosubTwo,weshouldmapthemto$s0and$s1WhatshouldImapaandbto?

“a+b”hastoeventuallybe$v0.Ishouldmakeatleastabeapreservedreg($s2).SinceIgetbbackfromacallandthere’snoothercallafterit,Icanlikelygetawaywithnotusingapreservedregforb.

Matni,CS64,Fa18 1111/7/18

subTwo:sub$v0,$a0,$a1jr$radoSomething:#preserveforthesake#ofwhatevercalled#doSomethingaddiu$sp,$sp,-16sw$s0,0($sp)sw$s1,4($sp)sw$s2,8($sp)sw$ra,12($sp)move$s0,$a0move$s1,$a1jalsubTwomove$s2,$v0

move$a0,$s1move$a1,$s0jalsubTwoadd$v0,$v0,$s2#popbackthepreserved#sothatthey’reready#forwhatevercalled#doSomethinglw$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$v0,$a0,$a1jr$radoSomething:addiu$sp,$sp,-16sw$s0,0($sp)sw$s1,4($sp)sw$s2,8($sp)sw$ra,12($sp)move$s0,$a0move$s1,$a1jalsubTwomove$s2,$v0

move$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

inta intb

inta intb

$t0-$t9

$a0 $a1

$s0 $s1

Orig.$ra

Orig.$s2

Orig.$s1

stackOrig.$s0

Arguments

Preserved

Unpreserved

a–b$v0

ResultValue

$ra a–b$s2

move$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;}

intb inta

inta intb

$t0-$t9

$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$v0,$a0,$a1jr$radoSomething:addiu$sp,$sp,-16sw$s0,0($sp)sw$s1,4($sp)sw$s2,8($sp)sw$ra,12($sp)move$s0,$a0move$s1,$a1jalsubTwomove$s2,$v0

move$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;}

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

subTwo:sub$v0,$a0,$a1jr$radoSomething:addiu$sp,$sp,-16sw$s0,0($sp)sw$s1,4($sp)sw$s2,8($sp)sw$ra,12($sp)move$s0,$a0move$s1,$a1jalsubTwomove$s2,$v0

LessonsLearned•  Wepassedargumentsintothefunctionsusing$a*

•  Weused$s*toworkoutcalculationsinregistersthatwewantedtopreserve,sowemadesuretosavetheminthecallstack–  ThesevarvaluesDOneedtolivebeyondacall–  Intheend,theoriginalvalueswerereturnedback

•  Wecoulduse$t*toworkoutsomecalcs.inregsthatwedidnotneedtopreserve–  ThesevaluesDONOTneedtolivebeyondafunctioncall

•  Weused$v*asregs.toreturnthevalueofthefunction

11/7/18 Matni,CS64,Fa18

AnotherExampleUsingRecursion

11/7/18 Matni,CS64,Fa18 16

RecursiveFunctions

•  Thissamesetuphandlesnestedfunctioncallsandrecursion–  i.e.Bysaving$ramethodicallyonthestack

•  Example:recursive_fibonacci.asm

11/7/18 Matni,CS64,Fa18 17

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));

}

11/7/18 Matni,CS64,Fa18 18

Basecases

recursive_fibonacci.asm•  We’llneedatleast3registerstokeeptrackof:

–  The(single)inputtothecall,i.e.varn–  Theoutput(orpartialoutput)tothecall–  Thevalueof$ra(sincethisisarecursivefunction)

•  We’lluse$s*registersb/cweneedtopreservethesevars/regs.beyondthefunctioncall

Ifwemake$s0=nand$s1=fib(n–1)•  Thenweneedtosave$s0,$s1and$raonthestackinthe

“fibonnaci”function–  Sothatwedonotcorrupt/losewhat’salreadyintheseregs

11/7/18 Matni,CS64,Fa18 19

recursive_fibonacci.asm

•  So,westartoffinthemain:portion– nisourargumentintothefunction,soit’sin$a0

•  We’llputournumber(example:7)in$a0andthencallthefunction“fibonacci”–  i.e. li$a0,7 jalfibonacci

11/7/18 Matni,CS64,Fa18 20

recursive_fibonacci.asmInsidethefunction“fibonacci”

•  First:Checkforthebasecases–  Isn($a0)equalto0or1?–  Branchaccordingly

•  Next:Dotherecursion---butfirst…!Weneedtoplanfor3wordsinthestack–  $sp=$sp–12–  Push3wordsin(i.e.12bytes)–  Theorderbywhichyouputthemindoes

notstrictlymatter,butitmakesmore“organized”sensetopush$s0,then$s1,then$ra

Matni,CS64,Fa18 21

Orig.$s0

Orig.$s1

Orig.$ra

n$a0

stack

$sp

Orig.ra$ra

Orig.s0 Orig.s1$s0 $s1

11/7/18

recursive_fibonacci.asm•  Next:calculatefib(n–1)

–  Callrecursively&copyoutput($v0)in$s1•  Next:calculatefib(n–2)

Matni,CS64,Fa18 22

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&copyoutput($v0)in$s1•  Next:calculatefib(n–2)

–  Callrecursively&add$s1totheoutput($v0)

Matni,CS64,Fa18 23

n$s0 $s1

Orig.$s0

Orig.$s1

Orig.$ra

n$a0

stack

fib(n-1)$v0

fib(n-2)fib(n-1)+fib(n-2)Orig.s1fib(n-1)

$sp

Newra$ra

recursive_fibonacci.asm•  Next:calculatefib(n–1)

–  Callrecursively&copyoutput($v0)in$s1•  Next:calculatefib(n–2)

–  Callrecursively&add$s1totheoutput($v0)•  Next:restoreregisters

–  Popthe3wordsbackto$s0,$s1,and$ra

•  Next:returntocaller(i.e.main)–  Issueajr$rainstruction

•  Notehowwhenweleavethefunctionandgobacktothe“callee”(main),wedidnotdisturbwhatwasintheregisterspreviously

•  Andnowwehaveouroutputwhereitshouldbe,in$v0 Matni,CS64,Fa18 24

n fib(n-1)$s0 $s1

Orig.$s0

Orig.$s1

Orig.$ra

n$a0

stack

$v0fib(n-1)+fib(n-2)Orig.s1Orig.s0

$sp

$raNewraOrig.ra

ACloserLookattheCode

•  Openrecursive_fibonacci.asm

11/7/18 Matni,CS64,Fa18 25

TailRecursion•  Checkoutthedemofiletail_recursive_factorial.asmathome•  What’sspecialaboutthetailrecursivefunctions(seeexample)?

–  Wheretherecursivecallistheverylastthinginthefunction.–  Withtherightoptimization,itcanuseaconstantstackspace

(noneedtokeepsaving$raoverandover–it’smoreefficient)

intTRFac(intn,intaccum){

if(n==0) returnaccum;else returnTRFac(n–1,n*accum);

}

11/7/18 Matni,CS64,Fa18 26

Forexample,ifyousaid:TRFac(4,1)Thentheprogramwouldreturn:TRFac(3,4),thenreturnTRFac(2,12),thenreturnTRFac(1,24),thenreturnTRFac(0,24),then,sincen=0,Itwouldreturn24

YourTo-Dos

•  Again,MAKESUREyou’vereadthe MIPSCallingConventionPDFfromourclasswebsite

•  Gooverthefibonnaci.asmandtail_recursive_factorial.asmprograms

•  Nextweek:IntrotoDigitalLogic(onWed.,‘cuzwedon’thaveclassonMon.!!!!)

11/7/18 Matni,CS64,Fa18 27

11/7/18 Matni,CS64,Fa18 28