Presentation is loading. Please wait.

Presentation is loading. Please wait.

More C Stack Frames / Pointer variables

Similar presentations


Presentation on theme: "More C Stack Frames / Pointer variables"— Presentation transcript:

1 More C Stack Frames / Pointer variables
Local Variables Pass & Return values Frame Ptr linkage (R5) and PC linkage (R7) Pointer Variables: Defining & using Pass by value Pass by reference (pointer)

2 Allocating Space for Variables
x0000 Trap Vectors Global data section All global variables stored here (actually all static variables) R4 points to Global Variables Run-time stack Used for local variables (among other things) R6 points to top of stack R5 points to top frame on stack New frame created for each “block” or scope (goes away when block exited) Accessing a variable: Global: LDR R1, R4, #x Local: LDR R2, R5, #-y Offset = distance from beginning of storage area x0100 Intr Vectors x0200 Op Sys x3000 instructions PC R4 global data Heap R6 run-time stack R5 xFE00 Device Registers xFFFF

3 Local Variable Storage
Local variables are stored in an stack frame. (also known as an activation record) Symbol table “offset” gives the distance from the base of the frame. R5 is the frame pointer – holds address of the base of the current frame. Because stack grows downward, base is the highest address of the frame, and variable offsets are <= 0. seconds minutes hours time rate amount R5

4 Context Frame (Activation Record) Format (Note: you will see that there is some inconsistency as to where the Frame begins) R6 Function stacked stuff …….. Local Variables Caller’s Frame Pointer (R5) Caller’s R7 (contains caller’s caller’s PC) Function Return Value Function Pass Value 1 Function Pass Value n R5 Frame …….. Local Variables “Previous R5”

5 Context Frame (Activation Record) Format (Note: you will see that there is some inconsistency as to where the Frame begins) R6 Function stacked stuff …….. Local Variables Caller’s Frame Pointer (R5) Caller’s R7 (contains caller’s caller’s PC) Function Return Value Function Pass Value 1 Function Pass Value n R5 Caller pushes arguments (last to first). Caller invokes subroutine (JSR). Callee allocates return value, pushes R7 and R5. Callee allocates space for local variables. Callee executes function code. Callee stores result into return value slot. Callee pops local variables, pops R5, pops R7. Callee returns RET (or JMP R7). Caller loads return value and pops arguments. Caller resumes computation… Frame …….. Local Variables “Previous R5”

6 Function Call Implementation (with nested calls)
Caller pushes arguments (last to first). Caller invokes subroutine (JSR). Callee allocates return value, pushes R7 and R5. Callee allocates space for local variables. Callee executes function code. Caller loads return value and pops arguments. Caller resumes computation… Callee stores result into return value slot. Callee pops local variables, pops R5, pops R7. Callee returns RET (or JMP R7).

7 Example #include <stdio.h> int Func1(int x); int Func2(int x);
int main() { int A = 3; int B = 5; int C; C = A + B; C = Func1(C); C = C + 1; return 2; } int Func1(int x) return Func2(x) + 1; int Func2(int x) return Func3(x) + 1; int Func3(int x) return Func4(x) + 1; int Func4(int x) return x + 1;

8 Example – Global Area GLOBAL_DATA_START ; R4 (Global Stk Ptr)
L1_second_prog .FILL lc3_L1_second_prog Func1 .FILL lc3_Func1 ; +1 L6_second_prog .FILL lc3_L6_second_prog ; +2 Func2 .FILL lc3_Func2 ; +3 L7_second_prog .FILL lc3_L7_second_prog ; +4 Func3 .FILL lc3_Func3 ; +5 L8_second_prog .FILL lc3_L8_second_prog ; +6 Func4 .FILL lc3_Func4 ; +7 L9_second_prog .FILL lc3_L9_second_prog ; +8 scanf .FILL lc3_scanf ; +9 printf .FILL lc3_printf ; +10 L5_second_prog .FILL #2 ; +11 L3_second_prog .FILL #5 ; +12 L4_second_prog .FILL #1 ; +13 L2_second_prog .FILL #3 ; +14 .END

9 Stack Snapshots Stk at main: xEFF9 xEFFA xEFFB xEFFC FramePtr (xEFFF)
xEFFD R7 (x300B) xEFFE return value space xEFFF <- StkPtr <- FramePtr (initially) Stk before call Func1: xEFF5 xEFF6 xEFF7 xEFF8 pass value to Func1 (C = 8) xEFF9 B = 5 xEFFA A = 3 xEFFB C = 8 (main local var) <- FramePtr (main) Stk before call Func2: xEFF0 xEFF1 xEFF2 xEFF3 pass value to Func2 (C = 8) xEFF4 (Func1 local var) <- FramePtr (Func1) xEFF5 R5 FramePtr (xEFFB) xEFF6 R7 Saved PC (x3024) xEFF7 return value from Func1 space xEFF9 B = 5 xEFFA A = 3 xEFFB C = 8 (main local var) <- FramePtr (main) xEFFC R5 FramePtr (xEFFF) xEFFD R7 Saved PC (x300B) xEFFE return value from main space

10 Stack Snapshots Stk in Func4: xEFE2 xEFE3 xEFE4
xEFE5 (Func4 local var) <- FramePtr (Func4) xEFE6 R5 FramePtr (xEFEA) xEFE7 R7 Saved PC (x3071) xEFE8 return value from Func4 = 9 xEFE9 pass value to Func4 (C = 8) xEFEA (Func3 local var) <- FramePtr (Func3) xEFEB R5 FramePtr (xEFEF) xEFEC R7 Saved PC (x3059) xEFED return value from Func3 space xEFEE pass value to Func3 (C = 8) xEFEF (Func2 local var) <- FramePtr (Func2) xEFF0 R5 FramePtr (xEFF4) xEFF1 R7 Saved PC (x3041) xEFF2 return value from Func2 space xEFF3 pass value to Func2 (C = 8) xEFF4 (Func1 local var) <- FramePtr (Func1) xEFF5 R5 FramePtr (xEFFB) xEFF6 R7 Saved PC (x3024) xEFF7 return value from Func1 space xEFF8 pass value to Func1 (C = 8) xEFF9 B = 5 xEFFA A = 3 xEFFB C = 8 (main local var) <- FramePtr (main) xEFFC R5 FramePtr (xEFFF) xEFFD R7 Saved PC (x300B) xEFFE return value from main space xEFFF <- StkPtr <- FramePtr (initially)

11 Stack Snapshots Stk in Func4: xEFE2 xEFE3 xEFE4
xEFE5 (Func4 local var) <- FramePtr (Func4) xEFE6 R5 FramePtr (xEFEA) xEFE7 R7 Saved PC (x3071) xEFE8 return value from Func4 xEFE9 pass value to Func4 (C = 8) xEFEA (Func3 local var) <- FramePtr (Func3) xEFEB R5 FramePtr (xEFEF) xEFEC R7 Saved PC (x3059) xEFED return value from Func3 space xEFEE pass value to Func3 (C = 8) xEFEF (Func2 local var) <- FramePtr (Func2) xEFF0 R5 FramePtr (xEFF4) xEFF1 R7 Saved PC (x3041) xEFF2 return value from Func2 space xEFF3 pass value to Func2 (C = 8) xEFF4 (Func1 local var) <- FramePtr (Func1) xEFF5 R5 FramePtr (xEFFB) xEFF6 R7 Saved PC (x3024) xEFF7 return value from Func1 space xEFF8 pass value to Func1 (C = 8) xEFF9 B = 5 xEFFA A = 3 xEFFB C = 8 (main local var) <- FramePtr (main) xEFFC R5 FramePtr (xEFFF) xEFFD R7 Saved PC (x300B) xEFFE return value from main space xEFFF <- StkPtr <- FramePtr Stk after return from Func4: xEFE5 xEFE6 xEFE7 xEFE8 return value from Func4 = 9 (C = 9) xEFE9 pass value to Func4 (C = 8) xEFEA (Func3 local var) <- FramePtr (Func3) xEFEB R5 FramePtr (xEFEF) xEFEC R7 Saved PC (x3059) xEFED return value from Func3 space xEFEE pass value to Func3 (C = 8) xEFEF (Func2 local var) <- FramePtr (Func2) xEFF0 R5 FramePtr (xEFF4) xEFF1 R7 Saved PC (x3041) xEFF2 return value from Func2 space xEFF3 pass value to Func2 (C = 8) xEFF4 (Func1 local var) <- FramePtr (Func1) xEFF5 R5 FramePtr (xEFFB) xEFF6 R7 Saved PC (x3024) xEFF7 return value from Func1 space xEFF8 pass value to Func1 (C = 8) xEFF9 B = 5 xEFFA A = 3 xEFFB C = 8 (main local var) <- FramePtr (main) xEFFC R5 FramePtr (xEFFF) xEFFD R7 Saved PC (x300B) xEFFE return value from main space xEFFF <- StkPtr <- FramePtr

12 Declaring Pointer variables
int *ptr; ptr is a pointer variable that points to an int type variable char *cp; cp is a pointer variable that points to a character type variable double *dp; dp is a pointer variable that points to a double type variable * is referred to as the indirection operator, or dereference operator *ptr returns the value of the variable pointed to by pointer variable ptr & is referred to as the unary or monadic operator &variable returns the address of the variable variable

13 Using Pointer Variables
A pointer is a variable which contains the address in memory of another variable. We can have a pointer to any variable type. The unary or monadic operator & provides the “address of a variable”. The indirection or dereference operator * gives the “contents of an object pointed to by a pointer variable”. To declare a pointer to a variable: int *pointer; int x=1, y=2; /* let x be at x3000 and y at 3001 */ int *ip; /* ip is an int type pointer */ ip=&x; /* ip=x x= y=2 */ y=*ip /* ip=x x= y=1 */ x=ip; /* ip=x x=x y=1 */ *ip=3; /* ip=x x= y=1 */ Note: ip = ip actually increments ip by Why?

14 Example: Parameter Passing by Value
#include <stdio.h> void Swap(int firstVal, int secondVal); int main() { int valueA = 3; int valueB = 4; Swap(valueA, valueB); return valueA; /* returns 3 */ } void Swap(int firstVal, int secondVal) int tempVal; /* Holds firstVal when swapping */ tempVal = firstVal; firstVal = secondVal; secondVal = tempVal; return; ? 3 4 Snapshot before return from subroutine

15 Example: Parameter Passing by Reference
#include <stdio.h> void NewSwap(int *firstVal, int *secondVal); int main() { int valueA = 3; int valueB = 4; NewSwap(&valueA, &valueB); return valueA; /* returns 4 */ } void NewSwap(int *firstVal, int *secondVal) int tempVal; /* Holds firstVal when swapping */ tempVal = *firstVal; *firstVal = *secondVal; *secondVal = tempVal; return; ? Snapshots During the Exchange What happened differently using pass by reference, rather than pass by value ?

16 Scanf( ) function scanf(“%d”, &input);
Recall reading from the keyboard in C: scanf(“%d”, &input); Why do we use &input ?

17 Pointer Example #include <stdio.h>
int IntDivide(int x, int y, int *quoPtr, int *remPtr); int main() { int dividend; /* The number to be divided */ int divisor; /* The number to divide by */ int quotient; /* Integer result of division */ int remainder; /* Integer remainder of division */ int error; /* Did something go wrong? */ printf("Input dividend: "); scanf("%d", &dividend); printf("Input divisor: "); scanf("%d", &divisor); error = IntDivide(dividend,divisor,&quotient,&remainder); if (!error) /* !error indicates no error */ printf("Answer: %d remainder %d\n", quotient, remainder); else printf("IntDivide failed.\n"); } int IntDivide(int x, int y, int *quoPtr, int *remPtr) if (y != 0) *quoPtr = x / y; /* Modify *quoPtr */ *remPtr = x % y; /* Modify *remPtr */ return 0; return -1;

18 Example Third_Compiled_C_Program: #include <stdio.h> int main()
{ int A=3,B,C; scanf("%d",&B); C = A + B; printf("C = %d\n", C); } Stk before call scanf: xEFF0 xEFF1 xEFF2 xEFF3 xEFF4 xEFF5 xEFF6 xEFF7 &scanf stringz xEFF8 &B (for scanf) xEFF9 C xEFFA B xEFFB A <- FramePtr (main) xEFFC FramePtr xEFFD R7 xEFFE return value space xEFFF <- StkPtr <- FramePtr (initially) Stk before call printf: xEFF7 &printf stringz xEFF8 C (for printf)

19 Example C Program with Function Calls
int main () { int a = 23; int b = 14; ... b = Watt(a); /* main calls both */ b = Volta(a,b); } int Watt(int c); int w = 5; w = Volta(w,10); /* Watt calls Volta */ return w; int Volta(int q, int r) int k = 3; int m = 6; /* Volta calls no one */ return k+m;

20 Snapshots of Stack Before, During, and After Function Calls

21 Context Frame or Activation Record Format
Function stacked stuff …….. Local Variables Caller’s Frame Pointer (R5) Caller’s R7(contains ITS caller’s PC) Function Return Value Function Pass Value 1 Function Pass Value n R5

22 Stack Snapshot Can you tell where we are in the program?

23 Activation Records on Stack
Volta’s R5 (Watt’s R5 ) (Main’s R5 ) Now where are we?

24 Calling the Function w = Volta(w, 10); 25 10 q r w dyn link ret addr
ret val a w = Volta(w, 10); ; push second arg AND R0, R0, #0 ADD R0, R0, #10 ADD R6, R6, #-1 STR R0, R6, #0 ; push first argument LDR R0, R5, #0 ADD R6, R6, #-1 STR R0, R6, #0 ; call subroutine JSR Volta new R6 R6 R5 xFD00 Note: Caller needs to know number and type of arguments, doesn't know about local variables.

25 Starting the Callee Function
xFCFB x3100 25 10 m k dyn link ret addr ret val q r w a ; leave space for return value ADD R6, R6, #-1 ; push return address ADD R6, R6, #-1 STR R7, R6, #0 ; push dyn link (caller’s frame ptr) ADD R6, R6, #-1 STR R5, R6, #0 ; set new frame pointer ADD R5, R6, #-1 ; allocate space for locals ADD R6, R6, #-2 new R6 new R5 R6 R5 xFD00

26 Ending the Callee Function
-43 217 xFCFB x3100 25 10 m k dyn link ret addr ret val q r w a R6 return k; ; copy k into return value LDR R0, R5, #0 STR R0, R5, #3 ; pop local variables ADD R6, R5, #1 ; pop dynamic link (into R5) LDR R5, R6, #0 ADD R6, R6, #1 ; pop return addr (into R7) LDR R7, R6, #0 ADD R6, R6, #1 ; return control to caller RET R5 new R6 new R5 xFD00

27 Resuming the Caller Function
217 25 10 ret val q r w dyn link ret addr a w = Volta(w,10); ; load return value (top of stack) LDR R0, R6, #0 ; perform assignment STR R0, R5, #0 ; pop return value ADD R6, R6, #1 ; pop arguments ADD R6, R6, #2 R6 new R6 R5 xFD00

28 Memory Map


Download ppt "More C Stack Frames / Pointer variables"

Similar presentations


Ads by Google