SYSTEM SOFTWARE (M1 TO M4) ShortNotes
SYSTEM SOFTWARE (M1 TO M4) ShortNotes
System Software
System software is a type of computer program that is designed to run a computer’s hardware and application
programs. It is a computer software designed to provide a platform to other software. Examples of system
software include operating systems, device drivers, firmware, and utility programs. The system software is the
interface between the hardware and user applications. The operating system (OS) is the best-known example
of system software.
Language processor
A language processor is a type of software that converts programming source code into machine-readable
code. There are three types of language processors:
1. Compiler: A compiler is a program that converts the entire source code into machine code in one go. It
checks for syntax errors and generates an object file that can be executed.
2. Interpreter: An interpreter is a program that converts high-level language to machine-level language line by
line. It first scans one line of a program or source code, checks for errors, and then executes it.
3. Assembler: An assembler is a program that converts assembly language into machine code. It translates
mnemonic codes into their equivalent binary codes. The choice of language processor depends on the
programming language used and the specific requirements of the application being developed.
This Note Is Uploaded to BSC CS Calicut University Study Notes
Compiler vs interpreter
A compiler and an interpreter are two types of language processors used in programming.
A compiler is a program that converts the entire source code into machine code in one go. It checks for syntax
errors and generates an object file that can be executed. The output generated by a compiler is usually faster
than that of an interpreter because the entire code is compiled before execution.
An interpreter, on the other hand, is a program that converts high-level language to machine-level language
line by line. It first scans one line of a program or source code, checks for errors, and then executes it. The
output generated by an interpreter is usually slower than that of a compiler because each line of code has to
be interpreted before execution.
The choice between using a compiler or an interpreter depends on the specific requirements of the application
being developed. Compilers are generally used for large programs where speed is important, while interpreters
are used for smaller programs where ease of use and flexibility are more important. Some programming
languages use both compilers and interpreters depending on the specific task being performed.
Loader
In computing, a loader is a program that loads machine codes of a program into the system memory. It is one
of the essential stages in the process of starting a program. In an operating system, the loader is responsible
for loading programs into memory and preparing them for execution. The loader may also perform additional
tasks such as resolving external references and relocating code to different memory locations.
Linker
A linker is a utility program that combines several separately compiled modules into one, resolving internal
differences between them. When a program is assembled/compiled, an intermediate form is produced into
which it is necessary to incorporate libraries and any other modules supplied by the user. The linker combines
these modules and libraries to create an executable file that can be run on the target system.
In computer science, a linker is a computer program that takes one or more object files generated by a compiler
and combines them into one executable program. The linker resolves external references between object files
and libraries, assigns memory addresses to code and data sections, and generates relocation information for
use by the loader.
The process of linking is important because it allows programmers to write modular code in separate files,
which can be compiled independently and then linked together to form a complete program.
Dynamic and static linking are two methods used by a linker to combine multiple object files into a single
executable program. Static linking involves combining all necessary object files into a single executable file at
compile time. This means that all libraries and modules required by the program are included in the final
executable, making it self-contained and independent of external dependencies. Static linking can result in
larger executable files but can also provide faster startup times and better performance.
Dynamic linking, on the other hand, involves postponing the resolution of some symbols until runtime. When
the program is executed, dynamic link libraries (DLLs) or shared objects are loaded as needed. This allows
multiple programs to share common libraries, reducing memory usage and disk space requirements. Dynamic
linking can result in smaller executable files but may also lead to slower startup times due to the need to load
external libraries at runtime.
Both dynamic and static linking have their advantages and disadvantages, and the choice between them
depends on factors such as performance requirements, memory usage constraints, and compatibility with
other software components.
phases in compilation
Compilation is the process of translating a high-level programming language into machine code that can be
executed by a computer. The following is a typical breakdown of the overall task of a compiler in an
approximate sequence:
1. Lexical Analysis: This phase involves breaking up the source code into tokens, which are meaningful units
such as keywords, identifiers, and operators.
2. Syntax Analysis: This phase involves analysing the structure of the program to ensure that it conforms to
the rules of the programming language's grammar. This phase also generates an abstract syntax tree (AST) that
represents the structure of the program.
3. Semantic Analysis: This phase involves checking for semantic errors in the program, such as type mismatches
and undeclared variables.
4. Intermediate Code Generation: This phase involves generating an intermediate representation of the
program that can be optimized before being translated into machine code.
5. Code Optimization: This phase involves transforming the intermediate code to improve its efficiency and
reduce its size.
6. Code Generation: This phase involves translating the optimized intermediate code into machine code that
can be executed by a computer.
7. Symbol Table Management: This phase involves managing information about symbols used in the program,
such as variable names and function names.
8. Error Handling: Finally, error handling is performed to generate error messages if there are errors in any of
these phases.
These phases may vary depending on the specific compiler implementation and programming language being
compiled, but they provide a general overview of what happens during compilation.
Types of macros
1. Simple Macros: These are the most basic type of macros, which simply replace a single line of code with
another line of code.
2. Parameterized Macros: These macros allow you to pass parameters to the macro, which can be used to
customize the behaviour of the macro.
3. Conditional Macros: These macros allow you to define different code blocks based on certain conditions.
This can be useful for creating more flexible and adaptable code.
4. Looping Macros: These macros allow you to repeat a block of code multiple times, with different values for
each iteration.
5. Recursive Macros: These macros allow you to call the macro from within itself, allowing for more complex
and powerful functionality.
Macro Expansion
Macro expansion is the process of replacing a macro call with its corresponding code. Once a macro is defined,
the macro name can be used instead of using the entire instruction sequence again and again. When the
program is compiled or assembled, the macro processor expands each macro call in the source code by
replacing it with its corresponding code.
Macro expansion can happen at either compile-time or runtime, depending on the programming language and
implementation. In compiled languages, macro expansion always happens at compile-time. This means that
the expanded code is generated before the program is run. In interpreted languages, macro expansion may
happen at runtime, which means that the expanded code is generated as needed during program execution.
Types of parameters
There are several types of macro parameters that can be used in programming. Here are some common types:
1. Positional Parameters: These are the most basic type of macro parameters, which are passed to the macro
in a specific order. The macro processor replaces each occurrence of a positional parameter with the
corresponding argument passed to the macro.
2. Keyword Parameters: These parameters allow you to pass arguments to a macro using keywords instead of
positional order. This can make it easier to understand what each argument represents.
3. Default Parameters: These parameters allow you to specify default values for arguments that are not
explicitly passed to the macro.
This Note Is Uploaded to BSC CS Calicut University Study Notes
4. Variable-Length Parameter Lists: These parameters allow you to pass a variable number of arguments to a
macro. This can be useful when you don't know how many arguments will be needed ahead of time.
5. Type Parameters: These parameters allow you to specify the data type of an argument passed to a macro,
which can help ensure that the correct type is used.
Program Linking
When a modern program comprises several procedures or subroutines together with the main program
module, the translator (such as a compiler) will translate them all independently into distinct object modules
usually stored in the secondary memory. Execution of the program in such cases is performed by linking
together these independent object modules and loading them into the main memory. Linking of various object
modules is done by the linker. The linking process is done only once, even though the program may be
repeatedly executed. This flexibility of allocation and relocation helps efficient utilization of the main memory.
GNU linker
The GNU linker (ld) is a command-line tool that takes the names of all the object files, and possibly libraries,
to be linked as arguments. It runs on all of the same host platforms as the GNU compiler. The linker is used to
combine multiple object files into a single executable file or library file. It also has a scripting language that can
be used to exercise tighter control over the object file that is output.
Loader Schemas
There are different types of loader schemes, each with its own advantages. One such scheme is the
general loading scheme, which saves memory and makes it available for the user program as loaders are
smaller in size than assemblers. The loader replaces the assembler
absolute loading scheme, which loads a program into memory at a fixed location. This scheme is simple but
inflexible since it requires that all programs be loaded into memory at the same location.
relocating loading scheme, which allows a program to be loaded into any part of memory and still execute
correctly. This type of loader adjusts all references to memory locations in the program so that they refer to
their correct locations in memory.
Linking Loader
Linking loaders are a special system program that gathers various object modules, links them together to
produce a single executable binary program, and loads them into memory. This category of loaders leads to a
popular class of loaders called direct-linking loaders. The loaders used in these situations are usually called
linking loaders, which link the necessary library functions and symbolic references. Essentially, linking loaders
accept and link together a set of object programs and a single file to load them into the core. Similarly, linking
loaders additionally perform relocation and overcome disadvantages of other loading schemes.
Overlays
In a general computing sense, overlaying means "the process of transferring a block of program code or other
data into internal memory, replacing what is already stored". Overlaying is a programming method that allows
programs to be larger than the computer's main memory. An embedded system would normally use overlays
because of the limitation of physical memory, which is internal memory for a system-on-chip, and the lack of
virtual memory facilities.
Dynamic Linking
Dynamic linking is a technique used in computer programming to allow multiple programs to share a single
copy of a subroutine or library. For example, run-time support routines for a high-level language like C can be
shared among several executing programs using dynamic linking. With a program that allows its user to
interactively call any of the subroutines of a large mathematical and statistical library, all of the library
subroutines could potentially be needed, but only a few will actually be used in any one execution. Dynamic
linking can avoid the necessity of loading the entire library for each execution except those necessary
subroutines.
Program Relocation
Relocatable programs are designed to be relocated to execute from a storage area other than the one
designated for it at the time of its coding or translation. This is possible because relocatable programs consist
of a program and relevant information for its relocation. The information provided can be used to relocate the
program to execute from a different storage area. On the other hand, non-relocatable programs cannot be
made to execute in any area of storage other than the one designated for it at the time of its coding or
translation.
Relocation is performed by relocating loaders, which are responsible for loading and linking object modules
and performing relocation as necessary. Relocation involves adjusting addresses in an object module so that
they refer to the correct memory locations when loaded into memory. This process is essential when loading
object modules into memory at different locations than where they were originally compiled or assembled.
Compiler Classification
Compilers are classified according to the input/output, internal structure, and behaviour at runtime. Here are
some of the different types of compilers that you can use:
1. Cross compilers: A compiler that runs on one platform but generates code for another platform.
2. One-pass or multi-pass compiler: A compiler that performs analysis and translation in a single pass or
multiple passes, respectively. One-pass compilers are faster than multi-pass compilers, but multi-pass
compilers can handle larger programs.
3. Source-to-source compiler: A compiler that takes a high-level language as input and produces an output
in the same high-level language.
4. Stage compiler: A compiler that is used for compiling assembly language of a machine.
5. Just-in-time (JIT) compiler: A type of dynamic compiler that compiles code at runtime instead of a head-
of-time compilation. JIT compilers are commonly used in virtual machines to improve performance.
Each type of compiler has its own unique characteristics and advantages depending on the specific needs of
your project.
Structure Of Compiler
This Note Is Uploaded to BSC CS Calicut University Study Notes
The scanner is a phase of the compiler that allows us to group the input characters into tokens and construct
a symbol table that is used for contextual analysis of the program code in the later phase. The tokens are also
known as lexemes, which include keywords, identifiers, operators, constants, and comments. The scanner
phase is also known as lexical analysis that helps group input characters into lexical units or tokens. The output
of the lexical phase is a stream of tokens.
The parser is a phase of the compiler that helps group tokens into syntactical units. The output we get from
the parser phase is a parse tree, which is a tree representation of a program. The program structure we get
from the parser phase is defined using context-free grammars, which is defined by the following five
components:
1. A finite terminal vocabulary Vt, which is a token produced by a scanner
2. A finite set of symbols known as the non-terminal vocabulary Vn
3. A start symbol S for the grammar
4. A finite set of productions, P
5. Push down automata
Contextual checkers are used by the compiler to analyse the parse tree for context-sensitive information,
which is known as static semantics. The output of the semantic analysis phase is an annotated parse tree. The
contextual checkers are responsible for checking that the program code follows the rules of the programming
language and that it makes sense in terms of its context.
The symbol table is a data structure used by the compiler to store information about the identifiers and their
attributes encountered in the source program. The symbol table is used by the compiler in later phases for
contextual analysis of the program code. The information stored in the symbol table can be a name
encountered in the source program or an attribute.
The error handler is another important component of a compiler that helps report and rectify an error that
occurs during the execution of the source program. The error handler is responsible for detecting errors,
reporting them to the user, and recovering from them if possible.
The code optimizer is a phase of the compiler that reconstructs a parse tree to reduce the size of the tree or
to reproduce an equivalent tree that gives more efficient code. The following are some examples of code
optimization techniques:
1. Constant folding: Constant folding allows us to reduce calculation in a program code by evaluating constant
expressions at compile-time instead of run-time.
2. Loop-constant code motion: Loop-constant code motion helps reduce the calculation inside a loop by
moving invariant computations outside the loop.
3. Induction variable reduction: During the execution of a program code, most of the processing time is spent
in the body of the loops. Induction variable reduction helps in improving performance by reducing the
execution time inside a loop.
The code generator is a phase of the compiler that generates the target code from the intermediate code. The
target code can be machine code or assembly language. There are two approaches to generating target code:
1. Generate code for a specific machine: In this approach, the compiler generates code for a specific machine
architecture. This approach produces highly optimized and efficient code, but it requires a separate
compilation process for each target machine.
2. Generate code for a ‘general’ or abstract machine: In this approach, the compiler generates code for an
abstract machine that is independent of any specific hardware architecture. Then, further translators are used
to turn the abstract code into code for specific machines. This approach produces less efficient but more
portable code.
A peephole optimizer is a type of code optimizer that scans small segments of the target code to improve the
efficiency of instructions in a program code. Peephole optimization is the last phase of the compilation process,
which helps us to discard redundant instructions in the program code.
The peephole optimizer works by examining a small window of instructions, typically three to five instructions
long, and looking for patterns that can be replaced with more efficient sequences. For example, it might replace
a sequence of two or more instructions with a single instruction that performs the same operation.