Presentation is loading. Please wait.

Presentation is loading. Please wait.

Functions & Activation Records Recursion

Similar presentations


Presentation on theme: "Functions & Activation Records Recursion"— Presentation transcript:

1 Functions & Activation Records Recursion
Chapter 14/17 Functions & Activation Records Recursion

2 Function Smaller, simpler, subcomponent of program
Provides abstraction hide low-level details give high-level structure to program, easier to understand overall program flow enables separable, independent development C functions zero or multiple arguments passed in single result returned (optional) return value is always the same type by convention, only one function named main (this defines the initial PC) In other languages, called procedures, subroutines, ...

3 Functions in C A function consists of a
Declaration (a.k.a prototype) includes return value, function name, and the order and data type of all arguments – names of argument are optional) Calls Definition Names of variables do not need to match prototype, but must match order/type Defines functionality (source code) and returns control (and a value) to caller May produce side-effects Declaration int Factorial (int n); Call a = x + Factorial (f + g); int Factorial(int n){ int i; int result = 1; for (i = 1; i <= n; i++) result *= i; return result; }

4 Why Declaration? Since function definition also includes return and argument types, why is declaration needed? Use might be seen before definition. Compiler needs to know return and arg types and number of arguments. Definition might be in a different file, written by a different programmer. include a "header" file with function declarations only compile separately, link together to make executable What if we need to pass more parameters than we have registers?!? All the compiler needs to know (1) what symbol to call the function (its name), (2) the type of the return value (for proper usage/intermediate storage) (3) how to set up the stack to call the function (arguments) This allows the compiler to inserted the necessary code for function activation when it is called

5 Implementing a Function Call: Overview
Making a function call involves three basic steps The parameters of the call are passed from the caller to the callee The callee does its task A return value is returned to the caller Functions in C are caller-independent Every function must be callable from any other function Activation record information about each function, including arguments and local variables also includes bookkeeping information values that must always be saved by the caller before doing the JSR arguments and bookeeping info pushed on run-time stack by caller callee responsible for other uses of stack (such as local variables) popped of the stack by caller after getting return value R5 (the frame pointer) is the “bottom” of the stack as far as the callee function definition is aware. It should not modify anything existing on the stack before its execution!

6 Implementing a Function Call: Overview
Calling function Called function allocate memory for activation record (push) copy arguments into stack arguments call function allocate space for return value [bookkeeping] (push) store mandatory callee save registers [bookkeeping] (push) allocate local variables (push) execute code put result in return value space deallocate local variables (pop) load callee save registers (pop) return get result from stack (pop) deallocate memory for activation record (pop)

7 Activation Record int funName(int a, int b) { int w, x, y; return y; } R6 y x w dynamic link return address return value a b locals R5 bookkeeping args Name Type Offset Scope a b w x y int 4 5 -1 -2 funName

8 Activation Record Bookkeeping
Return value space for value returned by function allocated even if function does not return a value Return address save pointer to next instruction in calling function convenient location to store R7 to protect it from change in case another function (JSR) is called Dynamic link caller’s frame pointer (basically a caller save of its own frame pointer R5) used to “pop” this activation record from stack In the LC-3 the format for an activation record includes only (and always) these three words pushed in that order!

9 Run-Time Stack Before call During call After call Memory R6 R5 Callee
Caller Memory R6 Callee Before call During call After call R5

10 Example Function Call int Callee (int q, int r) { int k, m; return k; } int Caller (int a) { int w = 25; w = Callee (w,10); return w; } 25 w dyn link ret addr ret val a R6 R5 xFD00

11 The Function Call: Preparation to Jump
int Callee (int q, int r) … int Caller (int a) … … w = Callee(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 JSR CALLEE ; Jump! 25 10 q r w dyn link ret addr ret val a New R6 R6 R5 Note: Caller needs to know number and type of arguments, doesn't know about local variables. xFD00

12 Starting the Callee Function
; push space for return value ADD R6, R6, #-1 ; push return address ADD R6, R6, #-1 STR R7, R6, #0 ; push dyn link (caller’s R5) ADD R6, R6, #-1 STR R5, R6, #0 ; set new frame pointer ADD R5, R6, #-1 ; allocate space for locals ADD R6, R6, #-2 … execute body of function xFCFB x3100 25 10 m k Dyn lnk (R5) ret addr ret value q r w dyn link ret val a new R6 new R5 R6 R5 Note: Callee makes room for bookkeeping variables (standard format) and its local variables (as necessary) xFD00

13 Ending the Callee Function
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 -43 217 xFCFB x3100 25 10 m k dyn link ret addr ret val q r w a R6 R5 new R6 new R5 xFD00

14 Resuming the Caller Function
w = Callee(w,10); ; JSR Callee ; LAST COMMAND ; load return value (top of stack) LDR R0, R6, #0 ; perform assignment of return value STR R0, R5, #0 ; pop return value and arguments ADD R6, R6, #3 Continue caller code 217 25 10 ret val q r w dyn link ret addr a R6 new R6 R5 xFD00

15 Summary of LC-3 Function Call Implementation
Caller pushes arguments (last to first). Caller invokes subroutine (JSR). Callee allocates return value, pushes R7 and R5. Callee allocates space for local variables (first to last). Callee executes function code. Callee stores result into return value slot. Callee pops local vars, pops R5, pops R7. Callee returns (JMP R7). Caller loads return value and pops arguments. Caller resumes computation…

16 Group Problem x0014 x000A z x0001 y x dyn link R6 ret addr ret val R5
main() { int x = 1, y = 10, z = 20; z = foo(x, y); } int foo(int a, int b) { int i, j; i = j + b; return i; x0014 x000A x0001 Assume JSR FOO ends up at address x3C00 z y x dyn link ret addr ret val R6 Show the assembly code for this instruction. R5 xFCFC xFCFD xFCFE xFCFF xFD00

17 What is Recursion? A recursive function is one that solves its task by calling itself on smaller pieces of data. Similar to recurrence function in mathematics. Like iteration -- can be used interchangeably; sometimes recursion results in a simpler solution. Standard example: Fibonacci numbers The n-th Fibonacci number is the sum of the previous two Fibonacci numbers. F(n) = F(n – 1) + F(n – 2) where F(1) = F(0) = 1 int Fibonacci(int n){ if ((n == 0) || (n == 1)) return 1; else return Fibonacci(n-1) + Fibonacci(n-2); }

18 Activation Records Whenever Fibonacci is invoked, a new activation record is pushed onto the stack. main calls Fibonacci(3) Fibonacci(3) calls Fibonacci(2) Fibonacci(2) calls Fibonacci(1) R6 Fib(1) R6 Fib(2) Fib(2) R6 Fib(3) Fib(3) Fib(3) main main main

19 Activation Records (cont.)
Fibonacci(1) returns, Fibonacci(2) calls Fibonacci(0) Fibonacci(2) returns, Fibonacci(3) calls Fibonacci(1) Fibonacci(3) returns R6 Fib(0) R6 Fib(2) Fib(1) Fib(3) Fib(3) R6 main main main

20 Tracing the Function Calls
If we are debugging this program, we might want to trace all the calls of Fibonacci. Note: A trace will also contain the arguments passed into the function. For Fibonacci(3), a trace looks like: Fibonacci(3) Fibonacci(2) Fibonacci(1) Fibonacci(0) Fibonacci(1) What would trace of Fibonacci(4) look like?

21 Fibonacci: LC-3 Code Activation Record temp dynamic link
return address return value n local bookkeeping Compiler generates temporary variable to hold result of first Fibonacci call. arg

22 In Summary: The Stack Since our program usually starts at a low memory address and grows upward, we start the stack at a high memory address and work downward. Purposes Temporary storage of variables Temporary storage of program addresses Communication with subroutines Push variables on stack Jump to subroutine Clean stack Return

23 Parameter passing on the stack
If we use registers to pass our parameters: Limit of 8 parameters to/from any subroutine. We use up registers so they are not available to our program. So, instead we push the parameters onto the stack. Parameters are passed on the stack Return values can be provided in registers (such as R0) or on the stack. Generally, only R6 should be changed by a subroutine. Other registers that are changed should must be callee saved/restored. Subroutines should be transparent Both the subroutine and the main program must know how many parameters are being passed! In C we would use a prototype: int power (int number, int exponent); In assembly, you must take care of this yourself. After you return from a subroutine, you must also clear the stack. Clean up your mess!

24 Characteristics of good subroutines
Generality – can be called with any arguments Passing arguments on the stack does this. Transparency – you have to leave the registers like you found them, except R6. Registers must be callee saved. Readability – well documented. Re-entrant – subroutine can call itself if necessary Store all information relevant to specific execution to non-fixed memory locations The stack! This includes temporary callee storage of register values!

25 Know how to… Push parameters onto the stack
Access parameters on the stack using base + offset addressing mode Draw the stack to keep track of subroutine execution Parameters Return address Clean the stack after a subroutine call

26 String Library Code Implementation of C/C++ function gets
No way to specify limit on number of characters to read Similar problems with other C/C++ functions strcpy,scanf, fscanf, sscanf, when given %s conversion specification cin (as commonly used in C++) /* Get string from stdin */ char *gets(char *dest) { int c = getc(); char *p = dest; while (c != EOF && c != '\n') { *p++ = c; c = getc(); } *p = '\0'; return dest;

27 Vulnerable Buffer Code
/* Echo Line */ void echo() { char buf[4]; /* Way too small! */ gets(buf); puts(buf); } int main() { printf("Type a string:"); echo(); return 0; }

28 Buffer Overflow Executions
unix>./bufdemo Type a string:123 123 unix>./bufdemo Type a string:12345 Segmentation Fault unix>./bufdemo Type a string: Segmentation Fault

29 Malicious Use of Buffer Overflow
Stack after call to gets() void foo(){ bar(); ... } foo stack frame return address A data written by gets() B pad void bar() { char buf[64]; gets(buf); ... } B exploit code bar stack frame Input string contains byte representation of executable code Overwrite return address with address of buffer When bar() executes ret, will jump to exploit code

30 Exploits Based on Buffer Overflows
Buffer overflow bugs allow remote machines to execute arbitrary code on victim machines. Internet worm Early versions of the finger server (fingerd) used gets() to read the argument sent by the client: finger Worm attacked fingerd server by sending phony argument: finger “exploit-code padding new-return-address” exploit code: executed a root shell on the victim machine with a direct TCP connection to the attacker. IM War AOL exploited existing buffer overflow bug in AIM clients exploit code: returned 4-byte signature (the bytes at some location in the AIM client) to server. When Microsoft changed code to match signature, AOL changed signature location.

31 Code Red Worm History When We Set Up CS:APP Web Site
June 18, Microsoft announces buffer overflow vulnerability in IIS Internet server July 19, over 250,000 machines infected by new virus in 9 hours White house must change its IP address. Pentagon shut down public WWW servers for day When We Set Up CS:APP Web Site Received strings of form GET /default.ida?NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN....NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN%u9090%u6858%ucbd3%u7801%u9090%u6858%ucbd3%u7801%u9090%u6858%ucbd3%u7801%u9090%u9090%u8190%u00c3%u0003%u8b00%u531b%u53ff%u0078%u0000%u00=a HTTP/1.0" "-" "-"

32 Code Red Exploit Code Starts 100 threads running Spread self
Generate random IP addresses & send attack string Between 1st & 19th of month Attack Send 98,304 packets; sleep for 4-1/2 hours; repeat Denial of service attack Between 21st & 27th of month Deface server’s home page After waiting 2 hours

33 Avoiding Overflow Vulnerability
/* Echo Line */ void echo() { char buf[4]; /* Way too small! */ fgets(buf, 4, stdin); puts(buf); } Use Library Routines that Limit String Lengths fgets instead of gets strncpy instead of strcpy Don’t use scanf with %s conversion specification Use fgets to read the string

34 Practice problems Why is R5 not callee-saved?
14.2, 14.4, 14.9, 14.10, (good!) The convention in LC-3 assembly is that all registers are callee-saved except for R5 (the frame pointer) R6 (the stack pointer) and R7 (the return link). Why is R5 not callee-saved? Why is R6 not callee-saved? Why is R7 not callee-saved? Is it true that any problem that can be solved recursively can be solved iteratively using a stack data structure? Why or why not?


Download ppt "Functions & Activation Records Recursion"

Similar presentations


Ads by Google