+-----------------------------+
| Object Program |
+-----------------------------+
|
v
+-----------------------------+
| Relocation & Linking Loader |
+-----------------------------+
|
v
+-----------------------------+
| Memory Allocation |
+-----------------------------+
|
v
+-----------------------------+
| Loaded Program in Memory |
+-----------------------------+
|
v
+-----------------------------+
| Program Execution |
+-----------------------------+
Design of a Direct Linking Loader
A Direct Linking Loader (DLL) is a type of loader that loads object
programs into memory for execution, resolving symbolic references
by linking the program with other necessary modules.
Key Features of a Direct Linking Loader:
1. Direct Loading: Loads the executable code directly into memory.
2. Linking and Relocation: Resolves all external references
(e.g., functions, variables) and relocates addresses during
loading.
3. Immediate Execution: Transfers control to the loaded
program after the loading process.
Steps in the Operation of a Direct Linking Loader:
1. Reading the Object Program:
○ The loader reads the object program (prepared by the
assembler) containing information about memory
allocation, external references, and relocation.
2. Relocation:
○ Adjusts address references in the program to match the
actual memory locations where the program is loaded.
3. Linking:
○ Resolves external references by linking different program
modules.
○ Uses the External Symbol Table (EST) or Linkage
Editor for reference.
4. Loading:
○ Copies the machine instructions and data from the object
file into appropriate memory locations.
5. Transfer of Control:
○ The loader transfers control to the starting instruction of
the loaded program.
Components of a Direct Linking Loader:
1. Object Module:
○ Contains the assembled code with relocation and linking
information.
2. Linking Information:
○ Includes references to symbols or routines that must be
resolved.
3. Relocation Information:
○ Contains details on which addresses in the code need to
be adjusted.
4. Memory Map:
○ Provides information about memory locations used by
the program.
Advantages of Direct Linking Loader:
● Efficient linking and loading process.
● Resolves external references during loading, reducing the
need for separate linking tools.
● Executes programs immediately after loading.
Dynamic Linking with or without Import
Dynamic linking refers to the process where an executable program
resolves library dependencies at runtime rather than during
compilation or loading. This provides flexibility, efficient memory
usage, and modular software design.
Dynamic Linking with Import
In this method, the program explicitly imports the functions or
symbols it needs from shared libraries (like DLLs or SO files).
Steps in Dynamic Linking with Import:
1. Declaration in Code:
○ Use an import directive or equivalent (e.g., #include
in C/C++) to indicate the dependency.
Example (C/C++):
#include <library.h>
○
2. Dynamic Linking by the Loader:
○ At runtime, the operating system's loader identifies and
links the imported symbols with the shared library.
○ Symbols and function references are resolved when the
program begins execution.
3. Benefits:
○ Explicit and clear dependency declaration.
○ Easier to manage symbol conflicts or versioning.
4. Example:
In Python:
python
import math
print(math.sqrt(16)) # Uses the 'math' shared
library
Dynamic Linking Without Import
Here, the program dynamically resolves and loads symbols from
libraries at runtime, often using specific system calls or functions
like dlopen and dlsym (in Unix-like systems) or LoadLibrary
and GetProcAddress (in Windows).
Steps in Dynamic Linking Without Import:
1. Load the Library Dynamically:
○ Use system-specific functions to load the library at
runtime.
Example (Unix-like systems):
void *handle = dlopen("liblibrary.so", RTLD_LAZY);
○
2. Retrieve Symbols Dynamically:
○ Use system calls to locate symbols (functions, variables,
etc.) in the library.
Example:
void (*func)() = dlsym(handle, "function_name");
func(); // Call the function
○
3. Unload the Library (Optional):
○ Release resources by unloading the library when it’s no
longer needed.
4. Benefits:
○ Greater control over the linking process.
○ Allows conditional loading of libraries based on runtime
requirements.
○ Reduces memory usage as only necessary libraries are
loaded.
i) Subroutine Linkage
Subroutine linkage refers to the mechanism by which a program
transfers control to a subroutine (function or procedure) and returns
control back to the main program after execution. It involves
managing data, control flow, and resources efficiently.
Components of Subroutine Linkage
1. Call Mechanism:
○ The main program calls the subroutine, passing required
arguments via registers, memory, or stack.
2. Prologue:
○ The subroutine initializes its environment, often saving
registers or stack pointers.
3. Execution:
○ The subroutine performs its intended function using local
and passed data.
4. Epilogue:
○ The subroutine cleans up resources, restores the saved
environment, and prepares for a return.
5. Return Mechanism:
○ Control is returned to the calling program, typically to the
instruction immediately following the call.
Features:
● Supports modular programming by dividing a program into
reusable subprograms.
● Handles recursion effectively by using the stack for each
subroutine's state.
ii) Overlays
Overlays are a technique used in systems with limited memory to
allow large programs to run by loading only the required portions of
the program into memory at a time.
How Overlays Work:
1. The program is divided into overlays, which are independent
segments.
2. Only one overlay (or set of overlays) is loaded into memory at
any time.
3. When a different part of the program is needed, the current
overlay is replaced with the required one.
Overlay Structure:
● Resident Area:
○ A portion of memory that remains constant and holds
critical routines like the overlay manager.
● Overlay Area:
○ A portion of memory where overlays are dynamically
loaded.
Features:
● Saves memory by not loading the entire program at once.
● Allows programs larger than physical memory to execute.
Example Use Case:
● Early operating systems or embedded systems with limited
memory.