22 2 Imperative Programming Languages
2.6 Memory Allocation for Variables of Basic Types
In this section we introduce some important concepts of compiler design, namely the
concepts of compile-time and run-time,static, and dynamic.Atcompile-time,agiven
C program is compiled into a CM
A program. At run-time this compiled C program
is executed with input data. Static information about a C program is all information
about this program that is knownat compile-time or that can be computed or derived
from other known information. Dynamic information is all information that only
becomes available when executing the CM
A program with the input data.
We have already seen examples of static and dynamic information about C pro-
grams. Static information includes, for instance, the target addresses of conditional
or unconditional jumps, since they are, after all, computed from the source program
with the aid of the code function. Obviously, this also holds true for all of the gen-
erated CM
A program. Thus, the CMA program as a whole is static. In general, the
values of variables and, thus, also the values of expressions containing variables,
are dynamic. These values may depend on input values of the program, which be-
come available only at run-time. Since the values of the conditions in statements are
dynamic, the control flow after evaluating a condition is also dynamic.
Consider a list of variable declarations of a C program of the form:
t
1
x
1
;...;t
k
x
k
;
For the moment, let us assume that all types are basic. According to our assumption
about the size of memory locations and the availability of memory, the values for
each variable x
i
of a basic type int or float, char, as well as enumeration types and
pointer variables, can be stored in a single memory location. This means that we
do not attempt, as is done in real compilers, to pack several small values into one
word. We obtain thus a simple scheme for storage allocation. We assign consecutive
addresses to variables in the order of their appearance in the list of declarations of
the program. The addresses start at the beginning of the stack. For the moment we
consider only programs without blocks and functions. The first assigned address is
1. For reasons that will become clear when we consider functions and blocks, the
assigned addresses are called relative addresses. The absolute address 1, thus, is
interpreted as the address 1 relative to the base address 0.
Let
ρ
denote a function that maps variables to their respective relative addresses.
Our strategy of storage allocation then means that
ρ
(x
i
)=i for 1 ≤ i ≤ k.
The relative addresses assigned in this way are static, since they result (in a sim-
ple way) from preprocessing the source program, namely, from the positions of the
variables within the list of declarations.
Theseaddresses are, of course, located in the memory area that has been reserved
for the stack of the C-Machine. When we deal with functions and procedures, it will
turn out that we are actually talking about several stacks, nested into each other. One
is large and contains the data sections of all functions that have been called and not