0% found this document useful (0 votes)
4 views26 pages

SPCC

The document outlines the differences between system software and application software, explaining their definitions, purposes, user interactions, dependencies, and examples. It also covers the distinctions between compilers and interpreters, the role of device drivers, and the process of program development and execution involving various system programs. Additionally, it discusses code optimization techniques, types of macros, and the functions of loaders in the compilation process.

Uploaded by

Eben Varghese
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
4 views26 pages

SPCC

The document outlines the differences between system software and application software, explaining their definitions, purposes, user interactions, dependencies, and examples. It also covers the distinctions between compilers and interpreters, the role of device drivers, and the process of program development and execution involving various system programs. Additionally, it discusses code optimization techniques, types of macros, and the functions of loaders in the compilation process.

Uploaded by

Eben Varghese
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd

Differences:

Basis System Software Application Software


Software designed to perform
Software that manages hardware and
Definition specific user tasks
system resources

To control and operate the computer


To help users perform tasks like
Purpose system
writing, browsing, etc.

Users do not interact directly most of the


User
time Users directly interact with it
Interaction

Runs independently and supports other


Dependency software Depends on system software to run

Starts when the computer is turned on


Execution Runs when the user opens it
Operating System, Compiler, Assembler,
Examples MS Word, Google Chrome, VLC
Drivers

Differences:

Compiler Interpreter

Translates the entire program at once Translates and executes the


into machine code. program line by line.

Execution is faster after compilation Execution is slower because


because code is already translated. translation happens during runtime.

Displays all errors after compiling the Displays errors one by one as they
whole program. occur.

Generates object code or executable


Does not generate object code.
file.

Program must be compiled before Program is executed directly without


execution. separate compilation.

Requires more memory to store object Requires less memory since no


code. object code is stored.
Device Driver – Simple Explanation

A device driver is a program that helps your computer talk to hardware


devices.
Your operating system (like Windows) cannot directly understand how every
device works, so it uses a driver as a translator.

👉 In simple words:
Device driver = Translator between OS and hardware

How it Works (Very Easy Idea)

 You give a command → (like print a file)

 OS sends that command → to device driver

 Driver converts it → into device-specific instructions

 Hardware understands and performs the task

Real-Life Example (Best for Memory)

Think of it like:

👉 You (OS) → Translator (Driver) → Foreign person (Hardware)

Without the translator, communication is not possible.

Why Device Drivers are Important

 Without drivers, hardware will not work properly

 They help in controlling devices like printer, mouse, etc.

 They ensure smooth communication between software and hardware

 Every device needs its own driver

Examples of Device Drivers

 Printer Driver → helps in printing

 Keyboard Driver → detects key presses


 Mouse Driver → controls pointer movement

 Display (Graphics) Driver → shows visuals on screen

 Sound Driver → handles audio

 Network Driver → connects to internet


Order and Role of System Programs (From Program Development to
Execution)

When a program is developed and executed, a series of system programs


work one after another to convert the source code into a form that the
computer can understand and run. Each system program has a specific role
in this process, starting from writing the program to its final execution.

The first step is the editor, which is used by the programmer to write and
modify the source code. It provides a simple interface to type, edit, and save
the program. The code written here is called the source program and is
usually written in a high-level or assembly language.

Next, the program goes to the macro processor. The macro processor looks
for any macros (short names for a group of instructions) and replaces them
with their actual code. This process is called macro expansion and helps in
reducing repetition and making the program easier to write.

After that, the program is given to the compiler. The compiler translates the
high-level language program into lower-level code (assembly or intermediate
code). It also checks for errors in the program such as syntax and semantic
errors. If errors are found, they are reported so the programmer can correct
them.

Then, the assembler takes the assembly language code and converts it into
machine code (object code). Assembly language uses symbolic instructions,
which are translated into binary code that the computer can understand.

Once the object code is generated, the linker combines it with other object
files and required library functions. It resolves external references and
produces a single executable file that is ready to run.

Finally, the loader loads this executable file into the main memory (RAM). It
allocates memory, adjusts addresses if needed, and transfers control to the
program so that execution begins.
Differences:

Top-Down Parsing Bottom-Up Parsing

It starts from the start symbol and It starts from the input string and tries
tries to derive the input string. to reach the start symbol.

It builds the parse tree from root to It builds the parse tree from leaves to
leaves. root.

It uses rightmost derivation in


It uses leftmost derivation.
reverse.

It is simpler and easier to implement. It is more complex but more powerful.

It may require backtracking in some


It does not require backtracking.
cases.

It detects errors later during parsing. It detects errors earlier.

Examples include recursive descent Examples include shift-reduce and LR


and predictive parsing. parsing.
Code Optimization in Compilers

Code optimization is the process of improving the intermediate or target


code generated by the compiler so that the program runs faster and uses
less memory, without changing its output. It removes unnecessary
instructions and improves efficiency. The main aim of optimization is to
produce better and faster machine code.

Need for Code Optimization

Code optimization is important because it improves the performance of a


program. Optimized code executes faster and uses fewer resources like
memory and CPU. It removes redundant calculations and unnecessary
instructions, making the program more efficient. This is especially useful in
large programs and systems where performance is critical.

Types of Code Optimization Techniques

1. Machine Independent Optimization

This type of optimization is done before code generation and does not
depend on any specific machine. It works on intermediate code and improves
the logic of the program. It is applicable to all systems.

2. Machine Dependent Optimization

This optimization is done after code generation and depends on the


hardware or processor. It improves the final machine code using features like
registers and instruction sets. It is specific to a particular machine.

3. Constant Folding

Constant folding evaluates constant expressions at compile time instead of


runtime. This reduces computation during execution and improves speed.
Example: 5 + 3 → 8
4. Constant Propagation

Constant propagation replaces variables that have constant values with their
actual values. This simplifies expressions and reduces computation.
Example: a = 10 → b = a + 5 → b = 10 + 5

5. Common Subexpression Elimination

This technique avoids repeated calculations of the same expression. The


result is calculated once and reused.
Example: a*b used multiple times → computed once

6. Dead Code Elimination

Dead code elimination removes instructions that do not affect the output of
the program. This reduces unnecessary operations.
Example: unused variables or overwritten values

7. Loop Optimization

Loop optimization improves the performance of loops by reducing repeated


calculations inside loops. It makes execution faster.

8. Peephole Optimization

Peephole optimization examines a small set of instructions and replaces


inefficient ones with better ones. It reduces code size and improves
performance.
Example: removing ADD R1, 0
Abstract Syntax Tree (AST)
An Abstract Syntax Tree (AST) is a tree representation of the structure of a program or
expression.
In this tree, internal nodes represent operators (like +, −, *, /) and leaf nodes represent operands
(variables or constants).
It shows the logical structure of the expression without unnecessary grammar details.
AST is mainly used in compilers for semantic analysis and code generation.

Directed Acyclic Graph (DAG)


A Directed Acyclic Graph (DAG) is a graph representation of an expression that avoids
repeated computations.
Common sub-expressions are stored only once and shared, making the program more efficient.
It has no cycles and a node can have multiple parents.
DAG is mainly used in compilers for code optimization.
Role of Finite Automata (FA) in Compilation Process

Finite Automata (FA) play an important role in the lexical analysis phase of
a compiler. Lexical analysis is the first phase where the source program is
broken into tokens such as keywords, identifiers, operators, and constants.

FA is used to recognize patterns in the input string. It reads the source


code character by character and checks whether the sequence of characters
forms a valid token. For example, it can identify whether a word is a valid
identifier or a number.

There are two types of FA used: Deterministic Finite Automata (DFA) and
Non-Deterministic Finite Automata (NFA). Usually, NFAs are first
designed from regular expressions and then converted into DFAs for efficient
implementation in lexical analyzers.

FA helps in:

 Identifying tokens correctly

 Removing white spaces and comments

 Detecting lexical errors (invalid tokens)

Example

If the input is:


int a = 10;

FA helps recognize:

 int → keyword

 a → identifier

 10 → number
Forms of Intermediate Code used by Compiler

Intermediate code is a representation of a program between high-level


language and machine code. It is simple, machine-independent, and easy to
optimize. There are different forms of intermediate code used by compilers.

1. Three-Address Code (TAC)

Three-address code is a simple form where each instruction has at most


three operands (two inputs and one result). It breaks complex expressions
into smaller steps using temporary variables. This makes code easy to
understand and optimize.

Example:

t1 = b-c
t2 = a * t1
t3 = t1 * d
t4 = a + t2
t5 = t4 + t3

2. Quadruples

Quadruples represent three-address code using four fields: (operator,


operand1, operand2, result). It is easy to store and modify during
optimization. Each instruction is stored as a separate record.

Example:

o arg arg resul


p 1 2 t

- b c t1

* a t1 t2

+ t2 t3 t4

3. Triples
Triples are similar to quadruples but do not use temporary variables. Instead,
they use the index of the instruction as a reference. This reduces the need
for extra storage.

Example:

Inde o arg arg


x p 1 2

0 - b c

1 * a (0)

2 + (1) d

4. Indirect Triples

Indirect triples are an improved version of triples. They use a separate


pointer table to refer to instructions. This allows easy rearrangement of
instructions without changing references.
Functions of Loader

A loader is a system program that loads the executable program into main
memory and prepares it for execution. It performs several important
functions to ensure the program runs correctly.

Allocation

Allocation is the process of assigning memory space to the program. The


loader decides where the program and its data will be placed in memory so
that it can execute properly.

Linking

Linking connects different modules and resolves external references. If a


program uses functions or variables from other files, the loader links them
together to form a complete program.

Relocation

Relocation adjusts the addresses of instructions when the program is loaded


into memory. If the program is not loaded at its original location, the loader
updates the addresses so that execution is correct.

Loading

Loading is the process of copying the program from secondary storage (disk)
into main memory (RAM). Once loaded, the program is ready for execution.

Transfer of Control

After loading, the loader transfers control to the starting address of the
program so that execution begins.

Loader Schemes

1. Absolute Loader

In this scheme, the program is loaded at a fixed memory location. The


addresses are already specified, so no relocation is needed.
Limitation:
It is not flexible because the program must be loaded at a specific location
and cannot be moved.

2. Relocating Loader

This loader can load the program at any memory location. It modifies
addresses during loading to suit the new location.

Limitation:
It is more complex and requires extra processing time.

3. Linking Loader

This loader performs both linking and loading. It combines multiple object
modules and loads the final executable into memory.

Limitation:
Loading time increases because linking is done at load time.

4. Dynamic Linking Loader

In this scheme, libraries are loaded only when needed during execution. This
saves memory and allows shared libraries.

Limitation:
Execution may be slower because linking happens during runtime and
dependencies may cause issues.
Types of Macros

Macros are used to avoid writing the same code again and again.
Instead of repeating instructions, we give them a name (macro), and the
macro processor replaces that name with actual code.

1. Simple Macro

A simple macro is a macro that does not take any parameters (inputs).
It contains a fixed set of instructions that always remain the same. Whenever
the macro is called, the same instructions are inserted into the program. This
is useful when the same code is repeated many times.

👉 Example:
If you define a macro to increment a value, every time you call it, the same
increment code is added.

2. Parameterized Macro

A parameterized macro is a macro that accepts inputs (parameters).


These parameters are given when the macro is called, and they are used
inside the macro body. This makes the macro flexible, because the same
macro can work with different values.

👉 Example:
Instead of writing separate code for adding different numbers, one macro
can be used with different inputs like ADD 5, 10 or ADD 2, 3.

3. Conditional Macro

A conditional macro is a macro that uses conditions like IF and ELSE. It


checks a condition and expands different code depending on whether the
condition is true or false. This helps in decision-making during macro
expansion.
👉 Example:
A macro can print “POSITIVE” if a number is greater than zero, otherwise
print “NEGATIVE”.

4. Nested Macro

A nested macro is when one macro is used inside another macro. This
means a macro can call another macro during its execution. It is useful for
organizing large programs and reusing multiple macros together.

👉 Example:
A macro for “PROCESS” can internally call another macro like “DISPLAY”.

Data Structures Used in Macro Expansion

During macro processing, some tables are used to store and manage macro
information.

1. MNT (Macro Name Table)

MNT stores the names of all macros defined in the program. Along with the
name, it also stores a pointer to where the macro definition is located in MDT.
When a macro is called, the macro processor first checks MNT to see if it
exists. It helps in quickly finding the macro.

👉 Easy idea:
MNT = List of macro names

2. MDT (Macro Definition Table)

MDT stores the actual code (body) of the macro. Each macro definition is
stored line by line in this table. When a macro is called, the macro processor
takes the instructions from MDT and replaces the macro call with those
instructions.

👉 Easy idea:
MDT = Actual macro code
3. ALA (Argument List Array)

ALA stores the values (arguments) passed to the macro during a call. It
matches actual values with the formal parameters defined in the macro. This
helps in correctly replacing parameters in the macro body.

👉 Easy idea:
ALA = Values given to macro

Types of Macros

Macros are used to reduce repetition of code by giving a name to a group


of instructions. Different types of macros provide flexibility and control.

🔹 Simple Macro

A simple macro is a macro that does not take any parameters (inputs).
It contains a fixed set of instructions, so every time you call it, the same code
is inserted.
There is no change in values or behavior during different calls.
👉 It is mainly used when the same code is repeated many times.

Example:

MACRO INCR
A=A+1
END
INCR

1. Parameterized Macro

A parameterized macro is a macro that takes inputs called parameters.


These parameters are passed when the macro is called and are used inside
the macro body. This allows the same macro to be reused with different
values, making programs more flexible and reducing code duplication.

👉 Example:

MACRO ADD X, Y
A=X+Y
END

ADD 5, 10

👉 Expansion:
A = 5 + 10

👉 Easy idea: One macro, many uses with different values.

2. Nested Macro

A nested macro is a macro that contains another macro inside it or calls


another macro. This means one macro can use another macro during its
execution. It helps in organizing large programs into smaller reusable parts
and improves modularity.

👉 Example:

MACRO DISPLAY
PRINT "HELLO"
END

MACRO MAIN
DISPLAY
END

MAIN

👉 Expansion:

PRINT "HELLO"

👉 Easy idea: Macro inside a macro.

3. Conditional Macro

A conditional macro is a macro that uses conditions like IF, ELSE to decide
which code to expand. It checks a condition and generates different outputs
depending on the result. This adds decision-making ability to macros.

👉 Example:

MACRO CHECK X
IF X > 0
PRINT "POSITIVE"
ELSE
PRINT "NEGATIVE"
END

CHECK 5

👉 Expansion:

PRINT "POSITIVE"

👉 Easy idea: Macro that can take decisions.

Types of Assembly Language Statements

Assembly language programs are made up of different types of statements.


Each type has a specific role in defining operations, storing data, and
controlling the program. The three main types are Imperative Statements,
Declarative Statements, and Assembler Directives.

1. Imperative Statements (IS)

Imperative statements are used to perform actual operations such as


arithmetic calculations, data transfer, and control operations. These
statements are directly translated into machine code and executed by the
processor. They form the main logic of the program.

👉 Example:

ADD A, B
SUB X, Y
MOV R1, R2
👉 Importance:
These statements are important because they perform all the actual work of
the program, like calculations and data movement.

2. Declarative Statements (DL)

Declarative statements are used to define variables and allocate


memory. They may also assign initial values to variables. These statements
do not perform operations but help in storing data used by the program.

👉 Example:

X DS 1 ; Reserve 1 memory location


Y DC 5 ; Store value 5

👉 Importance:
They are important because they provide storage for data, without which the
program cannot store or process values.

3. Assembler Directives (AD)

Assembler directives are instructions given to the assembler to control the


assembly process. They do not generate machine code but help in
organizing the program, setting memory locations, and defining the start and
end of the program.

👉 Example:

START 100
ORIGIN 200
END

👉 Importance:
They are important because they control how the program is assembled and
executed, including memory allocation and program structure.
Data Structures Used in Assembler

An assembler uses different data structures (tables) to store and manage


information while converting assembly language into machine code. These
tables help in identifying instructions, storing symbols, handling constants,
and resolving references.

1. MOT (Machine Opcode Table)

MOT stores all the machine instructions like ADD, SUB, LOAD, etc.
Each instruction is stored with its opcode and details.
The assembler uses MOT to convert mnemonics into machine code.
In simple words, it is like a dictionary of instructions

Mnemon Opcod Lengt


ic e h

ADD 01 2

SUB 02 2

MOV 03 2
Mnemon Opcod Lengt
ic e h

👉 Importance:
It helps the assembler convert symbolic instructions into actual machine
instructions.

2. POT (Pseudo Opcode Table)

POT stores assembler directives like START, END, ORIGIN.


These are not real instructions and do not generate machine code.
They help control the assembly process and program structure.
In simple words, they give instructions to the assembler, not the CPU.

Pseudo-
op

START

END

ORIGIN

👉 Importance:
It helps in controlling program structure, memory location, and execution
flow.

3. ST (Symbol Table)

ST stores all symbols (labels and variables) with their addresses.


It is mainly built during Pass 1 of the assembler.
It helps replace symbol names with actual memory addresses.
In simple words, it is a name-to-address mapping table.

👉 Example:

Symb Addre
ol ss

X 100

LOOP 120
Symb Addre
ol ss

👉 Importance:
It helps in resolving symbol references and generating correct machine code.

4. LT (Literal Table)

LT stores literals (constant values like =5, =10) used in the program.
Each literal is assigned a memory location by the assembler.
It helps in managing and accessing constant values efficiently.
In simple words, it is a table of constant values with addresses.

Liter Addre
al ss

=5 200

=10 204

👉 Importance:
It helps in handling constants efficiently and assigning them proper memory
locations.

5. FRT (Forward Reference Table)

FRT stores symbols that are used before they are defined in the program.
These are called forward references. The assembler temporarily stores them
and resolves them later when their definitions are found.

👉 Example:

If a statement uses symbol X before it is defined, it is stored in FRT until X is


assigned an address.

👉 Importance:
It helps in handling forward references, especially in single-pass assemblers.
Macro Processor

Definition

A macro processor is a system program that processes macro definitions


and macro calls in a program. It replaces macro names with their actual set
of instructions, a process called macro expansion. This helps reduce
repetition and makes programs shorter and easier to write.

Functions of Macro Processor

1. Macro Definition Processing

The macro processor reads and stores macro definitions written in the
program. It identifies the macro name and its body and stores them in tables
like MNT (Macro Name Table) and MDT (Macro Definition Table). This allows
the macro to be used later when called.

2. Macro Call Recognition

The macro processor scans the program and detects macro calls. When it
finds a macro name in the program, it checks in the MNT to confirm that it is
a valid macro. This step ensures that macros are correctly identified.

3. Macro Expansion

Macro expansion is the main function of the macro processor. It replaces the
macro call with the actual instructions stored in MDT. This means the macro
name is replaced by its full code in the program.

4. Parameter Handling

If the macro has parameters, the macro processor handles them using ALA
(Argument List Array). It matches the actual values given in the macro call
with the formal parameters in the macro definition. Then it replaces them
correctly in the macro body.

5. Maintaining Tables

The macro processor maintains important data structures such as MNT, MDT,
and ALA. These tables help in storing macro names, definitions, and
arguments. They ensure efficient processing and correct expansion of
macros.

Example (Simple Idea)

If a macro is defined as:


MACRO ADD X, Y
A=X+Y

And called as:


ADD 5, 10
It will expand to:
A = 5 + 10

1-Pass Assembler

A 1-pass assembler processes the entire program only once. While


reading each line, it assigns addresses, updates the symbol table, and
generates machine code at the same time. It is faster because it scans the
program only once.

However, it has difficulty handling forward references (when a symbol is


used before it is defined). To solve this, it may use extra structures like a
forward reference table.

👉 Key Idea:
One scan → fast but complex
2-Pass Assembler

A 2-pass assembler processes the program two times.

 In Pass 1, it reads the program, assigns addresses, and builds the


symbol table.

 In Pass 2, it uses this information to generate the final machine code.

It easily handles forward references because all symbols are already known
before code generation.

👉 Key Idea:
First collect → then generate

You might also like