C Stack Frames Pointer variables Stack Local Variables

C Stack Frames / Pointer variables Stack: • Local Variables • Pass & Return values • Frame Ptr linkage (R 5) and PC linkage (R 7) Pointer Variables: • Defining & using • Pass by value • Pass by reference (pointer)

Compiling C

Allocating Space for Variables x 0000 • • • Global data section – All global variables stored here (actually all static variables) – R 4 points to Global Variables x 0100 x 0200 Op Sys instructions – Used for local variables (among other things) – R 6 points to top of stack – R 5 points to top frame on stack – New frame created for each “block” or scope (goes away when block exited) global data PC R 4 Heap Accessing a variable: – Global: LDR R 1, R 4, #x x. FE 00 – Local: x. FFFF Offset = distance from beginning of storage area Intr Vectors x 3000 Run-time stack LDR R 2, R 5, #-y Trap Vectors run-time stack Device Registers R 6 R 5

Example C program #include <stdio. h> int main() { /* Declare local int amount; /* int rate; /* int time; /* int hours; /* int minutes; /* int seconds; /* variables */ The number of bytes to be transferred The average network transfer rate The time, in seconds, for the transfer The number of hours for the transfer The number of mins for the transfer The number of secs for the transfer */ */ */ /* Get input: number of bytes and network transfer rate */ printf("How many bytes of data to be transferred? "); scanf("%d", &amount); printf("What is the transfer rate (in bytes/sec)? "); scanf("%d", &rate); } /* Calculate total time in seconds time = amount / rate; */ /* Convert time into hours, minutes, seconds hours = time / 3600; /* 3600 seconds in an hour minutes = (time % 3600) / 60; /* 60 seconds in a minute seconds = ((time % 3600) % 60); /* remainder is seconds */ */ /* Output results */ printf("Transfer Time : %d h return 0 %d m %d s n", hours, minutes, seconds);

Symbol Table • Like assembler, compiler needs to know information associated with identifiers – in assembler, all identifiers were labels and information is address • Compiler keeps more information - Name (identifier) - Type - Location in memory - Scope Where are local variables stored? Why?

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. – R 5 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, R 5 and variable offsets are <= 0. seconds minutes hours time rate amount

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

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

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

Context Frame or Activation Record Format (Stack PTR) R 6 Function stacked stuff Called Program ……. . (Frame PTR) R 5 Called Program Local Variables Caller’s Frame Pointer (R 5) Caller’s R 7(contains ITS caller’s PC) Function Return Value Called Program Function Pass Value 1 ……. . Calling program Function Pass Value n ……. . Local Variables “PUSHED” on Stack By:

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

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 x 3000 and y at 3001 */ int *ip; /* ip is an int type pointer */ ip=&x; /* ip=x 3000 x= 1 y=2 */ y=*ip /* ip=x 3000 x= 1 y=1 */ x=ip; /* ip=x 3000 x=x 3000 y=1 */ *ip=3; /* ip=x 3000 x=3 y=1 */ Note: ip = ip + 1 actually increments ip by 4. Why?

Example Define local variables: int object; int *ptr; Now, let’s assign values to them: object = 4; ptr = &object *ptr = *ptr + 1; The last statement above is equivalent to: object = object + 1 What are the final values of object and ptr ?

Example: Parameter Passing by Value #include <stdio. h> void Swap(int first. Val, int second. Val); int main() { int value. A = 3; int value. B = 4; } Swap(value. A, value. B); return 0; void Swap(int first. Val, int second. Val) { int temp. Val; /* Holds first. Val when swapping */ } temp. Val = first. Val; first. Val = second. Val; second. Val = temp. Val; return; Snapshot before return from subroutine

Example: Parameter Passing by Reference #include <stdio. h> void New. Swap(int *first. Val, int *second. Val); int main() { int value. A = 3; int value. B = 4; } New. Swap(&value. A, &value. B); return 0; void New. Swap(int *first. Val, int *second. Val) { int temp. Val; /* Holds first. Val when swapping */ } temp. Val = *first. Val; *first. Val = *second. Val; *second. Val = temp. Val; return; Snapshots During the Exchange What happened differently using pass by reference, rather than pass by value ?

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

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