Procedures & The Stack Spring 2016 Procedures & The StackProcedures & The Stack Spring...

Preview:

Citation preview

Spring 2016Procedures & The Stack

Procedures&TheStack

Announcements¢ Lab1graded

§ Latedays§ Extracredit

¢ HW2out¢ Lab2prepinsectiontomorrow

§ Bringlaptops!¢ Slides

1

HTTP://XKCD.COM/1270/

Spring 2016Procedures & The Stack

Roadmap

2

car *c = malloc(sizeof(car));c->miles = 100;c->gals = 17;float mpg = get_mpg(c);free(c);

Car c = new Car();c.setMiles(100);c.setGals(17);float mpg =

c.getMPG();

get_mpg:pushq %rbpmovq %rsp, %rbp...popq %rbpret

Java:C:

Assemblylanguage:

Machinecode:

01110100000110001000110100000100000000101000100111000010110000011111101000011111

Computersystem:

OS:

Memory&dataIntegers&floatsMachinecode&Cx86assemblyProcedures&stacksArrays&structsMemory&cachesProcessesVirtualmemoryMemoryallocationJavavs.C

Spring 2016Procedures & The Stack

Mechanismsrequiredforprocedures¢ Passingcontrol

§ Tobeginningofprocedurecode§ Backtoreturnpoint

¢ Passingdata§ Procedurearguments§ Returnvalue

¢ Memorymanagement§ Allocateduringprocedureexecution§ Deallocate uponreturn

¢ Allimplementedwithmachineinstructions§ Anx86-64procedureusesonlythose

mechanismsrequiredforthatprocedure

P(…) {••y = Q(x);print(y)•

}

int Q(int i){

int t = 3*i; int v[10];••return v[t];

}

3

Spring 2016Procedures & The Stack

Questionstoansweraboutprocedures

¢ HowdoIpassargumentstoaprocedure?¢ HowdoIgetareturnvaluefromaprocedure?¢ WheredoIputlocalvariables?¢ Whenafunctionreturns,howdoesitknowwheretoreturn?

¢ Toanswersomeofthesequestions,weneedacallstack …

4

Spring 2016Procedures & The Stack

Outline¢ StackStructure¢ CallingConventions

§ Passingcontrol§ Passingdata§ Managinglocaldata

¢ IllustrationofRecursion

5

Spring 2016Procedures & The Stack

MemoryLayout

6

Instructions

Literals

StaticData

DynamicData(Heap)

Stack

Largeconstants(e.g.,“example”)

static variables(includingglobalvariables(C))

variablesallocatedwithnew ormalloc

localvariables;procedurecontext

0

2N-1

MemoryAddresses

HighAddresses

LowAddresses

Spring 2016Procedures & The Stack

MemoryLayout

7

Instructions

Literals

StaticData

DynamicData(Heap)

Stack Managed“automatically”(bycompiler)writable;notexecutable

Managedbyprogrammerwritable;notexecutable

Initializedwhenprocessstartswritable;notexecutable

Initializedwhenprocessstartsread-only;notexecutable

Initializedwhenprocessstartsread-only;executable

segmentationfaults?

Spring 2016Procedures & The Stack

x86-64Stack

¢ Regionofmemorymanagedwithstack“discipline”§ Growstowardloweraddresses§ Customarilyshown“upside-down”

¢ Register%rsp containsloweststackaddress§ %rsp =addressoftop element,the

most-recently-pusheditemthatisnot-yet-popped

StackPointer:%rsp

Stack“Top”

Stack“Bottom”HighAddresses

LowAddresses

StackGrowsDown

IncreasingAddresses

8

Spring 2016Procedures & The Stack

x86-64Stack:Push¢ pushq Src§ FetchoperandatSrc

§ Src canbereg,memory,immediate§ Decrement %rsp by8§ Storevalueataddressgivenby%rsp

¢ Example:§ pushq %rcx§ Adjust%rsp andstorecontentsof

%rcx onthestack

-8

Stack“Bottom”

StackPointer:%rsp

Stack“Top”

HighAddresses

LowAddresses0x00…00

StackGrowsDown

IncreasingAddresses

9

Spring 2016Procedures & The Stack

¢ popq Dest§ Loadvalueataddressgivenby%rsp§ StorevalueatDest (mustberegister)§ Increment %rsp by8

¢ Example:§ popq %rcx§ Storescontentsoftopofstackinto%rcx andadjust%rsp

StackPointer:%rsp

Stack“Top”

Stack“Bottom”x86-64Stack:Pop

+8

HighAddresses

LowAddresses0x00…00

StackGrowsDown

IncreasingAddresses

10

Thosebitsarestillthere;we’rejustnotusingthem.

Spring 2016Procedures & The Stack

Procedures¢ StackStructure¢ CallingConventions

§ Passingcontrol§ Passingdata§ Managinglocaldata

¢ IllustrationofRecursion

11

Spring 2016Procedures & The Stack

ProcedureCallOverview

12

Caller

Callee

¢ Callee mustknowwheretofindargs¢ Callee mustknowwheretofindreturnaddress¢ Callermustknowwheretofindreturnvalue¢ CallerandCallee runonsameCPU,sousethesameregisters

¢ Howdowedealwithregisterreuse?¢ Unneededstepscanbeskipped(e.g.ifnoargumentsornoreturnvalue)

…<setupargs>call<cleanupargs><findreturnval>…

<createlocalvars>…

<setupreturnval><destroylocalvars>ret

procedures

Spring 2016Procedures & The Stack

ProcedureCallOverview

13

Caller

Callee…

<saveregs><setupargs>call<cleanupargs><restoreregs><findreturnval>…

<saveregs><createlocalvars>…

<setupreturnval><destroylocalvars><restoreregs>ret

¢ Theconvention ofwheretoleave/findthingsiscalledthecallingconvention(orprocedurecalllinkage).§ Detailsvarybetweensystems§ Wewillseetheconventionforx86-64/Linux indetail§ Whatcouldhappenifourprogramdidn’tfollowtheseconventions?

Spring 2016Procedures & The Stack

CodeExamples

long mult2(long a, long b)

{long s = a * b;return s;

}

void multstore(long x, long y, long *dest) {

long t = mult2(x, y);*dest = t;

}

0000000000400550 <mult2>:400550: mov %rdi,%rax # a400553: imul %rsi,%rax # a * b400557: retq # Return

0000000000400540 <multstore>:400540: push %rbx # Save %rbx400541: mov %rdx,%rbx # Save dest400544: callq 400550 <mult2> # mult2(x,y)400549: mov %rax,(%rbx) # Save at dest40054c: pop %rbx # Restore %rbx40054d: retq # Return

14

Spring 2016Procedures & The Stack

ProcedureControlFlow¢ Usestacktosupportprocedurecallandreturn¢ Procedurecall:call label

1. Pushreturnaddressonstack(why?,andwhichexactaddress?)2. Jumptolabel

15

Spring 2016Procedures & The Stack

ProcedureControlFlow¢ Usestacktosupportprocedurecallandreturn¢ Procedurecall:call label

1. Pushreturnaddressonstack2. Jumptolabel

¢ Returnaddress:§ Addressofinstructionimmediatelyaftercall instruction§ Examplefromdisassembly:

400544: callq 400550 <mult2>

400549: movq %rax,(%rbx)

Returnaddress=0x400549

¢ Procedurereturn:ret1. Popreturnaddressfromstack2. Jumptoaddress

16

nextinstructionhappenstobeamove,butcouldbeanything

Spring 2016Procedures & The Stack

ProcedureCall Example(step1)

0000000000400550 <mult2>:400550: mov %rdi,%rax••400557: retq

0000000000400540 <multstore>:••400544: callq 400550 <mult2>400549: mov %rax,(%rbx)••

0x400544

0x120

•••

%rsp

0x120

0x128

0x130

%rip

17

Spring 2016Procedures & The Stack

0000000000400550 <mult2>:400550: mov %rdi,%rax••400557: retq

0000000000400540 <multstore>:••400544: callq 400550 <mult2>400549: mov %rax,(%rbx)••

0x400550

0x118

0x400549

•••

%rsp

0x120

0x128

0x130

0x118

%rip

ProcedureCall Example(step2)

18

Spring 2016Procedures & The Stack

0000000000400550 <mult2>:400550: mov %rdi,%rax••400557: retq

0000000000400540 <multstore>:••400544: callq 400550 <mult2>400549: mov %rax,(%rbx)••

0x400557

0x118

0x400549

•••

%rsp

0x120

0x128

0x130

0x118

%rip

ProcedureReturnExample(step1)

19

Spring 2016Procedures & The Stack

0000000000400550 <mult2>:400550: mov %rdi,%rax••400557: retq

0000000000400540 <multstore>:••400544: callq 400550 <mult2>400549: mov %rax,(%rbx)••

0x400549

0x120

•••

%rsp

0x120

0x128

0x130

%rip

ProcedureReturn Example(step2)

20

Spring 2016Procedures & The Stack

Procedures¢ StackStructure¢ CallingConventions

§ Passingcontrol§ Passingdata§ Managinglocaldata

¢ IllustrationofRecursion

21

Spring 2016Procedures & The Stack

ProcedureDataFlow

Registers– NOTinMemory!¢ First6arguments

¢ Returnvalue

Stack– inMemory!

¢ Onlyallocatestackspacewhenneeded

%rdi

%rsi

%rdx

%rcx

%r8

%r9

%rax

Arg 7

•• •

Arg 8

Arg n

•• •

HighAddresses

LowAddresses0x00…00

Diane’sSilkDressCosts$8 9

Spring 2016Procedures & The Stack

X86-64ReturnValues¢ Byconvention,valuesreturnedbyproceduresareplacedinthe

%rax register§ Choiceof%rax isarbitrary,couldhaveeasilybeenadifferentregister

¢ Caller mustmakesuretosavethecontentsof%rax beforecallingacallee thatreturnsavalue§ Partofregister-savingconvention

¢ Calleeplacesreturnvalueintothe%rax register§ Anytypethatcanfitin8bytes– integer,float,pointer,etc.§ Forreturnvaluesgreaterthan8bytes,besttoreturnapointer tothem

¢ Uponreturn,caller findsthereturnvalueinthe%rax register

23

Spring 2016Procedures & The Stack

DataFlow Examples

long mult2(long a, long b)

{long s = a * b;return s;

}

void multstore(long x, long y, long *dest) {

long t = mult2(x, y);*dest = t;

}

0000000000400550 <mult2>:# a in %rdi, b in %rsi400550: movq %rdi,%rax # a 400553: imul %rsi,%rax # a * b# s in %rax400557: retq # Return

0000000000400540 <multstore>:# x in %rdi, y in %rsi, dest in %rdx•••400541: movq %rdx,%rbx # Save dest400544: callq 400550 <mult2> # mult2(x,y)# t in %rax400549: movq %rax,(%rbx) # Save at dest•••

24

Spring 2016Procedures & The Stack

Outline¢ Procedures

§ StackStructure§ CallingConventions

§ Passingcontrol§ Passingdata§ Managinglocaldata

§ IllustrationofRecursion

25

Spring 2016Procedures & The Stack

Stack-BasedLanguages¢ Languagesthatsupportrecursion

§ e.g.,C,Java,mostmodern languages§ Codemustbe re-entrant

§ Multiple simultaneous instantiationsofsingleprocedure§ Needsomeplacetostorestateofeachinstantiation

§ Arguments§ Localvariables§ Returnpointer

¢ Stackdiscipline§ Statefor agivenprocedureneededfor alimitedtime

§ Startingfromwhenitiscalledtowhen itreturns§ Callee alwaysreturnsbeforecallerdoes

¢ Stackallocatedin frames§ Statefor asingleprocedure instantiation

26

Spring 2016Procedures & The Stack

FramePointer:%rbp(Optional)

StackFrames¢ Contents

§ Returnaddress§ IfNeeded:

§ Localvariables§ Temporaryspace

¢ Management§ Spaceallocatedwhen procedureisentered

§ “Set-up”code§ Spacedeallocateduponreturn

§ “Finish”code

StackPointer:%rsp

PreviousFrame

Stack“Top”

27

Framefor

currentproc

Spring 2016Procedures & The Stack

CallChainExample

yoo(…){

••who();••

}

who(…){

• amI();• amI();•

}

amI(…){

•if(…){amI()

}•

}

yoo

who

amI

amI

amI

ExampleCallChain

amI

ProcedureamI isrecursive(callsitself)

28

Spring 2016Procedures & The Stack

Example:calltoyoo

yoo

who

amI

amI

amI

amI

yoo

%rbp

%rsp

Stack

yoo

yoo(…){

••who();••

}

29

Spring 2016Procedures & The Stack

yoo(…){

••who();••

}

Example:calltowho

yoo

who

amI

amI

amI

amI

yoo

%rbp

%rsp

Stack

yoo

who

who(…){

• amI();• amI();•

}

30

Spring 2016Procedures & The Stack

yoo(…){

••who();••

}

who(…){

• • •amI();• • •amI();• • •

}

Example:calltoamI

yoo

who

amI

amI

amI

amI

yoo

%rbp

%rsp

Stack

yoo

who

amI

amI(…){

•if(){amI()

}•

}

31

Spring 2016Procedures & The Stack

Example:recursivecalltoamI

yoo

who

amI

amI

amI

amI

yoo

%rbp

%rsp

Stack

yoo

who

amI

amI

yoo(…){

••who();••

}

who(…){

• • •amI();• • •amI();• • •

}

amI(…){

••amI();••

}

amI(…){

•if(){amI()

}•

}

32

Spring 2016Procedures & The Stack

Example:(another)recursivecalltoamI

yoo

who

amI

amI

amI

amI

yoo

%rbp

%rsp

Stack

yoo

who

amI

amI

amI

yoo(…){

••who();••

}

who(…){

• • •amI();• • •amI();• • •

}

amI(…){

•if(){amI()

}•

}

amI(…){

•if(){amI()

}•

}

amI(…){

•if(){amI()

}•

}

33

Spring 2016Procedures & The Stack

Returnfrom:(another)recursivecalltoamI

yoo

who

amI

amI

amI

amI

yoo

%rbp

%rsp

Stack

yoo

who

amI

amI

yoo(…){

••who();••

}

who(…){

• • •amI();• • •amI();• • •

}

amI(…){

•if(){amI()

}•

}

amI(…){

•if(){amI()

}•

}

amI

34

Spring 2016Procedures & The Stack

Returnfrom:recursivecalltoamI

yoo

who

amI

amI

amI

amI

yoo

%rbp

%rsp

Stack

yoo

who

amI

yoo(…){

••who();••

}

who(…){

• • •amI();• • •amI();• • •

}

amI(…){

•if(){amI()

}•

}

amI

amI

35

Spring 2016Procedures & The Stack

Returnfrom:calltoamI

yoo

who

amI

amI

amI

amI

yoo

%rbp

%rsp

Stack

yoo

who

yoo(…){

••who();••

}

who(…){

• amI();• amI();•

} amI

amI

amI

36

Spring 2016Procedures & The Stack

Example:(second)calltoamI

yoo

who

amI

amI

amI

amI

yoo

%rbp

%rsp

Stack

yoo

who

amI

yoo(…){

••who();••

}

who(…){

• amI();• amI();•

}

amI(…){

•if(){amI()

}•

}

37

Spring 2016Procedures & The Stack

Returnfrom:(second)calltoamI

yoo

who

amI

amI

amI

amI

yoo

%rbp

%rsp

Stack

yoo

who

yoo(…){

••who();••

}

who(…){

• amI();• amI();•

} amI

38

Spring 2016Procedures & The Stack

Returnfrom:calltowho

yoo

who

amI

amI

amI

amI

yoo

%rbp

%rsp

Stack

yooyoo(…){

••who();••

} amI

who

39

Spring 2016Procedures & The Stack

x86-64/LinuxStackFrame

¢ Caller’s StackFrame§ Extraarguments(if>6args)forthiscall§ Returnaddress

§ Pushedbycall instruction

¢ Current/Callee StackFrame§ Oldframepointer(optional)§ Savedregistercontext

(whenreusingregisters)§ Localvariables

(Ifcan’tbekeptinregisters)§ “Argumentbuild”area

(Ifcallee needstocallanotherfunction-parametersforfunctionabouttocall,ifneeded)

ReturnAddr

SavedRegisters

+Local

Variables

ArgumentBuild

(Optional)

Old%rbp

Arguments7+

CallerFrame

Framepointer%rbp

Stackpointer%rsp

(Optional)

40

Spring 2016Procedures & The Stack

April22

41

Spring 2016Procedures & The Stack

Example:incrementlong increment(long *p, long val) {

long x = *p;long y = x + val;*p = y;return x;

}

increment:movq (%rdi), %raxaddq %rax, %rsimovq %rsi, (%rdi)ret

Register Use(s)

%rdi Argumentp

%rsi Argumentval,y

%rax x,Returnvalue

42

Spring 2016Procedures & The Stack

ProcedureCallExample(initialstate)

¢ Returnaddressonstackis:§ addressofinstructionimmediately

followingthecallto“call_incr”(shownhereasmain,butcouldbeanything).

43

call_incr:subq $16, %rspmovq $351, 8(%rsp)movl $100, %esileaq 8(%rsp), %rdicall incrementaddq 8(%rsp), %raxaddq $16, %rspret

long call_incr() {long v1 = 351;long v2 = increment(&v1, 100);return v1+v2;

}

InitialStackStructure

•••

Returnaddr <main+8> ⟵%rsp

Spring 2016Procedures & The Stack

ProcedureCallExample(step1)

¢ Setupspaceforlocalvariables§ Onlyv1needsspaceonthestack

¢ Compilerallocatedextraspace§ Oftendoesthisforavarietyof reasons,

including alignment.

44

call_incr:subq $16, %rspmovq $351, 8(%rsp)movl $100, %esileaq 8(%rsp), %rdicall incrementaddq 8(%rsp), %raxaddq $16, %rspret

StackStructure

Allocatespaceforlocalvars

long call_incr() {long v1 = 351;long v2 = increment(&v1, 100);return v1+v2;

}

•••

Returnaddr <main+8>

351Unused

⟵old %rsp

⟵%rsp

⟵%rsp+8

Spring 2016Procedures & The Stack

ProcedureCallExample(step2)

call_incr:subq $16, %rspmovq $351, 8(%rsp)movl $100, %esileaq 8(%rsp), %rdicall incrementaddq 8(%rsp), %raxaddq $16, %rspret

StackStructure

45

Setupparametersforcalltoincrement

long call_incr() {long v1 = 351;long v2 = increment(&v1, 100);return v1+v2;

}

Aside: movl isusedbecause100isasmallpositive valuethatfitsin32bits.Highorderbitsofrsi getsettozeroautomatically.Ittakesonelessbytetoencodeamovl thanamovq.

Register Use(s)

%rdi &v1

%rsi 100

•••

Returnaddr <main+8>

351Unused ⟵%rsp

⟵%rsp+8

Spring 2016Procedures & The Stack

ProcedureCallExample(step3)

¢ Statewhileinsideincrement.§ Returnaddressontopofstackisaddress

oftheaddq instruction immediatelyfollowing calltoincrement.

46

call_incr:subq $16, %rspmovq $351, 8(%rsp)movl $100, %esileaq 8(%rsp), %rdicall incrementaddq 8(%rsp), %raxaddq $16, %rspret

long call_incr() {long v1 = 351;long v2 = increment(&v1, 100);return v1+v2;

}

StackStructure

increment:movq (%rdi), %raxaddq %rax, %rsimovq %rsi, (%rdi)ret

Register Use(s)

%rdi &v1

%rsi 100

%rax

•••

Returnaddr <main+8>

351Unused

Returnaddr <call_incr+?> ⟵%rsp

Spring 2016Procedures & The Stack

ProcedureCallExample(step4)

¢ Statewhileinsideincrement.§ After codeinbodyhasbeenexecuted.

47

call_incr:subq $16, %rspmovq $351, 8(%rsp)movl $100, %esileaq 8(%rsp), %rdicall incrementaddq 8(%rsp), %raxaddq $16, %rspret

long call_incr() {long v1 = 351;long v2 = increment(&v1, 100);return v1+v2;

}

StackStructure

increment:movq (%rdi), %rax # x = *paddq %rax, %rsi # y = x+100movq %rsi, (%rdi) # *p = yret

Register Use(s)

%rdi &v1

%rsi 451

%rax 351

•••

Returnaddr <main+8>

451Unused

Returnaddr <call_incr+?> ⟵%rsp

Spring 2016Procedures & The Stack

ProcedureCallExample(step5)

¢ Afterreturningfromcalltoincrement.§ Registersandmemoryhavebeenmodified

andreturnaddresshasbeenpoppedoffstack.

48

call_incr:subq $16, %rspmovq $351, 8(%rsp)movl $100, %esileaq 8(%rsp), %rdicall incrementaddq 8(%rsp), %raxaddq $16, %rspret

StackStructurelong call_incr() {

long v1 = 351;long v2 = increment(&v1, 100);return v1+v2;

}

Register Use(s)

%rdi &v1

%rsi 451

%rax 351

•••

Returnaddr <main+8>

451Unused ⟵%rsp

⟵%rsp+8

Spring 2016Procedures & The Stack

ProcedureCallExample(step6)StackStructure

49

long call_incr() {long v1 = 351;long v2 = increment(&v1, 100);return v1+v2;

}

call_incr:subq $16, %rspmovq $351, 8(%rsp)movl $100, %esileaq 8(%rsp), %rdicall incrementaddq 8(%rsp), %raxaddq $16, %rspret Register Use(s)

%rax 451+351

•••

Returnaddr <main+8>

451Unused ⟵%rsp

⟵%rsp+8

Update%rax tocontainv1+v2

Spring 2016Procedures & The Stack

ProcedureCallExample(step7)StackStructure

50

De-allocatespaceforlocalvars

long call_incr() {long v1 = 351;long v2 = increment(&v1, 100);return v1+v2;

}

call_incr:subq $16, %rspmovq $351, 8(%rsp)movl $100, %esileaq 8(%rsp), %rdicall incrementaddq 8(%rsp), %raxaddq $16, %rspret Register Use(s)

%rax 802

•••

Returnaddr <main+8>

451Unused

⟵%rsp

⟵old %rsp

Spring 2016Procedures & The Stack

ProcedureCallExample(step8)

¢ Statejustbeforereturningfromcalltocall_incr.

51

call_incr:subq $16, %rspmovq $351, 8(%rsp)movl $100, %esileaq 8(%rsp), %rdicall incrementaddq 8(%rsp), %raxaddq $16, %rspret

StackStructurelong call_incr() {

long v1 = 351;long v2 = increment(&v1, 100);return v1+v2;

}

Register Use(s)

%rax 802

•••

Returnaddr <main+8> ⟵%rsp

Spring 2016Procedures & The Stack

ProcedureCallExample(step9)

¢ StateimmediatelyAFTER returningfromcalltocall_incr.§ Returnaddr hasbeenpoppedoff stack§ Controlhasreturned totheinstruction

immediately following thecalltocall_incr (not shownhere).

52

call_incr:subq $16, %rspmovq $351, 8(%rsp)movl $100, %esileaq 8(%rsp), %rdicall incrementaddq 8(%rsp), %raxaddq $16, %rspret

%rsp...

FinalStackStructurelong call_incr() {

long v1 = 351;long v2 = increment(&v1, 100);return v1+v2;

}

Register Use(s)

%rax 802

Spring 2016Procedures & The Stack

RegisterSavingConventions¢ Whenprocedureyoo callswho:§ yoo isthecaller§ who isthecallee

¢ Can registerbeusedfortemporarystorage?

§ No!Contentsofregister%rdx overwrittenbywho!§ Thiscouldbetrouble– somethingshouldbedone. Either:

§ callershouldsave%rdx before thecall(andrestoreitafterthecall)§ callee shouldsave%rdx beforeusing it(and restoreitbefore returning)

yoo:• • •movq $15213, %rdxcall whoaddq %rdx, %rax• • •ret

who:• • •subq $18213, %rdx• • •ret

?

53

Spring 2016Procedures & The Stack

RegisterSavingConventions¢ Whenprocedureyoo callswho:

§ yoo isthecaller§ who isthecallee

¢ Canaregisterbeusedfortemporarystorage?¢ Conventions

§ “Caller Saved”§ Callersavestemporaryvaluesinitsstackframebeforecalling§ Callerrestoresvaluesafterthecall

§ “CalleeSaved”§ Calleesavestemporaryvaluesinitsstackframebeforeusing§ Calleerestoresthembeforereturningtocaller

54

Spring 2016Procedures & The Stack

x86-64LinuxRegisterUsage,part1

¢ %rax§ Returnvalue§ Alsocaller-saved&restored§ Canbemodifiedbyprocedure

¢ %rdi,...,%r9§ Arguments§ Alsocaller-saved&restored§ Canbemodifiedbyprocedure

¢ %r10,%r11§ Caller-saved&restored§ Canbemodifiedbyprocedure

%rax

%rdx

%rcx

Returnvalue

%r8

%r9

%r10

%r11

%rdi

%rsi

Arguments

Caller-savedtemporaries

55

Spring 2016Procedures & The Stack

x86-64LinuxRegisterUsage,part2

¢ %rbx,%r12,%r13,%r14§ Callee-saved§ Calleemustsave&restore

¢ %rbp§ Callee-saved§ Calleemustsave&restore§ Maybeusedasframepointer§ Canmix&match

¢ %rsp§ Specialformofcallee save§ Restoredtooriginalvalueupon

exitfromprocedure

%rbx

%rsp

Callee-savedTemporaries

Special%rbp

%r12

%r13

%r14

56

Spring 2016Procedures & The Stack

%rax

%rbx

%rcx

%rdx

%rsi

%rdi

%rsp

%rbp

x86-6464-bitRegisters:UsageConventions

57

%r8

%r9

%r10

%r11

%r12

%r13

%r14

%r15Callee saved Callee saved

Callee saved

Callee saved

Callee saved

Caller saved

Callee saved

Stackpointer

Caller Saved

Returnvalue- Caller saved

Argument#4- Caller saved

Argument#1- Caller saved

Argument#3- Caller saved

Argument#2- Caller saved

Argument#6- Caller saved

Argument#5- Caller saved

Spring 2016Procedures & The Stack

Callee-SavedExample(step1)

call_incr2:pushq %rbxsubq $16, %rspmovq %rdi, %rbxmovq $351, 8(%rsp)movl $100, %esileaq 8(%rsp), %rdicall incrementaddq %rbx, %raxaddq $16, %rsppopq %rbxret

long call_incr2(long x) {long v1 = 351;long v2 = increment(&v1, 100);return x+v2;

}

InitialStackStructure

%rsp

...

Rtn address

ResultingStackStructure

351

Unused %rsp

...

Rtn address

%rsp+8

Saved%rbx

58

Spring 2016Procedures & The Stack

Callee-SavedExample(step2)

call_incr2:pushq %rbxsubq $16, %rspmovq %rdi, %rbxmovq $351, 8(%rsp)movl $100, %esileaq 8(%rsp), %rdicall incrementaddq %rbx, %raxaddq $16, %rsppopq %rbxret

Pre-returnStackStructure

%rsp

...

Rtn address

StackStructure

351

Unused %rsp

...

Rtn address

%rsp+8

Saved%rbx

59

long call_incr2(long x) {long v1 = 351;long v2 = increment(&v1, 100);return x+v2;

}

Spring 2016Procedures & The Stack

WhyCallerand CalleeSaved?¢ Wewantone callingconventiontosimplyseparate

implementationdetailsbetweencallerandcallee

¢ Ingeneral,neithercaller-savenorcallee-saveis“best”:§ Ifcallerisn’tusingaregister,caller-saveisbetter§ Ifcallee doesn’tneedaregister,callee-saveisbetter§ If“doneedtosave”,callee-savegenerallymakessmallerprograms

§ Functionsarecalledfrommultipleplaces

¢ So…“someofeach”andcompilertriesto“pickregisters”thatminimizeamountofsaving/restoring

60

Spring 2016Procedures & The Stack

Procedures¢ StackStructure¢ CallingConventions

§ Passingcontrol§ Passingdata§ Managinglocaldata

¢ IllustrationofRecursion

61

Spring 2016Procedures & The Stack

/* Recursive popcount */long pcount_r(unsigned long x) {

if (x == 0)return 0;

elsereturn (x & 1)

+ pcount_r(x >> 1);}

RecursiveFunction pcount_r:movl $0, %eaxtestq %rdi, %rdije .L6pushq %rbxmovq %rdi, %rbxandl $1, %ebxshrq %rdicall pcount_raddq %rbx, %raxpopq %rbx

.L6:rep; ret

62

Spring 2016Procedures & The Stack

RecursiveFunction:BaseCasepcount_r:

movl $0, %eaxtestq %rdi, %rdije .L6pushq %rbxmovq %rdi, %rbxandl $1, %ebxshrq %rdicall pcount_raddq %rbx, %raxpopq %rbx

.L6:rep; ret

Register Use(s) Type

%rdi x Argument

%rax Returnvalue Returnvalue

63

/* Recursive popcount */long pcount_r(unsigned long x) {

if (x == 0)return 0;

elsereturn (x & 1)

+ pcount_r(x >> 1);}

Trick becausesomeHWdoesn’tlikejumpingtoret

Spring 2016Procedures & The Stack

RecursiveFunction:RegisterSavepcount_r:

movl $0, %eaxtestq %rdi, %rdije .L6pushq %rbxmovq %rdi, %rbxandl $1, %ebxshrq %rdicall pcount_raddq %rbx, %raxpopq %rbx

.L6:rep; ret

←%rsp

...

<main+15>

Saved%rbx

64

/* Recursive popcount */long pcount_r(unsigned long x) {

if (x == 0)return 0;

elsereturn (x & 1)

+ pcount_r(x >> 1);}

Register Use(s) Type

%rdi x Argument

Spring 2016Procedures & The Stack

RecursiveFunction:CallSetuppcount_r:

movl $0, %eaxtestq %rdi, %rdije .L6pushq %rbxmovq %rdi, %rbxandl $1, %ebxshrq %rdicall pcount_raddq %rbx, %raxpopq %rbx

.L6:rep; ret

65

/* Recursive popcount */long pcount_r(unsigned long x) {

if (x == 0)return 0;

elsereturn (x & 1)

+ pcount_r(x >> 1);}

Register Use(s) Type

%rdi x >> 1 Recursivearg

%rbx x & 1 Callee-saved ←%rsp

...

rtn <main+?>

Saved%rbx

Spring 2016Procedures & The Stack

rtn <pcount_r+22>

...

RecursiveFunction:Call pcount_r:movl $0, %eaxtestq %rdi, %rdije .L6pushq %rbxmovq %rdi, %rbxandl $1, %ebxshrq %rdicall pcount_raddq %rbx, %raxpopq %rbx

.L6:rep; ret

66

/* Recursive popcount */long pcount_r(unsigned long x) {

if (x == 0)return 0;

elsereturn (x & 1)

+ pcount_r(x >> 1);}

Register Use(s) Type

%rbx x & 1 Callee-saved

%raxRecursive callreturnvalue – ←%rsp

...

rtn <main+?>

Saved%rbx

Spring 2016Procedures & The Stack

RecursiveFunction:Resultpcount_r:

movl $0, %eaxtestq %rdi, %rdije .L6pushq %rbxmovq %rdi, %rbxandl $1, %ebxshrq %rdicall pcount_raddq %rbx, %raxpopq %rbx

.L6:rep; ret

67

/* Recursive popcount */long pcount_r(unsigned long x) {

if (x == 0)return 0;

elsereturn (x & 1)

+ pcount_r(x >> 1);}

Register Use(s) Type

%rbx x & 1 Callee-saved

%rax Returnvalue

...

rtn <main+?>

Saved%rbx ←%rsp

Spring 2016Procedures & The Stack

rtn <main+?>

Saved%rbx

RecursiveFunction:Completionpcount_r:

movl $0, %eaxtestq %rdi, %rdije .L6pushq %rbxmovq %rdi, %rbxandl $1, %ebxshrq %rdicall pcount_raddq %rbx, %raxpopq %rbx

.L6:rep; ret

68

/* Recursive popcount */long pcount_r(unsigned long x) {

if (x == 0)return 0;

elsereturn (x & 1)

+ pcount_r(x >> 1);}

Register Use(s) Type

%rax Returnvalue

...←%rsp

Spring 2016Procedures & The Stack

ObservationsAboutRecursion¢ Workswithoutanyspecialconsideration

§ Stackframesmeanthateachfunctioncallhasprivatestorage§ Savedregisters&localvariables§ Savedreturnpointer

§ Registersavingconventionspreventonefunctioncallfromcorruptinganother’sdata§ Unlessthecodeexplicitlydoesso(e.g.,bufferoverflow- describedinfuturelecture)

§ Stackdisciplinefollowscall/returnpattern§ IfPcallsQ,thenQreturnsbeforeP§ Last-In,First-Out

¢ Alsoworksformutualrecursion§ PcallsQ;QcallsP

69

Spring 2016Procedures & The Stack

x86-64StackFrames¢ Often(ideally),x86-64functionsneednostackframeatall

§ Justareturnaddressispushedontothestackwhenafunctioncallismade

¢ Afunctiondoesneedastackframewhenit:§ Hastoomanylocalvariablestoholdinregisters§ Haslocalvariablesthatarearraysorstructs§ Usestheaddress-ofoperator(&)tocomputetheaddressofalocalvariable§ Callsanotherfunctionthattakesmorethansixarguments§ Needstosavethestateofcaller-saveregistersbeforecallingaprocedure§ Needstosavethestateofcallee-saveregistersbeforemodifyingthem

70

Spring 2016Procedures & The Stack

x86-64ProcedureSummary¢ ImportantPoints

§ Proceduresareacombinationofinstructionsandconventions§ Conventionspreventfunctionsfromdisruptingeachother

§ Stackistherightdatastructureforprocedurecall/return§ IfPcallsQ,thenQreturnsbeforeP

¢ Recursionhandledbynormalcallingconventions§ Callercanstorevaluesinlocalstackframeandin

callee-savedregisters§ Putfunctionargumentsattopofstack§ Resultreturnin%rax

ReturnAddr

SavedRegisters

+Local

Variables

ArgumentBuild

Old%rbp

Arguments7+

CallerFrame

%rbp(Optional)

%rsp

71

Spring 2016Procedures & The Stack

Onemorex86-64example¢ Exampleofpassingmorethan6parametersandpassing

addressesoflocalvariables¢ Thefollowingexample,alongwithabriefre-capofx86-64calling

conventionsisinthisvideo:

5.ProceduresandStacks§ …§ 6.x86-64CallingConventions

https://courses.cs.washington.edu/courses/cse351/videos/05/056.mp4

72

Spring 2016Procedures & The Stack

x86-64Example(1)

73

long int call_proc() {

long x1 = 1;int x2 = 2;short x3 = 3;char x4 = 4;proc(x1, &x1, x2, &x2,

x3, &x3, x4, &x4);return (x1+x2)*(x3-x4);

}

call_proc:subq $32,%rspmovq $1,16(%rsp) # x1movl $2,24(%rsp) # x2movw $3,28(%rsp) # x3movb $4,31(%rsp) # x4• • •

Returnaddresstocallerofcall_proc

Note: Detailsmayvarydependingoncompiler.

←%rsp

Spring 2016Procedures & The Stack

x86-64Example(2)– Allocatelocalvars

74

long int call_proc() {

long x1 = 1;int x2 = 2;short x3 = 3;char x4 = 4;proc(x1, &x1, x2, &x2,

x3, &x3, x4, &x4);return (x1+x2)*(x3-x4);

}

call_proc:subq $32,%rspmovq $1,16(%rsp) # x1movl $2,24(%rsp) # x2movw $3,28(%rsp) # x3movb $4,31(%rsp) # x4• • •

Returnaddresstocallerofcall_proc

←%rsp

x3x4 x2

x1

8

16

24

Spring 2016Procedures & The Stack

x86-64Example(3)– setupparams toproc

75

long int call_proc() {

long x1 = 1;int x2 = 2;short x3 = 3;char x4 = 4;proc(x1, &x1, x2, &x2,

x3, &x3, x4, &x4);return (x1+x2)*(x3-x4);

}

call_proc:• • •leaq 24(%rsp),%rcx # %rcx=&x2leaq 16(%rsp),%rsi # %rsi=&x1leaq 31(%rsp),%rax # %rax=&x4movq %rax,8(%rsp) # arg8=&4movl $4,(%rsp) # arg7=4leaq 28(%rsp),%r9 # %r9=&x3movl $3,%r8d # %r8 = 3movl $2,%edx # %rdx = 2movq $1,%rdi # %rdi = 1call proc• • •

Arg 8

Arg 7

x3x4 x2

x1

Returnaddresstocallerofcall_proc

Argumentspassedin(inorder):rdi,rsi,rdx,rcx,r8,r9

8

16

24

Sameinstructionsasinvideo,justadifferentorder.←%rsp

Spring 2016Procedures & The Stack

x86-64Example(4)– setupparams toproc

76

long int call_proc() {

long x1 = 1;int x2 = 2;short x3 = 3;char x4 = 4;proc(x1, &x1, x2, &x2,

x3, &x3, x4, &x4);return (x1+x2)*(x3-x4);

}

call_proc:• • •leaq 24(%rsp),%rcxleaq 16(%rsp),%rsileaq 31(%rsp),%raxmovq %rax,8(%rsp)movl $4,(%rsp)leaq 28(%rsp),%r9movl $3,%r8dmovl $2,%edxmovq $1,%rdicall proc• • •

Arg 8

Arg 7

x3x4 x2

x1

Returnaddresstocallerofcall_procArgumentspassedin(inorder):rdi,rsi,rdx,rcx,r8,r9

Notesizes

8

16

24

←%rsp

Spring 2016Procedures & The Stack

x86-64Example(5)– callproc

77

long int call_proc() {

long x1 = 1;int x2 = 2;short x3 = 3;char x4 = 4;proc(x1, &x1, x2, &x2,

x3, &x3, x4, &x4);return (x1+x2)*(x3-x4);

}

call_proc:• • •leaq 24(%rsp),%rcxleaq 16(%rsp),%rsileaq 31(%rsp),%raxmovq %rax,8(%rsp)movl $4,(%rsp)leaq 28(%rsp),%r9movl $3,%r8dmovl $2,%edxmovq $1,%rdicall proc• • •

Arg 8

Arg 7

x3x4 x2

x1

Returnaddresstocallerofcall_proc

Returnaddresstolineaftercalltoproc ←%rsp

Spring 2016Procedures & The Stack

x86-64Example(6) – aftercalltoproc

78

long int call_proc() {

long x1 = 1;int x2 = 2;short x3 = 3;char x4 = 4;proc(x1, &x1, x2, &x2,

x3, &x3, x4, &x4);return (x1+x2)*(x3-x4);

}

Arg 8

Arg 7

x3x4 x2

x1

Returnaddresstocallerofcall_proc movs__:moveandsignextend

cltq:signextend%eax into%rax(special-casetosavespace)

8

16

24

call_proc:• • •movswl 28(%rsp),%eax # %eax=x3movsbl 31(%rsp),%edx # %edx=x4subl %edx,%eax # %eax=x3-x4cltqmovslq 24(%rsp),%rdx # %rdx=x2addq 16(%rsp),%rdx #%rdx=x1+x2imulq %rdx,%rax # %rax=rax*rdxaddq $32,%rspret

←%rsp

Spring 2016Procedures & The Stack

x86-64Example(7)– de-allocatelocalvars

79

long int call_proc() {

long x1 = 1;int x2 = 2;short x3 = 3;char x4 = 4;proc(x1, &x1, x2, &x2,

x3, &x3, x4, &x4);return (x1+x2)*(x3-x4);

}

call_proc:• • •movswl 28(%rsp),%eaxmovsbl 31(%rsp),%edxsubl %edx,%eaxcltqmovslq 24(%rsp),%rdxaddq 16(%rsp),%rdximulq %rdx,%raxaddq $32,%rspret

Returnaddresstocallerofcall_proc ←%rsp

Recommended