procedures and the call stack
play

Procedures and the Call Stack Topics Procedures Call stack - PowerPoint PPT Presentation

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,


  1. Procedures and the Call Stack Topics • Procedures • Call stack • Procedure/stack instructions • Calling conventions • Register-saving conventions

  2. 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

  3. 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

  4. Call Chain Example Call Chain yoo(…) { yoo • • who(…) who(); who { • • • • • ru(); ru ru ru(…) } • • • { ru(); • • • • • } • } 4

  5. First Try (broken) yoo: who: jmp who back: done: jmp back stop: What if we want to call a function from multiple places in the code?

  6. First Try (broken) What if we want to call a function from multiple places in the code? who: 1 2 ru: jmp ru back2: 6 3,7 5 jmp ru 4 back2: done: jmp back2 9 8 stop:

  7. 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

  8. Memory Layout Addr Perm Contents Managed by Initialized Stack 2 N -1 RW Procedure context Compiler Run-time Programmer, Dynamic Heap RW Run-time malloc/free, data structures new/GC Global variables/ Compiler/ Statics RW Startup static data structures Assembler/Linker Compiler/ Literals R String literals Startup Assembler/Linker Compiler/ Text X Instructions Startup Assembler/Linker 0

  9. Call Stack Stack “Bottom” Memory region managed with stack discipline higher %rsp holds lowest stack address addresses (address of "top" element) stack grows toward lower addresses Stack Pointer: %rsp Stack “Top” 9

  10. Call Chain Example Example Call Chain yoo(…) { yoo • • who(…) who(); who { • • • amI(); amI amI amI(…) } • { amI(); • amI • if(…){ } amI() } amI • } Procedure amI is recursive (calls itself) 14

  11. Stack yoo yoo(…) { yoo yoo • who %rsp • who(); amI amI • • } amI amI 15

  12. Stack yoo(…) yoo who(…) { yoo yoo { • amI(…) who • • • • { amI(); who(); amI(…) • who • • • amI • amI { if(…){ amI(); amI(…) • • amI() { • • • } if(…){ } amI amI • } amI() • if(…){ } } amI() • amI amI } } • } amI %rsp 19

  13. Stack yoo(…) yoo who(…) { yoo { yoo • who • • amI(); who(); who • amI • amI %rsp amI(); • • } amI amI } amI amI amI 22

  14. Stack yoo(…) yoo who(…) { yoo yoo { • amI(…) who • • { amI(); who(); • who • amI • amI if(){ amI(); • amI() • } } amI amI } • %rsp } amI 23

  15. Stack yoo yoo(…) yoo yoo { who %rsp • • who(); who amI amI • • amI } amI amI 25

  16. Stack frames support procedure calls. Contents Local variables Caller Function arguments (after first 6) Frame Return information Temporary space Frame for current Management procedure Space allocated when procedure is entered %rsp Stack Pointer “Setup” code Space deallocated before return Stack “Top” “Finish” code Why not just give every procedure a permanent chunk of memory to hold its local variables, etc? 26

  17. Code Examples void multstore (long x, long y, long *dest) { long t = mult2(x, y); *dest = t; 0000000000400540 <multstore>: } 400540: push %rbx # Save %rbx 400541: mov %rdx,%rbx # Save dest 400544: callq 400550 <mult2> # mult2(x,y) 400549: mov %rax,(%rbx) # Save at dest 40054c: pop %rbx # Restore %rbx 40054d: retq # Return long mult2(long a, long b){ 0000000000400550 <mult2>: long s = a * b; 400550: mov %rdi,%rax # a return s; 400553: imul %rsi,%rax # a * b } 400557: retq # Return 27

  18. Procedure Control Flow Instructions Procedure call: callq label 1. Push return address on stack 2. Jump to label Return address: Address of instruction after call . Example: 400544: callq 400550 <mult2> 400549: movq %rax,(%rbx) Procedure return: retq 1. Pop return address from stack 2. Jump to address 28

  19. Call Example (step 1) • • 0x130 0000000000400540 <multstore>: • 0x128 • • 0x120 400544: callq 400550 <mult2> 400549: mov %rax,(%rbx) • %rsp 0x120 • %rip 0x400544 0000000000400550 <mult2>: 400550: mov %rdi,%rax • • 400557: retq 29

  20. Call Example (step 2) • • 0x130 0000000000400540 <multstore>: • 0x128 • • 0x120 400544: callq 400550 <mult2> 0x118 0x400549 400549: mov %rax,(%rbx) • %rsp 0x118 • %rip 0x400550 0000000000400550 <mult2>: 400550: mov %rdi,%rax • • 400557: retq 30

  21. Return Example (step 1) • • 0x130 0000000000400540 <multstore>: • 0x128 • • 0x120 400544: callq 400550 <mult2> 0x118 0x400549 400549: mov %rax,(%rbx) • %rsp 0x118 • %rip 0x400557 0000000000400550 <mult2>: 400550: mov %rdi,%rax • • 400557: retq 31

  22. Return Example (step 2) • • 0x130 0000000000400540 <multstore>: • 0x128 • • 0x120 400544: callq 400550 <mult2> 400549: mov %rax,(%rbx) • %rsp 0x120 • %rip 0x400549 0000000000400550 <mult2>: 400550: mov %rdi,%rax • • 400557: retq 32

  23. Procedure Data Flow Remaining arguments passed First 6 arguments passed on stack (in memory) in registers High Addresses Arg 1 %r d i Diane’s • • • Silk %r s i Dress Arg n %r d x Costs $8 9 %r c x • • • %r 8 Arg 8 Arg 6 %r 9 Arg 7 Return value Low Addresses %rax Only allocate stack space when needed

  24. Stack Frame … Caller Frame Extra Arguments to callee Return Address Saved Registers + Callee Local Variables Frame Extra Arguments Stack pointer %rsp for next call 35

  25. Common Stack Frame Caller Return Address Frame Callee Frame Stack pointer %rsp 36

  26. Data Flow Examples void multstore (long x, long y, long *dest) { long t = mult2(x, y); *dest = t; 0000000000400540 <multstore>: } # x in %rdi, y in %rsi, dest in %rdx • • • 400541: movq %rdx,%rbx # Save dest 400544: callq 400550 <mult2> # mult2(x,y) # t in %rax 400549: movq %rax,(%rbx) # Save at dest • • • long mult2(long a, 0000000000400550 <mult2>: long b){ # a in %rdi, b in %rsi long s = a * b; 400550: movq %rdi,%rax # a return s; 400553: imul %rsi,%rax # a * b } # s in %rax 400557: retq # Return 37

  27. Example: increment long increment(long* p, long val) { long x = *p; long y = x + val; *p = y; return x; } increment: Register Use(s) movq (%rdi), %rax Argument p %rdi addq %rax, %rsi movq %rsi, (%rdi) Argument val , y %rsi ret x , Return value %rax 38

  28. Procedure Call Example (initial state) Initial Stack Structure long call_incr() { long v1 = 240; long v2 = increment(&v1, 61); • • • return v1+v2; %rsp } Return addr <main+8> call_incr: subq $16, %rsp %rdi movq $240, 8(%rsp) movl $61, %esi leaq 8(%rsp), %rdi %rsi call increment addq 8(%rsp), %rax addq $16, %rsp %rax ret 39

  29. Procedure Call Example (step 1) Stack Structure long call_incr() { long v1 = 240; • • • long v2 = increment(&v1, 61); return v1+v2; %rsp } Return addr <main+8> Space for v1 à 240 Compiler allocated extra space for alignment à Unused call_incr: subq $16, %rsp Allocate space for local vars %rdi movq $240, 8(%rsp) movl $61, %esi leaq 8(%rsp), %rdi %rsi call increment addq 8(%rsp), %rax addq $16, %rsp %rax ret 40

  30. Procedure Call Example (step 2) Stack Structure long call_incr() { long v1 = 240; • • • long v2 = increment( &v1, 61 ); return v1+v2; %rsp } Return addr <main+8> 240 Unused call_incr: subq $16, %rsp %rdi movq $240, 8(%rsp) &v1 movl $61, %esi Set up args for call leaq 8(%rsp), %rdi to increment %rsi call increment 61 addq 8(%rsp), %rax addq $16, %rsp %rax ret Aside: movl is used because 61 is a small positive value that fits in 32 bits. High order bits of % rsi get set to zero automatically. It takes one less byte to encode a movl than a movq . 41

  31. Procedure Call Example (step 3) Stack Structure long call_incr() { long v1 = 240; long v2 = increment( &v1, 61 ) ; return v1+v2; • • • } %rsp Return addr <main+8> call_incr: subq $16, %rsp 240 movq $240, 8(%rsp) Unused movl $61, %esi Return addr <call_incr+?> leaq 8(%rsp), %rdi call increment %rdi addq 8(%rsp), %rax addq $16, %rsp &v1 ret %rsi increment: 61 movq (%rdi), %rax addq %rax, %rsi %rax movq %rsi, (%rdi) ret 42

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend