Upload
others
View
6
Download
0
Embed Size (px)
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