os (1)
os (1)
Introduction
A programming system includes the tools and methodologies used to develop, manage, and execute computer
programs. Over the years, programming systems have evolved significantly, reflecting advancements in
hardware and software technologies.
Historical Evolution
1. Early Programming Systems (1940s-1950s)
• Programs were written in binary machine language, making programming tedious and error-prone.
• Assembly language introduced mnemonic instructions.
Key Components:
• Machine Language (binary instructions)
• Assembly Language (mnemonic symbols)
• Assembler (translates assembly to machine language)
2. Higher-Level Languages (Late 1950s-1960s)
• Introduction of languages such as Fortran, COBOL, ALGOL.
• Simplified programming with more natural language constructs.
Key Components:
• Compiler (high-level code to machine language)
• Loader (loads programs into memory)
• Linker (combines program modules)
3. Structured and Modular Programming (1970s)
• Emphasized clarity, structured control flows, and modularity.
Key Components:
• Structured languages: C, Pascal
• Libraries for code reuse
• Development environments (early IDEs)
4. Object-Oriented Programming (1980s-1990s)
• Software designed using objects representing real-world entities.
Key Components:
• Object-oriented languages: C++, Java
• Classes, inheritance, polymorphism
• Integrated Development Environments (IDEs)
5. Modern Programming Systems (2000-present)
• Focused on productivity, scalability, continuous integration, and cloud computing.
1
Key Components:
• Modern languages: Python, JavaScript, Go, Rust
• Version control: Git, SVN
• Automated Testing Frameworks: JUnit, pytest
• Continuous Integration/Continuous Deployment (CI/CD): Jenkins, GitLab CI/CD
• Cloud Computing Platforms: AWS, Azure, Google Cloud
Historical Evolution
1. Serial Processing (1940s-1950s)
• Computers ran one job at a time, operated manually by programmers.
• No operating systems; programs directly managed hardware.
• Slow and inefficient; considerable downtime between programs.
2. Batch Systems (1950s-1960s)
• Jobs with similar requirements grouped into batches.
• Batch processing improved utilization by minimizing idle time.
• Introduction of job control languages (JCL) for specifying job requirements.
3. Multiprogramming (1960s)
• Enabled multiple programs to reside in memory simultaneously.
• CPU switches jobs to utilize waiting times (e.g., during I/O operations).
• Significant improvement in CPU utilization and throughput.
4. Time-Sharing Systems (1970s)
• Allowed multiple users to interact with the computer simultaneously.
• Enabled interactive computing, with short CPU time slices allocated to users.
• Led to development of UNIX, which introduced concepts like shell and file permissions.
5. Personal Computing (1980s)
• Emergence of personal computers with OS such as DOS, Windows, and Mac OS.
• Graphical user interfaces (GUIs) provided ease of use for non-technical users.
• Focus shifted towards user-friendliness and desktop management.
6. Modern Operating Systems (1990s-present)
2
• OS evolved to support advanced multitasking, virtual memory, and security features.
• Introduction of networked and distributed operating systems.
• Integration of virtualization and cloud computing.
• Major modern operating systems: Windows, Linux, macOS, Android, and iOS.
Impacts of OS Evolution
• Improved resource utilization and efficiency.
• Enhanced user experience and accessibility.
2. Compilers
• Convert high-level language (HLL) code to machine language in one go.
• Perform syntax checking, semantic analysis, optimization, and code generation.
• Produce executable files directly.
3. Interpreters
• Translate and execute code line-by-line at runtime.
• Allow immediate execution and debugging.
3
Historical Evolution
1. Early Translators (1950s-1960s)
• First assemblers developed to ease binary coding.
• Development of interpreters for languages like BASIC and Lisp for interactive environments.
3. Modern Translators (1990s-present)
• Advanced compiler techniques: Just-In-Time (JIT) compilation, dynamic translation.
Machine Structure
Definition: Machine structure refers to the internal organization of a computer system’s hardware compo-
nents that interact to fetch, decode, and execute instructions.
Key Components:
4
• Registers: Small storage units within the CPU for holding operands, instructions, or memory ad-
dresses temporarily.
– E.g., Accumulator (ACC), Base Register (BX), Stack Pointer (SP).
• Main Memory (RAM): Holds both program instructions and data during execution.
• System Buses:
– Data Bus: Transfers actual data.
– Address Bus: Transfers location addresses to memory or I/O.
– Control Bus: Transfers control signals like Read/Write or Interrupt.
• Input/Output Devices: Allow interaction with the external world. Examples include keyboard,
mouse, display, network cards.
Example Architecture: Von Neumann Model
• Single memory space for both data and instructions.
Machine Language
Definition: Machine language is a set of binary instructions that a computer can execute directly. It is the
lowest level of code, often represented in bits (0s and 1s).
Features:
• Each instruction contains an opcode and one or more operands.
Advantages:
5
Assembly Language
Definition: Assembly language is a low-level programming language that uses symbolic mnemonics to
represent machine-level instructions.
Characteristics:
Sample Instructions:
MOV AX , 0005 h ; Load the number 5 ( in hex ) into register AX
ADD AX , 0003 h ; Add 3 to AX
MOV [2000 h ] , AX ; Store the result into memory address 2000 h
Extended Example:
START : MOV AX , 0040 h ; Load hex 0040 into AX
MOV BX , AX ; Copy AX into BX
INC BX ; Increment BX
CMP BX , 0045 h ; Compare BX to 0045 h
JNE START ; Jump back to START if not equal
Applications
• Writing bootloaders and BIOS code.
• Programming microcontrollers (e.g., Arduino, 8051).
• Device drivers and OS kernel modules.
6
Loaders
Loader Schemes
A loader is a system software component responsible for loading machine language programs into memory.
It prepares the code for execution by the processor, ensuring correct address translation, linking external
symbols, and managing memory layout.
1. Compile-and-Go Loader
Working:
• Source code is compiled and immediately loaded into memory.
• Execution begins directly after compilation.
• No object file or loader module is created.
Example:
$ cc program . c
$ ./ a . out \ textit {( executed immediately after compilation )}
Advantages:
• Simple implementation.
• Fast startup for development/debugging.
Disadvantages:
• Compilation must be repeated for every run.
• Source code must be available.
• Inefficient memory usage; no memory reuse.
2. Absolute Loader
Working:
• Loader reads object code with absolute addresses.
• Loads it directly into those addresses without modification.
Format:
• Header Record: Program name, start address.
• Text Record: Instructions/data with absolute addresses.
7
• End Record: Entry point address.
Example:
H COPY 0000 0018
T 0000 141033282030...
E 0000
Advantages:
• Fast and efficient loading.
Disadvantages:
• No support for relocation.
• Programmer must manage memory.
3. Relocating Loader
Working:
• Uses relocation table to adjust all absolute addresses.
• Loader calculates the new address based on actual load position.
Relocation Formula:
Advantages:
• Programs can be loaded at any memory location.
• Memory is better utilized.
Disadvantages:
• Requires relocation table and address scanning.
8
5. Dynamic Loader
Working:
• Loads modules only when required at run time.
Features
• Fixed Memory Addresses: The object code contains absolute addresses, and the loader places the code
into these exact memory locations.
• No Relocation or Linking: The loader does not modify addresses or resolve external references.
• Due to its straightforward operation, it’s easy to implement but lacks flexibility.
Example:
H COPY 001000 00107 A
T 001000 1 E 141033 281030 300015 ...
T 00101 E 15 482039 3 C1003 ...
E 001000
9
Working of Absolute Loader
1. Read the header record to determine the starting address.
2. For each text record:
• Read the starting address and object code.
• Place the code at the exact specified location in memory.
3. Read the end record and transfer control to the starting address.
Advantages
• Extremely fast loading since no relocation/linking is needed.
• Simple to implement and understand.
Disadvantages
• Cannot handle programs that need to be loaded at different memory locations.
• No support for multiple modules or external references.
• Programmer must handle all memory-related details.
Use Cases
• Useful for bootstrapping or loading very small, self-contained programs.
• Common in early operating systems and simple embedded systems.
Illustration
Figure: Loading
memory blocks using Absolute Loader
10
Design of a Direct-Linking Loader
Introduction
A Direct-Linking Loader (DLL) is an advanced loader that performs both linking and relocation at load
time. It is designed to manage large applications that consist of multiple object modules. It uses external
symbol definitions to combine all required modules into a single executable.
Key Features
• Two-pass loading process.
• Maintains an External Symbol Table (ESTAB).
• Handles external references across object modules.
• Adjusts relocation using modification records.
Advantages
• Enables modular program development.
11
Disadvantages
• Requires more memory and processing time.
• Complex implementation and debugging.
Use Cases
• Suitable for large-scale software systems.
• Used in modern operating systems and multi-module application development.
Illustration
12