calling conventions
play

Calling Conventions Hakim Weatherspoon CS 3410 Computer Science - PowerPoint PPT Presentation

Calling Conventions Hakim Weatherspoon CS 3410 Computer Science Cornell University [Weatherspoon, Bala, Bracy, McKee and Sirer] Big Picture: Where are we going? compute jump/branch targets A memory register D D alu file B +4 addr


  1. Need a “Call Stack” high mem 2 main: myfn: jal myfn addi sp,sp,-4 after1 after1: sw x1, 0(sp) sp add x1,x2,x3 if ( test ) after2 sp jal myfn after2 after2: sp lw x1, 0(sp) after2 addi sp,sp,4 sp jr x1 low mem Stack used to save and restore contents of x1 30

  2. Stack Growth (Call) Stacks start at a high address in memory Stacks grow down as frames are pushed on • Note: data region starts at a low address and grows up • The growth potential of stacks and data region are not artificially limited 31

  3. An executing program in memory 0xfffffffc top system reserved 0x80000000 0x7ffffffc stack dynamic data (heap) .data static data 0x10000000 code (text) .text 0x00400000 bottom 32 system reserved 0x00000000

  4. An executing program in memory 0xfffffffc top system reserved 0x80000000 0x7ffffffc stack “Data Memory” dynamic data (heap) static data 0x10000000 code (text) “Program Memory” 0x00400000 bottom 33 system reserved 0x00000000

  5. Anatomy of an executing program compute jump/branch targets A memory register D D alu file B x2 ($sp) +4 x1 ($ra) addr Stack, Data, Code PC inst control d in d out M Stored in Memory B memory extend new Forward imm unit Detect pc hazard Stack, Data, Code Instruction Write- Instruction Execute Stored in Memory ctrl ctrl ctrl Memory Decode Back Fetch IF/ID ID/EX EX/MEM MEM/WB 34

  6. An executing program in memory 0xfffffffc top system reserved 0x80000000 0x7ffffffc stack “Data Memory” dynamic data (heap) static data 0x10000000 code (text) “Program Memory” 0x00400000 bottom 35 system reserved 0x00000000

  7. Return Address lives in Stack Frame Stack Manipulated by push/pop operations Context: after 2 nd JAL to myfn (from myfn) PUSH: ADDI sp, sp, -20 // move sp down SW x1, 16(sp) // store retn PC 1 st main stack frame Context: 2 nd myfn is done (x1 == ???) POP : LW x1, 16(sp) // restore retn PC  r31 myfn stack frame ADDI sp, sp, 20 // move sp up x2000 JR x1 // return after2 myfn stack frame x1FD0 r29 x2000 x1FD0 r31 For now: Assume each frame = x20 bytes XXXX after2 (just to make this example concrete) 36

  8. The Stack Stack contains stack frames (aka “activation records”) • 1 stack frame per dynamic function • Exists only for the duration of function • Grows down, “top” of stack is sp, x2 • Example: lw x5, 0(sp) puts word at top of stack into x5 Each stack frame contains: • Local variables, return address (later), register backups (later) main stack frame myfn stack frame int main(…) { system reserved ... myfn stack frame stack myfn(x); $sp  } int myfn(int n) { heap static data ... myfn(); code 37 } system reserved

  9. The Heap • Heap holds dynamically allocated memory • Program must maintain pointers to anything allocated • Example: if x5 holds x • lw x6, 0(x5) gets first word x points to • Data exists from malloc() to free() system reserved stack X void some_function() { Y int *x = malloc(1000); z int *y = malloc(2000); 3000 bytes 2000 bytes free(y); int *z = malloc(3000); heap } static data 1000 bytes code 38 system reserved

  10. Data Segment Data segment contains global variables • Exist for all time, accessible to all routines • Accessed w/global pointer • gp, x3, points to middle of segment • Example: lw x5, 0(gp) gets middle-most word (here, max_players) system reserved int max_players = 4; stack int main(...) { 4 gp  heap ... static data } code 39 system reserved

  11. Globals and Locals Variables Visibility Lifetime Location Function-Local Global Dynamic Where is main ? Where is i ? Where is n ? int n = 100; int main (int argc, char* argv[ ]) { (A)Stack (A)Stack (A)Stack int i, m = n, sum = 0; (B)Heap (B)Heap (B)Heap int* A = malloc(4*m + 4); (C)Global Data (C)Global Data (C)Global Data for (i = 1; i <= m; i++) { (D)Text (D)Text (D)Text sum += i; A[i] = sum; } printf ("Sum 1 to %d is %d\n", n, sum); 40 }

  12. An executing program in memory 0xfffffffc top system reserved 0x80000000 0x7ffffffc stack “Data Memory” dynamic data (heap) static data 0x10000000 code (text) “Program Memory” 0x00400000 bottom 41 system reserved 0x00000000

  13. Globals and Locals Variables Visibility Lifetime Location function Function-Local w/in function stack invocation i, m, sum, A program Global n, str whole program .data execution Anywhere that b/w malloc Dynamic heap *A has a pointer and free int n = 100; int main (int argc, char* argv[ ]) { int i, m = n, sum = 0; int* A = malloc(4*m + 4); for (i = 1; i <= m; i++) { sum += i; A[i] = sum; } printf ("Sum 1 to %d is %d\n", n, sum); 42 }

  14. Takeaway2: Need a Call Stack JAL (Jump And Link) instruction moves a new value into the PC, and simultaneously saves the old value in register x1 (aka ra or return address) Thus, can get back from the subroutine to the instruction immediately following the jump by transferring control back to PC in register x1 Need a Call Stack to return to correct calling procedure. To maintain a stack, need to store an activation record (aka a “stack frame”) in memory. Stacks keep track of the correct return address by storing the contents of x1 in memory (the stack). 43

  15. Calling Convention for Procedure Calls Transfer Control • Caller  Routine • Routine  Caller Pass Arguments to and from the routine • fixed length, variable length, recursively • Get return value back to the caller Manage Registers • Allow each routine to use registers • Prevent routines from clobbering each others’ data 44

  16. Next Goal Need consistent way of passing arguments and getting the result of a subroutine invocation 45

  17. Arguments & Return Values Need consistent way of passing arguments and getting the result of a subroutine invocation Given a procedure signature, need to know where arguments should be placed $a0, $a1 • int min(int a, int b); • int subf(int a, int b, int c, int d, int e, int f, int g, int h, int i); • stack? int isalpha(char c); • int treesort(struct Tree *root); • struct Node *createNode(); $a0 • struct Node mynode(); $a0, $a1 $a0 Too many combinations of char, short, int, void *, struct, etc. • RISC-V treats char, short, int and void * identically 46

  18. Simple Argument Passing (1-8 args) First eight arguments: main() { int x = myfn(6, 7); passed in registers x10-x17 x = x + 2; • aka $a0, $a1, …, $a7 } Returned result: passed back in a register main: • Specifically, x10, aka a0 li x10, 6 • And x11, aka a1 li x11, 7 jal myfn addi x5, x10, 2 Note: This is not the entire story for 1-8 arguments. Please see the Full Story slides. 47

  19. Conventions so far: • args passed in $a0, $a1, …, $a7 • return value (if any) in $a0, $a1 • stack frame at $sp - contains $ra (clobbered on JAL to sub-functions) Q: What about argument lists? 48

  20. Many Arguments (8+ args) main() { myfn(0,1,2,..,7,8,9); sp  First eight arguments: 9 … passed in registers x10-x17 8 } • aka a0, a1, …, a7 space for x17 Subsequent arguments: space for x16 main: space for x15 ”spill” onto the stack li x10, 0 space for x14 li x11, 1 space for x13 … Args passed in child’s space for x12 li x17, 7 stack frame space for x11 li x5, 8 space for x10 sw x5, -8(x2) li x5, 9 sw x5, -4(x2) Note: This is not the entire story for 9+ args. jal myfn Please see the Full Story slides. 49

  21. Many Arguments (8+ args) main() { myfn(0,1,2,..,7,8,9); sp  First eight arguments: 9 … passed in registers x10-x17 8 } • aka a0, a1, …, a7 space for x17 Subsequent arguments: space for x16 main: space for x15 ”spill” onto the stack li a0, 0 space for x14 li a1, 1 space for x13 … Args passed in child’s space for x12 li a7, 7 stack frame space for x11 li t0, 8 space for x10 sw t0, -8(sp) li t0, 9 sw t0, -4(sp) Note: This is not the entire story for 9+ args. jal myfn Please see the Full Story slides. 50

  22. Argument Passing: the Full Story main() { myfn(0,1,2,..,7,8,9); Arguments 1-8: sp  9 … -4($sp) passed in x10-x17 8 } -8($sp) room on stack -12($sp) space for x17 Arguments 9+: space for x16 -16($sp) main: placed on stack -20($sp) space for x15 li a0, 0 space for x14 -24($sp) li a1, 1 Args passed in space for x13 -28($sp) … child’s stack frame space for x12 -32($sp) li a7, 7 space for x11 -36($sp) li t0, 8 space for x10 -40($sp) sw t0, -8(x2) li t0, 9 sw t0, -4(x2) jal myfn 51

  23. Pros of Argument Passing Convention • Consistent way of passing arguments to and from subroutines • Creates single location for all arguments • Caller makes room for a0-a7 on stack • Callee must copy values from a0-a7 to stack  callee may treat all args as an array in memory • Particularly helpful for functions w/ variable length inputs: printf(“Scores: %d %d %d\n”, 1, 2, 3); • Aside: not a bad place to store inputs if callee needs to call a function (your input cannot stay in $a0 if you need to call another function!) 52

  24. iClicker Question Which is a true statement about the arguments to the function void sub(int a, int b, int c, int d, int e, int f, int g, int h, int i); A. Arguments a ‐ i are all passed in registers. B. Arguments a ‐ i are all stored on the stack. C. Only i is stored on the stack, but space is allocated for all 9 arguments. D. Only a-h are stored on the stack, but space is allocated for all 9 arguments. 53

  25. iClicker Question Which is a true statement about the arguments to the function void sub(int a, int b, int c, int d, int e, int f, int g, int h, int i); A. Arguments a ‐ i are all passed in registers. B. Arguments a ‐ i are all stored on the stack. C. Only i is stored on the stack, but space is allocated for all 9 arguments. D. Only a-h are stored on the stack, but space is allocated for all 9 arguments. 54

  26. Frame Layout & the Frame Pointer sp  blue’s stack frame blue’s Ret Addr sp  blue() { pink(0,1,2,3,4,5); } 55

  27. Frame Layout & the Frame Pointer Notice blue’s stack frame • Pink’s arguments are on pink’s stack blue’s Ret Addr sp  • sp changes as functions call other space for a5 fp  functions, complicates accesses space for a4  Convenient to keep pointer to bottom of space for a3 pink’s stack == frame pointer space for a2 stack x8, aka fp (also known as s0) space for a1 frame can be used to restore sp on exit space for a0 pink’s Ret Addr blue() { pink(0,1,2,3,4,5); } sp  pink(int a, int b, int c, int d, int e, int f) { … 56 }

  28. Conventions so far • first eight arg words passed in $a0, $a1, …, $a7 • Space for args in child’s stack frame • return value (if any) in $a0, $a1 • stack frame ($fp/$s0 to $sp) contains: - $ra (clobbered on JAL to sub-functions) - space for 8 arguments to Callees - arguments 9+ to Callees 57

  29. RISCV Register Conventions so far: x0 zero zero x16 x1 ra Return address x17 x2 sp x18 s2 Saved registers Stack pointer x3 x19 x4 x20 t0 x5 x21 Temporary registers t1 x6 x22 x7 t2 x23 Saved register or x24 x8 s0/fp framepointer x25 x9 s1 Saved register x26 Function args or x10 a0 x27 return values x28 t3 Temporary registers x11 a1 x29 x12 a2 Function args x30 x13 a3 x31 58 x14 a4

  30. C & RISCV: the fine print C allows passing whole structs a2, a3 a0, a1 • int dist(struct Point p1, struct Point p2); • Treated as collection of consecutive 32-bit arguments - Registers for first 4 words, stack for rest • Better: int dist(struct Point *p1, struct Point *p2); a0 a1 a0, a1 Where are the arguments to: void sub(int a, int b, int c, int d, int e, int f, int g, int h, int i); stack void isalpha(char c); void treesort(struct Tree *root); Where are the return values from: a0 struct Node *createNode(); a0 struct Node mynode(); a0, a1 Many combinations of char, short, int, void *, struct, etc. • RISCV treats char, short, int and void * identically 59

  31. Globals and Locals Global variables are allocated in the “data” region of the program • Exist for all time, accessible to all routines Local variables are allocated within the stack frame • Exist solely for the duration of the stack frame Dangling pointers are pointers into a destroyed stack frame • C lets you create these, Java does not • int *foo() { int a; return &a; } Return the address of a, But a is stored on stack, so will be removed when call returns and point will be invalid 60

  32. Global and Locals How does a function load global data? • global variables are just above 0x10000000 Convention: global pointer • x3 is gp (pointer into middle of global data section) gp = 0x10000800 • Access most global data using LW at gp +/- offset LW t0, 0x800(gp) LW t1, 0x7FF(gp) 61

  33. Anatomy of an executing program 0xfffffffc top system reserved 0x80000000 0x7ffffffc stack dynamic data (heap) $gp static data 0x10000000 code (text) 0x00400000 bottom 62 system reserved 0x00000000

  34. Frame Pointer It is often cumbersome to keep track of location of data on the stack • The offsets change as new values are pushed onto and popped off of the stack Keep a pointer to the bottom of the top stack frame • Simplifies the task of referring to items on the stack A frame pointer, x8, aka fp/s0 • Value of sp upon procedure entry • Can be used to restore sp on exit 63

  35. Conventions so far • first eight arg words passed in a0-a7 • Space for args in child’s stack frame • return value (if any) in a0, a1 • stack frame (fp/s0 to sp) contains: • ra (clobbered on JALs) • space for 8 arguments • arguments 9+ • global data accessed via gp 64

  36. Calling Convention for Procedure Calls Transfer Control • Caller  Routine • Routine  Caller Pass Arguments to and from the routine • fixed length, variable length, recursively • Get return value back to the caller Manage Registers • Allow each routine to use registers • Prevent routines from clobbering each others’ data 65

  37. Next Goal What convention should we use to share use of registers across procedure calls? 66

  38. Register Management Functions: • Are compiled in isolation • Make use of general purpose registers • Call other functions in the middle of their execution • These functions also use general purpose registers! • No way to coordinate between caller & callee  Need a convention for register management 67

  39. Register Usage Suppose a routine would like to store a value in a register Two options: callee-save and caller-save Callee-save: • Assume that one of the callers is already using that register to hold a value of interest • Save the previous contents of the register on procedure entry, restore just before procedure return • E.g. $ra, $fp/$s0, $s1-$s11, $gp, $tp • Also, $sp Caller-save: • Assume that a caller can clobber any one of the registers • Save the previous contents of the register before proc call • Restore after the call • E.g. $a0-a7, $t0-$t6 RISCV calling convention supports both 68

  40. Caller-saved Registers that the caller cares about: t0… t9 About to call a function? • Need value in a t-register after function returns?  save it to the stack before fn call Suppose:  restore it from the stack after fn returns t0 holds x • Don’t need value?  do nothing t1 holds y t2 holds z Where do we save and restore? Functions void myfn(int a) { • Can freely use these registers int x = 10; • Must assume that their contents int y = max(x, a); are destroyed by other functions int z = some_fn(y); return (z + y); } 69

  41. Callee-saved Registers a function intends to use: s0… s9 About to use an s-register? You MUST : • Save the current value on the stack before using • Restore the old value from the stack before fn returns Suppose: s1 holds x s2 holds y s3 holds z Functions Where do we save and restore? • Must save these registers before void myfn(int a) { using them int x = 10; • May assume that their contents int y = max(x, a); are preserved even across fn calls int z = some_fn(y); return (z + y); } 70

  42. Caller-Saved Registers in Practice Assume the registers are free for main: the taking, use with no overhead … [use x5 & x6] Since subroutines will do the same, … must protect values needed later: addi x2, x2, -8 Save before fn call sw x6, 4(x2) Restore after fn call sw x5, 0(x2) jal myfn Notice: Good registers to use if you lw x6, 4(x2) don’t call too many functions or if lw x5, 0(x2) the values don’t matter later on addi x2, x2, 8 anyway. … [use x5 & x6] 71

  43. Caller-Saved Registers in Practice Assume the registers are free for main: the taking, use with no overhead … [use $t0 & $t1] Since subroutines will do the same, … must protect values needed later: addi $sp, $sp,-8 Save before fn call sw $t1, 4($sp) Restore after fn call sw $t0, 0($sp) jal myfn Notice: Good registers to use if you lw $t1, 4($sp) don’t call too many functions or if lw $t0, 0($sp) the values don’t matter later on addi $sp, $sp, 8 anyway. … [use $t0 & $t1] 72

  44. Callee-Saved Registers in Practice main: addi x2, x2, -16 Assume caller is using the registers sw x1, 12(x2) Save on entry sw x8, 8(x2) Restore on exit sw x18, 4(x2) sw x9, 0(x2) addi x8, x2, 12 Notice: Good registers to use if you make … a lot of function calls and need values [use x9 and x18] that are preserved across all of them. … Also, good if caller is actually using the lw x1, 12(x2) registers, otherwise the save and lw x8, 8(x2)($sp) restores are wasted. But hard to know lw x18, 4(x2) this. lw x9, 0(x2) addi x2, x2, 16 jr x1 73

  45. Callee-Saved Registers in Practice main: addi $sp, $sp, -16 Assume caller is using the registers sw $ra, 12($sp) Save on entry sw $fp, 8($sp) Restore on exit sw $s2, 4($sp) sw $s1, 0($sp) addi $fp, $sp, 12 Notice: Good registers to use if you make … a lot of function calls and need values [use $s1 and $s2] that are preserved across all of them. … Also, good if caller is actually using the lw $ra, 12($sp) registers, otherwise the save and lw $fp, 8($sp)($sp) restores are wasted. But hard to know lw $s2, 4($sp) this. lw $s1, 0($sp) addi $sp, $sp, 16 jr $ra 74

  46. Clicker Question You are a compiler. Do you choose to put a in a: (A) Caller-saved register (t) (B) Callee-saved register (s) (C) Depends on where we put the other variables in this fn (D) Both are equally valid 75

  47. Clicker Question You are a compiler. Do you choose to put a in a: (A) Caller-saved register (t) (B) Callee-saved register (s) (C) Depends on where we put the other variables in this fn (D) Both are equally valid Repeat but assume that foo is recursive (bar/baz  foo) 76

  48. Clicker Question You are a compiler. Do you choose to put b in a: (A) Caller-saved register (t) (B) Callee-saved register (s) (C) Depends on where we put the other variables in this fn (D) Both are equally valid 77

  49. Frame Layout on Stack fp  Assume a function uses two incoming callee-save registers. args How do we allocate a stack frame? saved ra saved fp How large is the stack frame? saved regs What should be stored in the stack ($s1 ... $s11) frame? Where should everything be stored? locals sp  outgoing args 78

  50. Frame Layout on Stack ADDI sp, sp, -16 # allocate frame SW ra, 12(sp) # save ra fp  incoming SW fp, 8(sp) # save old fp args SW s2, 4(sp) # save ... saved ra SW s1, 0(sp) # save ... saved fp ADDI fp, sp, 12 # set new frame ptr … ... saved regs BODY ($s1 ... $s11) … ... LW s1, 0(sp) # restore … locals LW s2, 4(sp) # restore … sp  LW fp, 8(sp) # restore old fp outgoing LW ra, 12(sp) # restore ra args ADDI sp, sp, 16 # dealloc frame JR ra 79

  51. Frame Layout on Stack fp  blue’s ra blue() { blue’s pink(0,1,2,3,4,5); saved fp stack } saved regs frame sp  args for pink 80

  52. Frame Layout on Stack blue’s ra blue() { blue’s pink(0,1,2,3,4,5); saved fp stack } saved regs frame pink(int a, int b, int c, int d, int e, int f) { args for pink fp  int x; pink’s ra orange(10,11,12,13,14); blue’s fp pink’s } stack saved regs frame x sp  args for orange 81

  53. Frame Layout on Stack blue’s ra blue() { blue’s pink(0,1,2,3,4,5); saved fp stack } saved regs frame pink(int a, int b, int c, int d, int e, int f) { args for pink int x; pink’s ra orange(10,11,12,13,14); blue’s fp pink’s } stack saved regs orange(int a, int b, int c, int, d, int e) { frame x char buf[100]; fp  args for orange gets(buf); // no bounds check! orange’s ra } orange pink’s fp stack saved regs frame buf[100] What happens if more than 100 bytes sp  is written to buf? 82

  54. Buffer Overflow blue’s ra blue() { blue’s pink(0,1,2,3,4,5); saved fp stack } saved regs frame pink(int a, int b, int c, int d, int e, int f) { args for pink int x; pink’s ra orange(10,11,12,13,14); blue’s fp pink’s } stack saved regs orange(int a, int b, int c, int, d, int e) { frame x char buf[100]; args for orange fp  gets(buf); // no bounds check! orange’s ra } orange pink’s fp stack saved regs frame buf[100] What happens if more than 100 bytes sp  is written to buf? 83

  55. RISCV Register Recap Return address: x1 (ra) Stack pointer: x2 (sp) Frame pointer: x8 (fp/s0) First four arguments: x10-x17 (a0-a7) Return result: x10-x11 (a0-a1) Callee-save free regs: x9,x18-x27 (s1-s11) Caller-save (temp) free regs: x5-x7, x28-x31 (t0-t6) Global pointer: x3 (gp) 84

  56. Convention Summary • first eight arg words passed in $a0-$a7 • Space for args in child’s stack frame • return value (if any) in $a0, $a1 • stack frame ($fp to $sp) contains: • $ra (clobbered on JALs) $fp  • local variables incoming • space for 8 arguments to Callees args • arguments 9+ to Callees saved ra • callee save regs: preserved saved fp • caller save regs: not preserved saved regs • global data accessed via $gp ($s0 ... $s7) locals $sp  85

  57. Activity #1: Calling Convention Example int test(int a, int b) { int tmp = (a&b)+(a|b); int s = sum(tmp,1,2,3,4,5,6,7,8); int u = sum(s,tmp,b,a,b,a); return u + a + b; } Correct Order: 1. Body First 2. Determine stack frame size 3. Complete Prologue/Epilogue 86

  58. Activity #1: Calling Convention Example test: int test(int a, int b) { LW t0, 0(sp) int tmp = (a&b)+(a|b); Prologue int s =sum(tmp,1,2,3,4,5,6,7,8); MOVE a0, a0 # s int u = sum(s,tmp,b,a,b,a); MOVE s1, a0 MOVE a1, t0 # tmp return u + a + b; } MOVE s2, a1 MOVE a2, s2 # b AND t0, a0, a1 MOVE a3, s1 # a OR t1, a0, a1 MOVE a4, s2 # b ADD t0, t0, t1 MOVE a5, s1 # a MOVE a0, t0 JAL sum LI a1, 1 LI a2, 2 … # add u (a0) and a (s1) LI a7, 7 ADD a0, a0, s1 LI t1, 8 ADD a0, a0, s2 SW t1, -4(sp) # a0 = u + a + b Epilogue SW t0, 0(sp) JAL sum 87

  59. Activity #1: Calling Convention Example test: int test(int a, int b) { LW t0, 0(sp) int tmp = (a&b)+(a|b); Prologue int s =sum(tmp,1,2,3,4,5,6,7,8); MOVE a0, a0 # s int u = sum(s,tmp,b,a,b,a); MOVE s1, a0 MOVE a1, t0 # tmp return u + a + b; } MOVE s2, a1 MOVE a2, s2 # b AND t0, a0, a1 MOVE a3, s1 # a OR t1, a0, a1 MOVE a4, s2 # b How many bytes do we ADD t0, t0, t1 MOVE a5, s1 # a MOVE a0, t0 JAL sum need to allocate for the LI a1, 1 stack frame? LI a2, 2 a) 24 … # add u (v0) and a (s1) LI a7, 7 ADD a0, a0, s1 b) 28 LI t1, 8 ADD a0, a0, s2 c) 36 SW t1, -4(sp) # a0 = u + a + b d) 40 Epilogue SW t0, 0(sp) e) 48 JAL sum 88

  60. Activity #1: Calling Convention Example test: int test(int a, int b) { LW t0, 0(sp) int tmp = (a&b)+(a|b); Prologue int s =sum(tmp,1,2,3,4,5,6,7,8); MOVE a0, v0 # s int u = sum(s,tmp,b,a,b,a); MOVE s1, a0 MOVE a1, t0 # tmp return u + a + b; } MOVE s2, a1 MOVE a2, s2 # b AND t0, a0, a1 MOVE a3, s1 # a space for a1 $fp  OR t1, a0, a1 MOVE a4, s2 # b space for a0 ADD t0, t0, t1 MOVE a5, s1 # a saved ra MOVE a0, t0 JAL sum LI a1, 1 saved fp LI a2, 2 saved regs … # add u (a0) and a (s1) (s1 ... s11) LI a7, 7 ADD a0, a0, s1 LI t1, 8 ADD a0, a0, s2 locals SW t1, -4(sp) # a0 = u + a + b (t0) $sp  Epilogue outgoing args SW t0, 0(sp) space for a0 – a7 JAL sum and 9 th arg 89

  61. Activity #1: Calling Convention Example test: int test(int a, int b) { LW t0, 0(sp) int tmp = (a&b)+(a|b); Prologue int s =sum(tmp,1,2,3,4,5,6,7,8); MOVE a0, a0 # s int u = sum(s,tmp,b,a,b,a); MOVE s1, a0 MOVE a1, t0 # tmp return u + a + b; } MOVE s2, a1 MOVE a2, s2 # b $fp  space incoming for a1 24 AND t0, a0, a1 MOVE a3, s1 # a space incoming for a0 20 OR t1, a0, a1 MOVE a4, s2 # b saved ra 16 ADD t0, t0, t1 MOVE a5, s1 # a saved fp 12 MOVE a0, t0 JAL sum saved reg s2 LI a1, 1 8 LI a2, 2 saved reg s1 4 … # add u (a0) and a (s1) local t0 0 LI a7, 7 ADD a0, a0, s1 $sp  outgoing 9 th arg LI t1, 8 ADD a0, a0, s2 -4 space for a7 SW t1, -4(sp) # a0 = u + a + b -8 space for a6 -12 Epilogue SW t0, 0(sp) … … JAL sum space for a1 -28 space for a0 -36 90

  62. Activity #2: Calling Convention Example: Prologue, Epilogue test: # allocate frame # save $ra $fp  space incoming for a1 24 # save old $fp Space incoming for a0 # callee save ... 20 saved ra # callee save ... 16 # set new frame ptr saved fp 12 • ... saved reg s2 8 • ... # restore … saved reg s1 4 # restore … local t0 0 $sp  # restore old $fp outgoing 9 th arg -4 # restore $ra space for a7 -8 # dealloc frame space for a6 -12 … … space for a1 -28 space for a0 -36 91

  63. Activity #2: Calling Convention Example: Prologue, Epilogue test: Space for t0 # allocate frame Space for a0 and a1 ADDI sp, sp, ‐28 # save $ra SW ra, sp, 16 $fp  space incoming for a1 24 # save old $fp SW fp, sp, 12 Space incoming for a0 # callee save ... 20 SW s2, sp, 8 saved ra # callee save ... 16 SW s1, sp, 4 # set new frame ptr saved fp 12 ADDI fp, sp, 24 ... saved reg s2 8 ... Body # restore … saved reg s1 4 (previous slide, Activity #1) # restore … local t0 0 LW s1, sp, 4 $sp  # restore old $fp outgoing 9 th arg -4 # restore $ra LW s2, sp, 8 space for a7 -8 # dealloc frame LW fp, sp, 12 space for a6 -12 LW ra, sp, 16 … … ADDI sp, sp, 28 space for a1 -28 JR ra space for a0 -36 92

  64. Next Goal Can we optimize the assembly code at all? 93

  65. Minimum stack size for a standard function? 94

  66. Minimum stack size for a standard function? $fp  incoming args saved ra saved fp saved regs ($s1 ... $s11) locals $sp  95

  67. Minimum stack size for a standard function? Leaf function does not invoke any other functions int f(int x, int y) { return (x+y); } $fp  incoming Optimizations? args No saved regs (or locals) saved ra No incoming args saved fp saved regs Don’t push $ra ($s1 ... $s11) No frame at all? Maybe. locals $sp  96

  68. Next Goal Given a running program (a process), how do we know what is going on (what function is executing, what arguments were passed to where, where is the stack and current stack frame, where is the code and data, etc)? 97

  69. Anatomy of an executing program 0xfffffffc top system reserved 0x80000000 0x7ffffffc stack dynamic data (heap) .data static data 0x10000000 PC code (text) 0x00400000 .text bottom 98 system reserved 0x00000000

  70. Activity #4: Debugging init(): 0x400000 printf(s, …): 0x4002B4 CPU: vnorm(a,b): 0x40107C $pc=0x004003C0 main(a,b): 0x4010A0 0x00000000 pi: 0x10000000 $sp=0x7FFFFFAC 0x0040010c str1: 0x10000004 $ra=0x00401090 0x7FFFFFF4 0x00000000 What func is running? 0x00000000 Who called it? 0x00000000 0x00000000 Has it called anything? 0x004010c4 Will it? 0x7FFFFFDC 0x00000000 Args? 0x00000000 Stack depth? 0x00000015 0x10000004 0x7FFFFFB0 Call trace? 0x00401090 99

  71. Activity #4: Debugging …F4 ra Memory …F0 fp init(): 0x400000 EA a3 printf(s, …): 0x4002B4 E8 a2 CPU: vnorm(a,b): 0x40107C E4 a1 $pc=0x004003C0 main(a,b): 0x4010A0 0x00000000 E0 a0 pi: 0x10000000 $sp=0x7FFFFFAC 0x0040010c DC ra str1: 0x10000004 $ra=0x00401090 main 0x7FFFFFF4 fp 0x7 …D8 0x00000000 0x7FFFFFD4 a3 What func is running? printf 0x00000000 0x7FFFFFD0 a2 vnorm Who called it? 0x00000000 0x7FFFFFCA a1 vnorm a0 0x00000000 0x7FFFFFC8 no Has it called anything? 0x004010c4 0x7FFFFFC4 ra b/c no space for no Will it? 0x7FFFFFDC 0x7FFFFFC0 fp outgoing args 0x00000000 0x7FFFFFBC a3 Args? Str1 and 0x15 0x00000000 0x7FFFFFB8 a2 4 Stack depth? 0x00000015 0x7FFFFFB4 a1 printf printf, vnorm, main, init 0x10000004 0x7FFFFFB0 a0 Call trace? 0x00401090 0x7FFFFFAC ra 100 0x7FFFFFA8 0x7FFFFFC4

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