
Procedures and the Call Stack Topics • Procedures • Call stack • Procedure/stack instructions • Calling conventions • Register-saving conventions Why Procedures? Why functions? Why methods? int contains_char(char* haystack, char needle) { while (*haystack != '\0') { if (*haystack == needle) return 1; haystack++; } return 0; } Procedural Abstraction Implementing Procedures How does a caller pass arguments to a procedure? How does a caller get a return value from a procedure? Where does a procedure store local variables? How does a procedure know where to return (what code to execute next when done)? How do procedures share limited registers and memory? 3 Call Chain Example yoo(…) Call Chain { • yoo • who(…) who(); { who • • • • • ru(); } ru(…) ru ru • • • { ru(); • • • • • } • } 4 First Try (broken) yoo: who: jmp who back: done: jmp back stop: What if I want to call a function multiple times? First Try (broken) What if I want to call a function multiple times? who: 1 2 ru: jmp ru back2: 6 3,7 5 jmp ru 4 back2: done: jmp back2 9 8 stop: Implementing Procedures How does a caller pass arguments to a procedure? How does a caller get a return value from a procedure? Where does a procedure store local variables? How does a procedure know where to return (what code to execute next when done)? How do procedures share limited registers and memory? All these need separate storage per call! (not just per procedure) 7 Memory Layout Addr Perm Contents Managed by Initialized N 2 -1 Stack RW Procedure context Compiler Run-time Programmer, Dynamic RW malloc/free, Run-time Heap data structures new/GC Global variables/ Compiler/ RW Startup Statics static data structures Assembler/Linker Compiler/ R String literals Startup Literals Assembler/Linker Compiler/ X Instructions Startup Text Assembler/Linker 0 Call Stack We see x86 organization. Stack “Bottom” Details differ across architectures, but big ideas are shared. higher Region of memory addresses Managed with stack discipline %esp holds lowest stack address (address of "top" element) stack grows toward lower addresses Stack Pointer: %esp (not extra-sensory perception) Stack “Top” 9 IA32 Call Stack: Push Stack “Bottom” pushl Src higher addresses stack grows toward lower addresses Stack Pointer: %esp Stack “Top” 10 IA32 Call Stack: Push Stack “Bottom” pushl Src 1. Fetch value from Src 2. Decrement %esp by 4 (why 4?) higher addresses 3. Store value at new address given by %esp stack grows toward lower addresses Stack Pointer: %esp -4 Stack “Top” 11 IA32 Call Stack: Pop Stack “Bottom” popl Dest higher addresses stack grows toward lower addresses Stack Pointer: %esp Stack “Top” 12 IA32 Call Stack: Pop Stack “Bottom” popl Dest 1. Load value from address %esp 2. Write value to Dest higher addresses 3. Increment %esp by 4 stack grows toward lower addresses Stack Pointer: %esp Stack “Top” Those bits are still there; we’re just not using them. 13 Call Chain Example Example yoo(…) Call Chain { • yoo • who(…) who(); { who • • • • • amI(); } amI(…) amI amI • • • { amI(); • amI • • • • } amI(); • amI • } Procedure amI is recursive (calls itself) 14 Stack frames support procedure calls. Contents Caller Frame Local variables Function arguments Base/Frame Pointer: Return information %ebp Temporary space Frame for current procedure Management %esp Stack Pointer Space allocated when procedure is entered “Set-up” code Stack “Top” Space deallocated upon return “Finish” code Why not just give every procedure a permanent chunk of memory to hold its local variables, etc? 15 Example Stack yoo(…) yoo %ebp { • yoo who • %esp who(); • amI amI • } amI amI 16 Example Stack who(…) yoo { • • • yoo who amI(); • • • %ebp amI(); amI amI who • • • %esp } amI amI 17 Example Stack amI(…) yoo { • yoo who • amI(); • amI amI who • } amI %ebp amI %esp amI 18 Example Stack amI(…) yoo { • yoo who • amI(); • amI amI who • } amI amI amI %ebp amI %esp 19 Example Stack amI(…) yoo { • yoo who • amI(); • amI amI who • } amI amI amI amI %ebp amI %esp 20 Example Stack amI(…) yoo { • yoo who • amI(); • amI amI who • } amI amI amI %ebp amI %esp 21 Example Stack amI(…) yoo { • yoo who • amI(); • amI amI who • } amI %ebp amI %esp amI 22 Example Stack who(…) yoo { • • • yoo who amI(); • • • %ebp amI(); amI amI who • • • %esp } amI amI 23 Example Stack amI(…) yoo { • yoo who • • • amI amI who • } amI %ebp amI %esp amI 24 Example Stack who(…) yoo { • • • yoo who amI(); • • • %ebp amI(); amI amI who • • • %esp } amI amI 25 Example Stack yoo(…) yoo %ebp { • yoo who • %esp who(); • amI amI • } amI amI How did we remember where to point %ebp when returning? 26 Procedure Control Flow Instructions Procedure call: call label 1. Push return address on stack 2. Jump to label Return address: Address of instruction after call. Example: 804854e: e8 3d 06 00 00 call 8048b90 <main> 8048553: 50 pushl %eax Procedure return: ret 1. Pop return address from stack 2. Jump to address 27 Procedure Call/Return: 1 804854e: e8 3d 06 00 00 call 8048b90 <main> 8048553: 50 pushl %eax call 8048b90 0x110 0x10c 0x108 123 %esp 0x108 %eip 0x804854e %eip = instruction pointer = program counter 28 Procedure Call/Return: 2 804854e: e8 3d 06 00 00 call 8048b90 <main> 8048553: 50 pushl %eax call 8048b90 0x110 0x110 0x10c 0x10c 0x108 123 0x108 123 0x104 0x8048553 %esp 0x108 %esp 0x1080x104 %eip 0x804854e %eip 0x804854e0x8048553 %eip = instruction pointer = program counter 29 Procedure Call/Return: 3 804854e: e8 3d 06 00 00 call 8048b90 <main> 8048553: 50 pushl %eax call 8048b90 PC-relative address 0x110 0x110 0x10c 0x10c 0x108 123 0x108 123 0x104 0x8048553 %esp 0x108 %esp 0x1080x104 %eip 0x804854e %eip 0x8048553 + 0x000063d 0x8048b90 %eip: program counter 30 Procedure Call/Return: 4 8048591: c3 ret ret 0x110 0x110 0x10c 0x10c 0x108 123 0x108 123 0x104 0x8048553 0x8048553 %esp 0x104 %esp 0x1040x108 %eip 0x8048591 %eip 0x80485910x8048553 %eip: program counter 31 IA32/Linux Stack Frame … Caller Frame Arguments to callee Return Address Caller's base pointer Saved Registers + Callee Local Variables Frame Stack Registers Base/Frame pointer %ebp Stack pointer %esp Arguments for next call 33 Revisiting swap Calling swap from call_swap int zip1 = 02481; call_swap: int zip2 = 98195; • • • pushl $zip2 # Global Var void call_swap() { pushl $zip1 # Global Var swap(&zip1, &zip2); call swap } • • • void swap(int *xp, int *yp) { int t0 = *xp; Resulting • int t1 = *yp; Stack • *xp = t1; • *yp = t0; } &zip2 &zip1 Rtn adr %esp 34 Revisiting swap swap: pushl %ebp movl %esp,%ebp Set pushl %ebx Up void swap(int *xp, int *yp) { movl 12(%ebp),%ecx int t0 = *xp; movl 8(%ebp),%edx int t1 = *yp; movl (%ecx),%eax Body *xp = t1; movl (%edx),%ebx *yp = t0; movl %eax,(%edx) } movl %ebx,(%ecx) movl -4(%ebp),%ebx movl %ebp,%esp Finish popl %ebp ret 35 swap Setup #1 Entering Stack Resulting Stack • • • %ebp • frame • %esp • &zip2 yp call_swap &zip1 xp %ebp Rtn adr Rtn adr %esp Old %ebp swap: pushl %ebp movl %esp,%ebp Set pushl %ebx Up 36 swap Setup #2 Entering Stack Resulting Stack • • • %ebp • frame • %esp • &zip2 yp call_swap &zip1 xp %ebp Rtn adr Rtn adr %esp Old %ebp swap: pushl %ebp movl %esp,%ebp Set pushl %ebx Up 37 swap Setup #3 Entering Stack Resulting Stack • • • %ebp • frame • %esp • &zip2 yp call_swap &zip1 xp %ebp Rtn adr Rtn adr %esp Old %ebp Old %ebx swap: pushl %ebp movl %esp,%ebp Set pushl %ebx Up 38 swap Body Entering Stack Resulting Stack • • • %ebp • frame • %esp Offset relative • to new %ebp &zip2 12 yp call_swap &zip1 8 xp %ebp Rtn adr 4 Rtn adr %esp Old %ebp Old %ebx movl 12(%ebp),%ecx # get yp movl 8(%ebp),%edx # get xp . Body 39 swap Finish #1 Finishing Stack Resulting Stack • • • • frame • • yp yp call_swap xp %ebp xp %ebp Rtn adr %esp Rtn adr %esp Old %ebp Old %ebp Old %ebx Old %ebx movl -4(%ebp),%ebx movl %ebp,%esp Finish popl %ebp ret 40 swap Finish #2 Finishing Stack Resulting Stack • • • • frame • • yp yp call_swap xp %ebp xp %ebp Rtn adr %esp Rtn adr %esp Old %ebp Old %ebp Old %ebx movl -4(%ebp),%ebx movl %ebp,%esp Finish popl %ebp ret 41 swap Finish #3 Finishing Stack Resulting Stack • • • • frame • • yp yp call_swap xp %ebp xp %ebp Rtn adr %esp Rtn adr %esp Old %ebp Old %ebx movl -4(%ebp),%ebx movl %ebp,%esp Finish popl %ebp ret 42 swap Finish #4 Finishing Stack Resulting Stack • • • • frame • • yp yp call_swap xp %ebp xp %ebp Rtn adr %esp %esp Old %ebp Old %ebx movl -4(%ebp),%ebx movl %ebp,%esp Finish popl %ebp ret 43 Disassembled swap 080483a4 <swap>: 80483a4: 55 push %ebp 80483a5: 89 e5 mov %esp,%ebp 80483a7: 53 push %ebx 80483a8: 8b 55 08 mov 0x8(%ebp),%edx 80483ab: 8b 4d 0c mov 0xc(%ebp),%ecx 80483ae: 8b 1a mov (%edx),%ebx 80483b0: 8b 01 mov (%ecx),%eax 80483b2: 89 02 mov %eax,(%edx) 80483b4: 89 19 mov %ebx,(%ecx) 80483b6: 5b pop %ebx mov %ebp,%esp 80483b7: c9 leave pop %ebp 80483b8: c3 ret Calling Code 8048409: e8 96 ff ff ff call 80483a4 <swap> 804840e: 8b 45 f8 mov 0xfffffff8(%ebp),%eax relative address (little endian) 44 swap Finish #4 Finishing Stack Resulting Stack • • • • frame • • yp yp call_swap xp %ebp xp %ebp Rtn adr %esp %esp Old %ebp Old %ebx Observation movl -4(%ebp),%ebx Saved & restored register %ebx movl %ebp,%esp Finish but not %eax, %ecx, or %edx popl %ebp ret 45 Register Saving Conventions When procedure yoo calls who: yoo is the caller who is the callee Will register contents still be there after a procedure call? yoo: who: • • • • • • movl $12345, %edx movl 8(%ebp), %edx call who ? addl $98195, %edx addl %edx, %eax • • • • • • ret ret 47 Register Saving Conventions When procedure yoo calls who: yoo is the caller who is the callee Will register contents still be there after a procedure call? Conventions Caller Save Caller saves temporary values in its frame before calling Callee Save Callee saves temporary values in its frame before using 48 IA32/Linux Register Saving Conventions %eax, %edx, %ecx Caller saves prior to call %eax Caller-Save %edx if needs values after call Tempor ar ies %ecx %eax %ebx also used to return Callee-Save %esi integer value Tempor ar ies %edi %ebx, %esi, %edi %esp Callee saves if will use Special %ebp %esp, %ebp special form of callee save restored to original values before returning 49 A Puzzle C function body: *p = d; Write the C function return x - c; header, types, and order of parameters.
Details
-
File Typepdf
-
Upload Time-
-
Content LanguagesEnglish
-
Upload UserAnonymous/Not logged-in
-
File Pages52 Page
-
File Size-