# Linker and Loader Design ## Linker A linker is a system program that connects compiled or assembled code to create an executable program. It takes object files and combines them into a single executable by resolving symbol references. For example, consider two C++ files: ```c++ // File1.cpp extern int x; int main() { x = 5; return 0; } // File2.cpp int x; ``` The `extern` keyword in `File1.cpp` indicates that `x` is defined in another file, `File2.cpp`, in this case. The linker's job is to resolve this reference. A linker performs two main tasks: 1. **Symbol Resolution**: It associates each symbol reference with one symbol definition. 2. **Relocation**: It updates the addresses of memory references from relative to absolute. ## Loader The loader loads the executable program into memory for execution. It determines the memory locations for data and code, copies instructions and data into memory, and initiates execution. There are three types of loaders: 1. **Absolute Loader**: The simplest type of loader which loads the program into a fixed part of memory. It assumes a fixed location in memory for the program. 2. **Relocatable Loader**: It allows programs to be loaded into different parts of memory, making efficient use of available memory. 3. **Dynamic Run-time Loader**: It loads routines into memory only as they are needed during program execution. Here's a simple example of program loading: ```assembly // Machine Code LOAD R1, x ADD R1, y STORE R1, z ``` In the assembly code above, `x`, `y`, and `z` are memory addresses. The loader replaces these symbolic addresses with actual physical addresses in memory before the program is run. In conclusion, the linker and loader play crucial roles in preparing a program for execution. They resolve symbol references, relocate relative addresses, and load the program into memory, making it possible to execute complex, multi-file programs efficiently.