Upload
others
View
10
Download
0
Embed Size (px)
Citation preview
February 20, 2017 Sam Siewert
CS 332 Programming Language Concepts
Lecture 7 – Subroutines
Purpose of a Subroutine Control Abstraction – perform a well defined operation – E.g. transform a color image into a graymap – Compute the root of a function by Regula Falsi method – Sort a list records by key numbers
Compared to Data Abstraction – represent a collection of information – E.g. Structure or record in a list, graph or tree abstract data type – Array of intensity data for a color image – Look-up table
Use of Stack for local variables (function scope) and passing of parameters mapping actual to formal arguments Sam Siewert 2
Subroutine Stack Fundamentals Recall Program Use of Memory – Code segment, constants – generally read-only – Data segment, Global memory – global variables, arrays,
structures File or module scope Application global (frowned upon) Lives in Data Segment
– Heap memory – allocation during run time E.g. C malloc or API to Heap Manager E.g. C++ “new” object instantiation
– Stack segment – local variables in a subroutine, parameters Recall scoping rules for local/global variables Pass by value and pass by reference
Sam Siewert 3
Subroutine Stack Visibility Subroutines Can Be Module/file global Or, Nested and Local to Another Subroutine
Sam Siewert 4
Simple C Local Function
Even C Has Simple Locally Visible Functions Modules and Object Orientation Provide More Sophisticated Scoping and Function/Method Visibility Link Error if We Call localfunct() in main()
Sam Siewert 5
#include <stdio.h> #include <string.h> void globalfunct(void) { void localfunct(void) { printf("local function\n"); } printf("global function\n"); localfunct(); } void main(void) { globalfunct(); // not visible here, so can't call, // but global can // localfunct(); }
Recall ASM and Machine Frame/Stack Support – ARM ABI
Stack address (sp, r13) Program Counter (pc, r15) Frame address (fp) Link Register (lr, r14) Intra-Procedure Call (ip, r12)
Sam Siewert 6
.text .align 2 .global gcda .type gcda, %function gcda: mov ip, sp stmfd sp!, {fp, ip, lr, pc} sub fp, ip, #4 sub sp, sp, #8 str r0, [fp, #-16] str r1, [fp, #-20] … END2: sub sp, fp, #12 ldmfd sp, {fp, sp, lr} bx lr Return from function
Argument #1 Argument #2
Copy Stack Ptr Push return info
Pop return info
ARM Prolog and Epilog – EABI http://mercury.pr.erau.edu/~siewerts/cs332/code/cs332_code/lcm/lcmarm.s http://en.wikipedia.org/wiki/Calling_convention#ARM
– r15 is the program counter. – r14 is the link register. (The BL instruction, used in a subroutine call, stores the return
address in this register). – r13 is the stack pointer. – r12 is the Intra-Procedure-call scratch register. – r4 to r11: used to hold local variables. – r0 to r3: used to hold argument values passed to a subroutine, and also hold results returned
from a subroutine.
If the type of value returned is too large to fit in r0 to r3, …, then the caller must allocate space for that value at run time, and pass a pointer in r0. The ARM calling convention mandates using a full-descending stack.
– In the prolog, push r4 to r11 to the stack to save if used, and push the return address in r14, to the stack. (This can be done with a single STM instruction).
– copy any passed arguments (in r0 to r3) to the local scratch registers (r4 to r11) or use – allocate other local variables to the remaining local scratch registers (r4 to r11) if needed – Compute and call other sub-routines using BL instruction (note r0 … r3 and r12, r14 are not
preserved) – Put result in r0 – In the epilog, pull r4 to r11 from the stack to restore if needed, and pull the return address
to the program counter r15. (This can be done with a single LDM instruction).
Sam Siewert 7
Underlying ISA Supports Stack – Parameters to
subroutines (pass by value or reference)
– Local variables – Temporary variables – Scoping
Operating System, PL Runtime, and API Libraries Using Globally Reserved Memory Support Heap – Runtime Allocation – Must Free at
Runtime or Count on Garbage Collection
Sam Siewert 8
PLP – Stack Layout Contents of a stack frame – bookkeeping
return PC (dynamic link) saved registers line number --- FOR DEBUGGING (“ –g”) saved display entries [avoid chaining for non-local variables in nested subroutines]
– Page 383, bottom – Page 387, Maintaining the Static Chain – Page 389 – In More Depth
static link – arguments and returns – local variables – Temporaries
Static Chain – Page 385, Figure 8.1, Examples 8.3 and 8.4 Sam Siewert 9
C Does Not Support Subroutine Nesting PLP, Page 389, In More Depth, Last sentence Subroutine example on p. 385 – subsp385.c We can define functions inside functions, but what are the visibility and scoping rules? – GCC Does Support Nested Functions for C (not C++) -
http://gcc.gnu.org/onlinedocs/gcc/Nested-Functions.html – Visual Studio Does not – try same code in VS2010
1> nesting-simple.cpp 1>c:\users\ssiewert\documents\visual studio 2010\projects\nesting-simple\nesting-simple\nesting-simple.cpp(16): error C2601: 'localfunct_E_in_A' : local function definitions are illegal … 2010\projects\nesting-simple\nesting-simple\nesting-simple.cpp(43): error C3861: 'localfunct_E_in_A': identifier not found 1> 1>Build FAILED.
http://c-faq.com/misc/nestfcns.html http://en.wikipedia.org/wiki/Nested_function – Due to nesting, the scope of the nested function is inside the
enclosing function. – This means that it can access local variables and other local
functions in the enclosing function, while all of this is invisible outside the enclosing function.
Sam Siewert 10
Calling Conventions E.g. MIPS, ARM ABI Maintenance of stack is responsibility of calling sequence and subroutine prolog and epilog – space is saved by putting as much in the prolog and epilog
as possible – time may be saved by putting stuff in the caller instead,
where more information may be known
Common strategy is to divide registers into caller-saves and callee-saves sets – caller uses the "callee-saves" registers first – "caller-saves" registers if necessary
Sam Siewert 11
MIPS Calling Convention (reminder) Caller – saves into the temporaries and locals area any caller-
saves registers whose values will be needed after the call
– puts up to 4 small arguments into registers $4-$7 (a0-a3) it depends on the types of the parameters and the order in which they appear in the argument list
– puts the rest of the arguments into the arg build area at the top of the stack frame
– does jal, which puts return address into register ra and branches
note that jal, like all branches, has a delay slot
Sam Siewert 12
MIPS Convention – From PLP In prolog, Callee
– subtracts framesize from sp – saves callee-saves registers used anywhere inside callee – copies sp to fp
In epilog, Callee
– puts return value into registers (mem if large) – copies fp into sp (see below for rationale) – restores saved registers using sp as base – adds to sp to deallocate frame – does jra
After call, Caller
– moves return value from register to wherever it's needed (if appropriate)
– restores caller-saves registers lazily over time, as their values are needed
All arguments have space in the stack, whether passed in registers or not
Sam Siewert 13
MIPS Convention - PLP Many parts of the calling sequence, prologue, and/or epilogue can be omitted in common cases – particularly LEAF routines (those that don't call
other routines) leaving things out saves time simple leaf routines don't use the stack - don't even use memory – and are exceptionally fast
This is Also True for ARM (x86, ARM, C) – E.g. subsp386_arm_Linux.s
Sam Siewert 14
Exploration Questions Why Does ANSI C not support Nested Functions? Why does GCC support anyway? Why does GCC also not support in C++ too? Does Java Support Nested Functions? C#? Python? Ada? Others? Why are Nested Functions Useful?
Sam Siewert 15
Discussion - Need for New PLs? Reflective programming (Java library) – Observing and Modifying Programs While Running – RTI (Real-Time Innovations – Stethoscope -
http://www.rti.com/company/news/ss4-3.html ) – Kernel Shark for Linux System Code – Systemtap
Approximate Computing , Concepts Similar to MPEG Encoding and Lossy / Approximation (No Specific Language) Reconfigurable Computing (Verilog and VHDL) – OpenCL Co-Processors (CUDA extension to C, OpenCL for GPU & Multi-core) Thomas Standish on Extensible Programming Languages – Paraphrase Extension – Orthophrase Extension – Metaphrase Extension – Libraries (Outside PL, but Similar to Paraphrase Extension)
Sam Siewert 16
Programming Language Research SIGPLAN PLDI
“Less is More” [Today More is More] Apparently Not True with Programming Languages [History] Reduced Feature Set Programming Language – Programmer Extensible – Galaxy Programming Language [circa 1989-1991], ref2 – A Common Core Language Design for Layered Extension, Siewert
& Zorn – Good for RISC and Computer Architecture – Good for Compilers? – CUDA (NVCC), Halide, Other C / C++ Extensions Today
For Compilers and Interpreters, More is More! Simplified Construction of Complex Programming Languages – Intermediate RTL and LLVMs [Clang] for Quick Adaptability – Programming Languages for PL Construction – Racket, racket-
lang.org – Leave Extension and Feature Sets to Compiler/Interpreter Experts – Programmer’s Want Built-in Features and Libraries
Sam Siewert 17
Parameter Passing – Part B Mapping of Actual to Formal Arguments By Value – C Default By Value/Result (Copying), Scripting Languages References (Aliases) – Using Pointers or Access/Ref Operators in Strongly Typed PLs Closure/name
Sam Siewert 18