Exploring Machine-Level Programming with x86-64 Procedures and Stack Discipline

cs 105 n.w
1 / 50
Embed
Share

This content delves into the intricacies of machine-level programming, focusing on x86-64 procedures, register-saving conventions, and stack operations. Learn about creating pointers to local variables, passing data in procedures, stack management, pushing and popping stack operations, and controlling procedure flow using the stack.

  • Machine Programming
  • x86-64
  • Procedures
  • Stack Discipline
  • Computer Science

Uploaded on | 1 Views


Download Presentation

Please find below an Image/Link to download the presentation.

The content on the website is provided AS IS for your information and personal use only. It may not be sold, licensed, or shared on other websites without obtaining consent from the author. If you encounter any issues during the download, it is possible that the publisher has removed the file from their server.

You are allowed to download the files provided on this website for personal or commercial use, subject to the condition that they are used lawfully. All files are the property of their respective owners.

The content on the website is provided AS IS for your information and personal use only. It may not be sold, licensed, or shared on other websites without obtaining consent from the author.

E N D

Presentation Transcript


  1. CS 105 Tour of the Black Holes of Computing Machine-Level Programming III: Procedures Topics x86-64 stack discipline Register-saving conventions Creating pointers to local variables

  2. Mechanisms in Procedures P( ) { y = Q(x); print(y) } Passing control To beginning of procedure code Back to calling point Passing data Procedure arguments Return value Memory management Allocate during procedure execution Deallocate upon return Mechanisms all implemented with machine instructions x86-64 procedures use only what s needed int Q(int i) { int t = 3*i; int v[10]; return v[t]; } CS 105 2

  3. x86-64 Stack Stack Bottom Region of memory managed with stack discipline Grows toward lower addresses Register %rsp indicates numerically lowest stack address Always holds address of top element Increasing Addresses Stack Grows Down Stack Pointer %rsp Stack Top CS 105 3

  4. x86-64 Stack Pushing Stack Bottom Pushing: pushqSrc Fetch operand at Src Decrement %rsp by 8 Then write operand at address given by %rsp Increasing Addresses Stack Grows Down Stack Pointer %rsp -8 New Stack Top CS 105 4

  5. x86-64 Stack Popping Stack Bottom Popping: popqDest Read memory data at address given by %rsp Increment %rsp by 8 Write to Dest Increasing Addresses Stack Pointer %rsp Stack Grows Down +8 New Stack Top CS 105 5

  6. Stack Operation Examples pushq %rax popq %rdx 0x118 0x118 0x118 0x110 0x110 0x110 0x108 123 0x108 123 0x108 123 0x100 213 0x100 213 %rax 213 %rax 213 %rax 213 %rdx 555 %rdx 555 %rdx 555 213 %rsp 0x108 %rsp 0x108 0x100 %rsp 0x100 0x108 CS 105 6

  7. Procedure Control Flow Use stack to support procedure call and return Procedure call: callorcallq call label Push return address on stack; jump to label Return address value Address of instruction just beyondcall Procedure return: retorretq (or rep; ret) Pop address from stack Jump to address CS 105 7

  8. Control-Flow Example #1 0x130 0000000000400540 <multstore>: 400544: callq 400550 <mult2> 400549: mov %rax,(%rbx) 0x128 0x120 %rsp 0x120 %rip 0x400544 0000000000400550 <mult2>: 400550: mov %rdi,%rax 400557: retq CS 105 8

  9. Control-Flow Example #2 0x130 0000000000400540 <multstore>: 400544: callq 400550 <mult2> 400549: mov %rax,(%rbx) 0x128 0x120 0x118 0x400549 %rsp 0x118 %rip 0x400550 0000000000400550 <mult2>: 400550: mov %rdi,%rax 400557: retq CS 105 9

  10. Control-Flow Example #3 0x130 0000000000400540 <multstore>: 400544: callq 400550 <mult2> 400549: mov %rax,(%rbx) 0x128 0x120 0x118 0x400549 %rsp 0x118 %rip 0x400557 0000000000400550 <mult2>: 400550: mov %rdi,%rax 400557: retq CS 105 10

  11. Control-Flow Example #4 0x130 0000000000400540 <multstore>: 400544: callq 400550 <mult2> 400549: mov %rax,(%rbx) 0x128 0x120 %rsp 0x120 %rip 0x400549 0000000000400550 <mult2>: 400550: mov %rdi,%rax 400557: retq CS 105 11

  12. Carnegie Mellon Procedure Data Flow Registers First 6 arguments Stack %rdi %rsi %rdx Arg n %rcx %r8 %r9 Arg 8 Arg 7 Only allocate stack space when needed Return value %rax CS 105 12

  13. Carnegie Mellon Diane s Silk Dress Cost $89 Registers %rdi %rsi %rdx %rcx %r8 %r9 CS 105 13

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

  15. Stack-Based Languages Languages That Support Recursion E.g., C, Pascal, Java, Python, Racket, Haskell, Code must be reentrant Multiple simultaneous instantiations of single procedure Need some place to store state of each instantiation Arguments Local variables Return pointer Stack Discipline State for given procedure needed for limited time From when called to when return Callee returns before caller does Stack Allocated in Frames State for single procedure instantiation CS 105 15

  16. Call Chain Example Call Chain Code Structure yoo( ) { who(); } yoo who who( ) { amI(); amI(); } amI amI amI amI( ) { amI amI(); Procedure amI is recursive } CS 105 16

  17. Carnegie Mellon Stack Frames Contents Return information Local storage (if needed) Temporary space (if needed) Previous Frame Management Space allocated when procedure entered Set-up code Frame includes push done by call instruction Deallocated upon return Finish code Includes pop done by ret instruction Frame Pointer: %rbp (Optional) x Frame for proc Stack Pointer: %rsp Stack Top CS 105 17

  18. Carnegie Mellon Example Stack yoo yoo( ) { who(); } %rbp yoo yoo who %rsp amI amI amI amI CS 105 18

  19. Carnegie Mellon Example Stack yoo yoo( ) { who(); } } who( ) { amI(); amI(); yoo yoo who %rbp who amI amI %rsp amI amI CS 105 19

  20. Carnegie Mellon Example Stack yoo yoo( ) { who(); } } } who( ) { amI(); amI(); amI(); yoo yoo amI( ) { who who amI amI %rbp amI amI %rsp amI CS 105 20

  21. Carnegie Mellon Example Stack yoo yoo( ) { who(); } } } who( ) { amI(); amI(); amI(); yoo yoo amI( ) { who amI( ) { amI(); } who amI amI amI amI %rbp amI amI %rsp CS 105 21

  22. Carnegie Mellon Example Stack yoo yoo( ) { who(); } } } who( ) { amI(); amI(); amI(); yoo yoo amI( ) { who amI( ) { amI(); } } who amI amI amI( ) { amI(); amI amI amI amI %rbp amI %rsp CS 105 22

  23. Carnegie Mellon Example Stack yoo yoo( ) { who(); } } } who( ) { amI(); amI(); amI(); yoo yoo amI( ) { who amI( ) { amI(); } who amI amI amI amI %rbp amI amI %rsp CS 105 23

  24. Carnegie Mellon Example Stack yoo yoo( ) { who(); } } } who( ) { amI(); amI(); amI(); yoo yoo amI( ) { who who amI amI %rbp amI amI %rsp amI CS 105 24

  25. Carnegie Mellon Example Stack yoo yoo( ) { who(); } } who( ) { amI(); amI(); yoo yoo who %rbp who amI amI %rsp amI amI CS 105 25

  26. Carnegie Mellon Example Stack yoo yoo( ) { who(); } } } who( ) { amI(); amI(); amI(); yoo yoo amI( ) { who who amI amI %rbp amI amI %rsp amI CS 105 26

  27. Carnegie Mellon Example Stack yoo yoo( ) { who(); } } who( ) { amI(); amI(); yoo yoo who %rbp who amI amI %rsp amI amI CS 105 27

  28. Carnegie Mellon Example Stack yoo %rbp yoo( ) { who(); } yoo yoo who %rsp amI amI amI amI CS 105 28

  29. Carnegie Mellon x86-64/Linux Stack Frame Current Stack Frame ( Top to Bottom) Argument build: Parameters for function about to be called Local variables(if can t keep in registers) Saved register context Old frame pointer (optional) Caller Frame Arguments 7+ Return Addr Old %rbp Frame pointer %rbp (Optional) Saved Registers + Local Variables Caller Stack Frame Return address Pushed by call instruction Arguments for this call Argument Build (Optional) Stack pointer %rsp CS 105 29

  30. Carnegie Mellon Example: incr long incr(long *p, long val) { long x = *p; long y = x + val; *p = y; return x; } incr: movq (%rdi), %rax addq %rax, %rsi movq %rsi, (%rdi) ret Register %rdi Use(s) Argument p %rsi Argument val, y %rax x, Return value CS 105 30

  31. Carnegie Mellon Example: Calling incr #1 Initial Stack Structure long call_incr() { long v1 = 15213; long v2 = incr(&v1, 3000); return v1 + v2; } . . . Rtn address %rsp call_incr: subq $16, %rsp movq $15213, 8(%rsp) movl $3000, %esi leaq 8(%rsp), %rdi call incr addq 8(%rsp), %rax addq $16, %rsp ret Resulting Stack Structure . . . Rtn address %rsp+8 15213 %rsp Unused CS 105 31

  32. Carnegie Mellon Example: Calling incr #2 Stack Structure long call_incr() { long v1 = 15213; long v2 = incr(&v1, 3000); return v1 + v2; } . . . Rtn address %rsp+8 15213 %rsp Unused call_incr: subq $16, %rsp movq $15213, 8(%rsp) movl $3000, %esi leaq 8(%rsp), %rdi call incr addq 8(%rsp), %rax addq $16, %rsp ret Register %rdi Use(s) &v1 %rsi 3000 CS 105 32

  33. Carnegie Mellon Example: Calling incr #3 Stack Structure long call_incr() { long v1 = 15213; long v2 = incr(&v1, 3000); return v1 + v2; } . . . Rtn address %rsp+8 18213 %rsp Unused call_incr: subq $16, %rsp movq $15213, 8(%rsp) movl $3000, %esi leaq 8(%rsp), %rdi call incr addq 8(%rsp), %rax addq $16, %rsp ret Register %rdi Use(s) &v1 %rsi 3000 CS 105 33

  34. Carnegie Mellon Example: Calling incr #4 Stack Structure long call_incr() { long v1 = 15213; long v2 = incr(&v1, 3000); return v1 + v2; } . . . Rtn address %rsp+8 18213 %rsp Unused call_incr: subq $16, %rsp movq $15213, 8(%rsp) movl $3000, %esi leaq 8(%rsp), %rdi call incr addq 8(%rsp), %rax addq $16, %rsp ret Register %rax Use(s) Return value Updated Stack Structure . . . %rsp Rtn address CS 105 34

  35. Carnegie Mellon Example: Calling incr #5 Updated Stack Structure long call_incr() { long v1 = 15213; long v2 = incr(&v1, 3000); return v1 + v2; } . . . %rsp Rtn address Register %rax Use(s) call_incr: subq $16, %rsp movq $15213, 8(%rsp) movl $3000, %esi leaq 8(%rsp), %rdi call incr addq 8(%rsp), %rax addq $16, %rsp ret Return value Final Stack Structure . . . %rsp CS 105 35

  36. Carnegie Mellon Register Saving Conventions When procedure yoo calls who: yoo is the caller caller who is the callee callee Can register x be used for temporary storage? yoo: movq $15213, %rdx call who addq %rdx, %rax ret who: ret subq $18213, %rdx Contents of register %rdx overwritten by who This could be trouble Need some coordination something should be done! CS 105 36

  37. Carnegie Mellon Register Saving Conventions When procedure yoo calls who: yoo is the caller caller who is the callee callee Can register x be used for temporary storage? Conventions Caller Saved Caller saves temporary values in its frame before the call Caller Saved Callee Callee Saved Callee saves temporary values in its frame before using Callee restores them before returning to caller Saved CS 105 37

  38. Carnegie Mellon x86-64 Linux Register Usage #1 %rax Return value Caller-saved Can be modified by procedure %rdi, ..., %r9 Arguments (Diane s silk dress) Caller-saved Can be modified by procedure %r10, %r11 Caller-saved Can be modified by procedure %rax %rdi %rsi Return value %rdx %rcx %r8 %r9 %r10 %r11 Arguments Caller-saved temporaries CS 105 38

  39. Carnegie Mellon x86-64 Linux Register Usage #2 %rbx, %r12, %r13, %r14 Callee-saved Callee must save & restore %rbx %r12 %r13 %r14 Callee-saved Temporaries %rbp Callee-saved Callee must save & restore May be used as frame pointer or as scratch Can mix & match %rbp Special %rsp %rsp Special form of callee save Restored to original value upon exit from procedure CS 105 39

  40. Carnegie Mellon Callee-Saved Example #1 Initial Stack Structure long call_incr2(long x) { long v1 = 15213; long v2 = incr(&v1, 3000); return x + v2; } . . . Rtn address %rsp call_incr2: pushq %rbx subq $16, %rsp movq %rdi, %rbx movq $15213, 8(%rsp) movl $3000, %esi leaq 8(%rsp), %rdi call incr addq %rbx, %rax addq $16, %rsp popq %rbx ret Resulting Stack Structure . . . Rtn address Saved %rbx %rsp+8 15213 %rsp Unused CS 105 40

  41. Carnegie Mellon Callee-Saved Example #2 Resulting Stack Structure long call_incr2(long x) { long v1 = 15213; long v2 = incr(&v1, 3000); return x + v2; } . . . Rtn address Saved %rbx call_incr2: pushq %rbx subq $16, %rsp movq %rdi, %rbx movq $15213, 8(%rsp) movl $3000, %esi leaq 8(%rsp), %rdi call incr addq %rbx, %rax addq $16, %rsp popq %rbx ret %rsp+8 15213 %rsp Unused Pre-return Stack Structure . . . Rtn address %rsp CS 105 41

  42. Carnegie Mellon Recursive Function /* Recursive popcount */ long pcount_r(unsigned long x) { if (x == 0) return 0; else return (x & 1) + pcount_r(x >> 1); } pcount_r: movl $0, %eax testq %rdi, %rdi je .L6 pushq %rbx movq %rdi, %rbx andl $1, %ebx shrq %rdi call pcount_r addq %rbx, %rax popq %rbx .L6: rep; ret CS 105 42

  43. Carnegie Mellon Recursive Function Terminal Case /* Recursive popcount */ long pcount_r(unsigned long x) { if (x == 0) return 0; else return (x & 1) + pcount_r(x >> 1); } pcount_r: movl $0, %eax testq %rdi, %rdi je .L6 pushq %rbx movq %rdi, %rbx andl $1, %ebx shrq %rdi call pcount_r addq %rbx, %rax popq %rbx .L6: rep; ret Register %rdi Use(s) x Type Argument Return value Return value %rax CS 105 43

  44. Carnegie Mellon Recursive Function Register Save /* Recursive popcount */ long pcount_r(unsigned long x) { if (x == 0) return 0; else return (x & 1) + pcount_r(x >> 1); } pcount_r: movl $0, %eax testq %rdi, %rdi je .L6 pushq %rbx movq %rdi, %rbx andl $1, %ebx shrq %rdi call pcount_r addq %rbx, %rax popq %rbx .L6: rep; ret Register %rdi Use(s) x Type Argument . . . Rtn address %rsp Saved %rbx CS 105 44

  45. Carnegie Mellon Recursive Function Call Setup /* Recursive popcount */ long pcount_r(unsigned long x) { if (x == 0) return 0; else return (x & 1) + pcount_r(x >> 1); } pcount_r: movl $0, %eax testq %rdi, %rdi je .L6 pushq %rbx movq %rdi, %rbx andl $1, %ebx shrq %rdi call pcount_r addq %rbx, %rax popq %rbx .L6: rep; ret Register %rdi Use(s) x >> 1 Type Rec. argument Callee-saved %rbx x & 1 CS 105 45

  46. Carnegie Mellon Recursive Function Call /* Recursive popcount */ long pcount_r(unsigned long x) { if (x == 0) return 0; else return (x & 1) + pcount_r(x >> 1); } pcount_r: movl $0, %eax testq %rdi, %rdi je .L6 pushq %rbx movq %rdi, %rbx andl $1, %ebx shrq %rdi call pcount_r addq %rbx, %rax popq %rbx .L6: rep; ret Register %rbx Use(s) x & 1 Recursive call return value Type Callee-saved %rax CS 105 46

  47. Carnegie Mellon Recursive Function Result /* Recursive popcount */ long pcount_r(unsigned long x) { if (x == 0) return 0; else return (x & 1) + pcount_r(x >> 1); } pcount_r: movl $0, %eax testq %rdi, %rdi je .L6 pushq %rbx movq %rdi, %rbx andl $1, %ebx shrq %rdi call pcount_r addq %rbx, %rax popq %rbx .L6: rep; ret Register %rbx Use(s) x & 1 Return value Type Callee-saved %rax CS 105 47

  48. Carnegie Mellon Recursive Function Completion /* Recursive popcount */ long pcount_r(unsigned long x) { if (x == 0) return 0; else return (x & 1) + pcount_r(x >> 1); } pcount_r: movl $0, %eax testq %rdi, %rdi je .L6 pushq %rbx movq %rdi, %rbx andl $1, %ebx shrq %rdi call pcount_r addq %rbx, %rax popq %rbx .L6: rep; ret Register %rax Use(s) Return value Type Return value . . . %rsp CS 105 48

  49. Carnegie Mellon Observations About Recursion Handled Without Special Consideration Stack frames mean that each function call has private storage Saved registers & local variables Saved return pointer Register saving conventions prevent one function call from corrupting another s data Unless the C code explicitly does so (e.g., buffer overflow in future lecture) Stack discipline follows call / return pattern If P calls Q, then Q returns before P Last-In, First-Out Also works for mutual recursion P calls Q; Q calls P CS 105 49

  50. Carnegie Mellon x86-64 Procedure Summary Important Points Stack is the right data structure for procedure call & return If P calls Q, then Q returns before P Caller Frame Arguments 7+ Recursion (& mutual recursion) handled by normal calling conventions Can safely store values in local stack frame and in callee- saved registers Put function arguments at top of stack Result return in %rax Return Addr Old %rbp %rbp (Optional) Saved Registers + Local Variables Pointers are addresses of values On stack or global Argument Build %rsp CS 105 50

Related


More Related Content