The executing target program runs in its own logical address space in which each program value has a location.
The management and organization of this logical address space are shared between the compiler, operating system, and the target machine.
The operating system maps the logical addresses into physical addresses, which are usually spread throughout memory.
The runtime representation of an object program in the logical address space consists of data and program areas as shown in the next slide.
A compiler for language like C++ on an operating system like Linux might subdivide memory in this way.
The amount of storage needed for a name is determined by its type.
An elementary data type, such as character, integer, or float, can be stored in an integral number of bytes.
Storage for aggregate types, such as an array or structure, must be large enough to hold all its components.
The storage layout for data objects is strongly influenced by addressing the constraints of the target machine.
On many machines, instructions to add integers may expect integers to be aligned, which is placed at an address divisible by 4.
An array of ten characters needs only enough bytes to hold ten characters, a compiler may allocate 12 bytes to get the proper alignment, leaving 2 bytes unused.
Space left unused padding. due to alignment considerations is referred to as padding.
The size of the generated target code is fixed at compile-time, so the compiler can place the executable target code in a statically determined area Code, usually in the low end of memory.
Similarly, the size of some program data objects, such as global constants,
and data generated by a compiler such as information to support garbage collection may be known at compile-time, and these data objects can be placed in another statically determined area called Static.
To maximize utilization of space at run time, the other two areas, Stack and Heap, are at the opposite ends of the remainder of the address space.
These areas are dynamic; their size can change as the program executes.
The stack is used to store data structures called activation records that get generated during procedure calls.
An activation record is used to store information about the status of the machine, such as the value of the program counter and machine registers, when a procedure call occurs.
When control returns from the call, the activation of the calling procedure can be restarted after restoring the values of relevant registers and setting the program counter to the point immediately after the call.
Data objects whose lifetimes are contained in that of activation can be allocated on the stack along with other information associated with the activation.
Many programming languages allow the programmer to allocate and deallocate data under program control.
Ex: C has the functions malloc and free that can be used to obtain and give back arbitrary chunks of storage.
The heap is used to manage this kind of long-lived data.