A program written in C/C++ is stored in one or more source modules as plain ASCII text files. These are compiled into object modules. Because we are focused on all memory- related aspects of this process, we emphasize the fact that all symbolic references from the source program are replaced by address references in the object module; the address references are in the form of logical (or relative) addresses, which represent the location of an object as the offset (distance) from the beginning of the load module (or an activation frame for a local object). During relocation and linking, all object modules are "forged" together into a single load module. During that process, all logical addresses are updated vis- -vis the beginning of the new load module being created. This load module contains all information about what the abstract program address space should look like.
When we request the operating system to execute a program, its load module is loaded into memory - that is, the program address space is created and mapped to physical addresses. Now the program can be executed one instruction at a time, in the usual way. Thus, on a certain level of abstraction, we can pretend that the C/C++ instructions of the source program are mapped onto sets of machine instructions stored in the memory and that data ( variables , objects, etc.) of the program are mapped to appropriate segments of the memory. (Static data - i.e., global objects and local objects defined with the storage class "static" - are mapped into the static data region of the program's memory, while dynamic data are mapped into the dynamic data region of the program's memory.) This level of abstraction is useful for discussions of programs and their semantics. Each object in a program thus corresponds to a well-defined segment of memory, and the program's instructions merely modify these objects; that is, the instructions either read the data from or store new data in these memory segments.