review stack frame
play

Review: Stack Frame CS451 16 Spring Process memory layout Stack is - PowerPoint PPT Presentation

Review: Stack Frame CS451 16 Spring Process memory layout Stack is used to store data associated stack with function calls Data stores static data where values can change. data segment On top of it, dynamic data is allocated with malloc()


  1. Review: Stack Frame CS451 ’16 Spring

  2. Process memory layout Stack is used to store data associated stack with function calls Data stores static data where values can change. data segment On top of it, dynamic data is allocated with malloc() text segment Text is for machine language of the user program

  3. Call stack int main (int argc, char **argv) { int n1 = f(3, -5); stack n1 = g(n1); } main int f (int p1, int p2) { int x; int a[3]; ... x = g(a[2]); return x; } int g (int param) { return param * 2; }

  4. Call stack int main (int argc, char **argv) { int n1 = f(3, -5); stack n1 = g(n1); } main int f (int p1, int p2) { int x; int a[3]; ... x = g(a[2]); return x; } int g (int param) { return param * 2; }

  5. Call stack int main (int argc, char **argv) { int n1 = f(3, -5); stack n1 = g(n1); } main int f (int p1, int p2) { f int x; int a[3]; ... x = g(a[2]); return x; } int g (int param) { return param * 2; }

  6. Call stack int main (int argc, char **argv) { int n1 = f(3, -5); stack n1 = g(n1); } main int f (int p1, int p2) { f int x; int a[3]; ... x = g(a[2]); return x; } int g (int param) { return param * 2; }

  7. Call stack int main (int argc, char **argv) { int n1 = f(3, -5); stack n1 = g(n1); } main int f (int p1, int p2) { f int x; int a[3]; g ... x = g(a[2]); return x; } int g (int param) { return param * 2; }

  8. Call stack int main (int argc, char **argv) { int n1 = f(3, -5); stack n1 = g(n1); } main int f (int p1, int p2) { f int x; int a[3]; g ... x = g(a[2]); return x; } int g (int param) { return param * 2; }

  9. Call stack int main (int argc, char **argv) { int n1 = f(3, -5); stack n1 = g(n1); } main int f (int p1, int p2) { f int x; int a[3]; ... x = g(a[2]); return x; } int g (int param) { return param * 2; }

  10. Call stack int main (int argc, char **argv) { int n1 = f(3, -5); stack n1 = g(n1); } main int f (int p1, int p2) { int x; int a[3]; ... x = g(a[2]); return x; } int g (int param) { return param * 2; }

  11. Call stack – what should we store in a frame? int main (int argc, char **argv) { int a, b; stack n1 = f(3, -5, 1, 4, 6); $sp n1 = g(n1); (stack pointer) } int f (int p1, int p2, int p3, int p4, int p5) { int x = 3; x = g(p1); return x; } int g (int param) { return param * 2; }

  12. Call stack – what should we store in a frame? int main (int argc, char **argv) { int a, b; stack n1 = f(3, -5, 1, 4, 6); $fp n1 = g(n1); (frame pointer) main } $sp (stack pointer) int f (int p1, int p2, int p3, int p4, int p5) { int x = 3; SP: current stack position x = g(p1); FP: previous position return x; (MIPS does not actually maintain $fp) } int g (int param) { return param * 2; }

  13. Call stack – what should we store in a frame? int main (int argc, char **argv) { int a, b; stack n1 = f(3, -5, 1, 4, 6); $fp Return Address n1 = g(n1); (frame pointer) main Local variables (a,b) } $sp (stack pointer) int f (int p1, int p2, int p3, int p4, int p5) { int x = 3; Return Address: after this function call, where should I jump? x = g(p1); * Return value is stored via registers $v0, $v1 return x; } int g (int param) { return param * 2; }

  14. Call stack – what should we store in a frame? int main (int argc, char **argv) { int a, b; stack n1 = f(3, -5, 1, 4, 6); $fp Return Address n1 = g(n1); (frame pointer) Local variables (a,b) main } Parameters (p5) $sp int f (int p1, int p2, int p3, int p4, int p5) { (stack pointer) int x = 3 Up to 4 parameters are passed by registers (a0-3), x = g(p1); but further parameters and struct parameters return x; call by value will be stored in a stack frame. } int g (int param) { return param * 2; }

  15. Call stack – what should we store in a frame? int main (int argc, char **argv) { int a, b; stack n1 = f(3, -5, 1, 4, 6); Return Address n1 = g(n1); Local variables (a,b) main } Parameters (p5) $fp Return Address int f (int p1, int p2, int p3, int p4, int p5) { (frame pointer) f Local variables (x) int x = 3 $sp x = g(p1); (stack pointer) return x; } int g (int param) { return param * 2; }

  16. Call stack – what should we store in a frame? int main (int argc, char **argv) { int a, b; stack n1 = f(3, -5, 1, 4, 6); Return Address n1 = g(n1); Local variables (a,b) main } Parameters (p5) Return Address int f (int p1, int p2, int p3, int p4, int p5) { f Local variables (x) int x = 3 $fp Return Address g x = g(p1); $sp return x; (stack pointer) } int g (int param) { return param * 2; }

  17. MIPS https://courses.cs.washington.edu/courses/cse451/16sp/help/mips.html • RISC instruction set architecture (e.g., ARM) • System/161 uses a dialect of MIPS processor: MIPS-161 • Registers are 32-bit • Some example instructions • add $t0, $t1, $t2 # $t0 = $t1 + $t2 (add as signed integers) • move $t2, $t3 # $t2 = $t3 • lw register, RAM_source # copy word at source to register • sw register, RAM_destination # copy word at register to destination • … • See http://logos.cs.uic.edu/366/notes/mips%20quick%20tutorial.htm

  18. MIPS example int f (int a, int b) { f: add $v0, $a0, $a1 return a+b; jr $ra # jump to return address } int g (int a, int b) { g: addi $sp, $sp, -12 # allocate stack space for 3 words return f(b, a) sw $ra, 8($sp) # store return address } sw $a0, 4($sp) sw $a1, 0($sp) # store local variable (prev. param) # 1 st arg. = b lw $a0, 0($sp) # 2 nd arg. = a lw $a1, 4($sp) jal f # jump to f, stores the next inst. to $ra lw $a0, 4($sp) # restore a lw $a1, 0($sp) # restore b lw $ra, 8($sp) # restore return address addi $sp, $sp, 12 # pop stack frame jr $ra # jump to return address

  19. MIPS more example • Delayed load, delayed branch • Because of CPU pipeline, load and branch instructions are in effect in the one instruction later. • i.e., the next instruction cannot use loaded register immediately • and, the next instruction of branch always is executed regardless of branching lw v0, 4(v1) jr v0 # wants to jump v0, but it’s not actually loaded The simplest solution is to put nop after load/branch lw v0, 4(v1) nop jr v0

  20. MIPS more & more example • MIPS coprocessor • Coprocessor 0 provides an abstraction of the function necessary to support an OS: exception handling, memory management, scheduling, and control of critical resources 1 . • Registers include ones related to TLB, page table, and etc. • Accessed by mfc0 (move from coprocessor 0), mtc0 (move to …) • e.g., mfc $k0, c0_cause # load the exception cause to k0 • k0, k1 registers • designated general purpose registers (not in coprocessor) for kernel-use • user code should not rely on these • You will see these in the later project! 1 http://www.cs.cornell.edu/courses/cs3410/2015sp/MIPS_Vol3.pdf

Recommend


More recommend