Lecture_notes/1.3_Functions/3_-_Function_calling_conventions.pdf Calling Conventions passing arguments to functions • Terminology: • Callee has parameters that are passed in to it (also called formal...

1 answer below »
This is a problem set question.


Lecture_notes/1.3_Functions/3_-_Function_calling_conventions.pdf Calling Conventions passing arguments to functions • Terminology: • Callee has parameters that are passed in to it (also called formal parameters) • Caller passes arguments to callee (also called actual parameters) • But this transfer of data between caller and callee can take many forms! int main() { ... p (a, b) ... } int p(int x, int y) { return x * y; } different kinds of parameters • Value parameters (call-by-value) • Reference parameters (call-by-reference) value parameters • “Call-by-value” • Used in C, Java, default in C++ • Passes the value of an argument to the function • Makes a copy of argument when function is called • Advantages? Disadvantages? value parameters int x = 1; void main () { foo(x, x); print(x); } void foo(int y, int z) { y = 2; z = 3; print(x); } • What do the print statements print? • Answer: print(x); //prints 1 print(x); //prints 1 reference parameters • “Call-by-reference” • Optional in Pascal (use “var” keyword) and C++ (use “&”) • Pass the address of the argument to the function • If an argument is an expression, evaluate it, place it in memory and then pass the address of the memory location • Advantages? Disadvantages? reference parameters int x = 1; void main () { foo(x, x); print(x); } void foo(int &y, int &z) { y = 2; z = 3; print(x); print(y); } • What do the print statements print? • Answer: print(x); //prints 3 print(x); //prints 3 print(y); //prints 3! how to pass values • Pass arguments in registers (value, if call by value; address of data if call by reference) • Advantage: fast, no memory operations to retrieve values • Disadvantage: limited space, need to be careful for more complicated data, uses more registers • Pass arguments on the stack (through memory) • Advantage: unlimited space for passing arguments, saves registers for other use • Disadvantage: requires more memory, adds instruction overhead • Architectures with lots of registers (e.g., RISC-V) prefer to pass arguments in registers, but all architectures default to stack if needed • In project, we will pass arguments on the stack to simplify code generation; passing in registers is a good optimization! next: tracking function symbols Lecture_notes/1.3_Functions/4_-_Functions_in_symbol_tables.pdf Symbols for Functions why do functions need to be in symbol tables? • Functions are symbols, so tracking them is important! • Avoid name conflicts (different functions with the same name) • This interacts in a funny way with function overloading • Keep track of the arguments and return information about a function • To make sure that functions are called properly • This also interacts in a funny way with function overloading • Keep track of the names of parameters to a function • To make sure they are accessed correctly during code generation functions are symbols and scopes • Functions also have their own scope! • Local variables in functions are in a different scope than local variables in other functions or global variables • Variable names can be reused • In global scope: need to track memory address of variables • In local scope: need to track stack offset of variables • Remember, local variables are stored on the stack, accessed relative to stack/frame pointers int foo(int x, int y) { int a; int b; ... } Name Type Location x int reg: a1 y int fp: +8 a int fp: -4 b int fp: -8 symbol tables are trees • Scopes are nested within one another • Global scope • Function scope nested within global scope • Local blocks nested within functions (not in uC) • Variables can be accessed if they are in scope: if they exist in the current scope or any scope this scope is nested inside • Store pointers from parent scopes to children scopes (e.g., global scope has a child scope for each function), and from children scope to parent scope int foo( ... ) { ... } int bar( ... ) { ... for ( ... ) { ... } } Global foo bar for-loop looking for symbols • When you access a variable in code, you want to check the current scope for the variable, as well as all parent scopes • Bind the variable to the entry in the “closest” scope • When generating code for that variable, generate address based on entry • Global scope: absolute address • Local scope: address offset from frame pointer int foo( ... ) { ... } int bar( ... ) { ... for ( ... ) { ... } } Global foo bar for-loop dealing with overloading • Some language support function overloading • Multiple functions with the same name, but different numbers/types of arguments • How do we deal with repeated names for functions? • Use name mangling: encode additional information into each function to incorporate information about argument types • Creates a different name for each distinct function void foo(int x, float y) becomes void foo3_int_float(int x, float y) //why put “3” at the end of foo? next: code generation for functions Lecture_notes/1.3_Functions/Calling_a_function.pdf Calling a Function int main() { int x; read(x); return p(x); } int p(int x) { int y; y = x * x; return y; } what happens when a function is called? • Transfer arguments from caller to callee • Can happen through registers or by storing arguments in memory int main() { int x; read(x); return p(x); } int p(int x) { int y; y = x * x; return y; } what happens when a function is called? • Transfer arguments from caller to callee • Can happen through registers or by storing arguments in memory • Save important local data • e.g., register holding return address of this function int main() { int x; read(x); return p(x); } int p(int x) { int y; y = x * x; return y; } what happens when a function is called? • Transfer arguments from caller to callee • Can happen through registers or by storing arguments in memory • Save important local data • e.g., register holding return address of this function • Jump to function int main() { int x; read(x); return p(x); } int p(int x) { int y; y = x * x; return y; } what happens when a function is called? • Transfer arguments from caller to callee • Can happen through registers or by storing arguments in memory • Save important local data • e.g., register holding return address of this function • Jump to function • Allocate space for function locals • Temporaries, local variables, int main() { int x; read(x); return p(x); } int p(int x) { int y; y = x * x; return y; } what happens when a function is called? • Transfer arguments from caller to callee • Can happen through registers or by storing arguments in memory • Save important local data • e.g., register holding return address of this function • Jump to function • Allocate space for function locals • Temporaries, local variables • Execute function int main() { int x; read(x); return p(x); } int p(int x) { int y; y = x * x; return y; } what happens when a function is called? • Transfer arguments from caller to callee • Can happen through registers or by storing arguments in memory • Save important local data • e.g., register holding return address of this function • Jump to function • Allocate space for function locals • Temporaries, local variables • Execute function • Transfer return value from callee to caller int main() { int x; read(x); return p(x); } int p(int x) { int y; y = x * x; return y; } what happens when a function is called? • Transfer arguments from caller to callee • Can happen through registers or by storing arguments in memory • Save important local data • e.g., register holding return address of this function • Jump to function • Allocate space for function locals • Temporaries, local variables • Execute function • Transfer return value from callee to caller • Return control back to caller function stack foo() baz() main() main() { foo(); ... } foo() { bar(); ... baz(); } fp sp call stack function stack main() { foo(); ... } foo() { bar(); ... baz(); } call stack Ad dr es se s go d ow n function stack main() main() { foo(); ... } foo() { bar(); ... baz(); } fp sp call stack Ad dr es se s go d ow n function stack main() main() { foo(); ... } foo() { bar(); ... baz(); } fp sp call stack Ad dr es se s go d ow n foo() function stack main() main() { foo(); ... } foo() { bar(); ... baz(); } fp sp call stack Ad dr es se s go d ow n foo() bar() function stack main() main() { foo(); ... } foo() { bar(); ... baz(); } fp sp call stack Ad dr es se s go d ow n foo() function stack main() main() { foo(); ... } foo() { bar(); ... baz(); } fp sp call stack Ad dr es se s
Answered 5 days AfterOct 25, 2021

Answer To: Lecture_notes/1.3_Functions/3_-_Function_calling_conventions.pdf Calling Conventions passing...

Darshan answered on Oct 30 2021
109 Votes
Q1.1
Yes, doing a poor job of alias analysis make register allocation worse. Let me explain below.
When an assignment to one register name can affect the value of another, such register names alias. Some architecture has general-purpose 16-bit registers that can also be used as eight 8-bit registers. Each 8-bit register is called a low address or a high address. The initial bits of a 16-bit...
SOLUTION.PDF

Answer To This Question Is Available To Download

Related Questions & Answers

More Questions »

Submit New Assignment

Copy and Paste Your Assignment Here