1.2.2 - Translators, libraries, linkers and loaders
A processor executes machine instructions, while programmers often write in a more readable language. You will follow how translators bridge that gap, why reusable libraries are helpful, and how linking and loading prepare translated code to run.
Translation bridges source and machine instructions
A translator converts program instructions into a form another system can process. A high-level language can express a calculation without naming CPU registers or instruction encodings. Machine code is made of instructions for a particular processor architecture, so the processor cannot directly execute the high-level text as though it were machine code.
An assembler translates assembly language into machine code. Assembly uses mnemonic instruction names and symbolic labels in place of numeric instruction encodings and addresses. An assembler looks up instruction encodings and resolves labels to addresses. In a simple assembly language, a mnemonic instruction usually corresponds closely to a machine instruction; a high-level statement may need several machine instructions. Assemblers can also support directives and macros, so “every source line always becomes exactly one instruction” is too absolute.
An assembly program for one instruction set normally needs changes for a different architecture. A high-level program can often be translated for several targets if an appropriate implementation exists and the program avoids target-specific assumptions. Neither portability nor correctness is guaranteed simply by choosing a high-level language.
Compilation and interpretation organise execution differently
Compiler
A compiler translates a program into target code before that target is run.
For a conventional native-code build, the output is object code that can be linked into an executable. Compilation can inspect the program as a whole and report errors found during translation. A successful build does not prove that the program's logic satisfies the requirements or that no runtime error will occur.
Interpreter
An interpreter processes and carries out source instructions during execution, typically without giving the user a separate native executable for that source program.
In the simple examination model, it translates/executes one instruction at a time. The interpreter must be present when the source is run. Repeated execution may repeat interpretation work, while compiled target code can normally run without translating its original source again.
During development, interpretation can support quick experiments: change a statement and run the new source without a separate native build. Errors encountered during execution can stop the program at that point. For repeated distribution, a native executable can provide faster execution and avoid supplying the original source. The target system must still have compatible architecture, operating-system interfaces and required libraries. “Compiled programs run on every computer” is false.
Real language implementations can combine these ideas: an implementation may compile source into intermediate bytecode and interpret that bytecode, or compile some code while running it. Python is used here for procedural teaching, but calling a language inherently “only interpreted” hides implementation choices. In a comparison question, state the conventional model and connect its operation to the given need.
Libraries supply reusable routines through interfaces
Library
A library is a collection of reusable code, such as mathematical, image-processing or networking routines.
Its interface documents available routines, arguments and results. The programmer calls those routines instead of reimplementing every detail.
This static Python example uses the standard mathematical library:
import math
area = 50
side = math.sqrt(area)
print(round(side, 2))
Square-side example
Example run7.07
The call supplies 50 to sqrt, receives its square root and rounds the displayed result to two decimal places. It does not round the stored side merely by printing round(side, 2). The routine's contract matters: a real-valued square root requires a non-negative input. Reuse saves development time and can provide well-tested specialist code, but the caller must still choose suitable inputs and handle relevant failures.
A library can introduce version, availability, security or licence dependencies. If an updated routine changes its interface or behaviour, callers may break. Keep a compatible version, understand the documentation and test the actual integration. A library's reputation is evidence to consider, not a proof that every use is correct.
Linking connects code and loading places it in memory
Separately translated modules may contain references to routines whose code is elsewhere. A linker resolves those references and combines the required object modules and library code to produce an executable, or records references to dynamically linked libraries. The job is connecting translated pieces; it is distinct from translating high-level source.
With static linking, required library code is incorporated into the executable at build time. The executable can be larger and different programs may contain their own copies, but that included library code does not need a separate shared-library installation at runtime. With dynamic linking, the executable uses a separate library whose code and addresses are connected at load time or during execution. This can permit shared code and separate library updates, but the expected compatible library must be available. An incompatible replacement can cause failure even when the program itself was unchanged.
A loader, normally part of the operating-system environment, takes an executable from secondary storage and places it in main memory, along with required libraries. It prepares the program's memory locations and execution state; relocation may adjust address references to match where code was placed. Execution then uses the loaded instructions. Loading does not turn high-level source into machine code or certify that the algorithm is correct.
[DIAGRAM: Simplified static linking and loading route; asset_slug: linking-loading; caption: The linker connects object code into an executable. The loader then places that executable in main memory.]

Suppose a payroll module calls a separately compiled rounding routine. The compiler can translate the payroll source while leaving a reference to that routine. The linker supplies the connection to its object code. On starting payroll, the loader brings the executable into memory.
Reuse, connection and preparation
The library supplies reusable routines. The linker connects references to the required code; the loader places the executable and required libraries in main memory and prepares execution. Keeping these responsibilities distinct makes a missing-library error easier to explain.