DEV Community

Rishav Saha
Rishav Saha

Posted on • Originally published at Medium on

Memory Management in OS Part-1| Abstract View of Memory, Memory Addressing, Linking and Loading|…

Memory Management in OS Part-1| Abstract View of Memory, Memory Addressing, Linking and Loading| CS-101


Photo by Gabriel Heinzer on Unsplash

Hola! CS-101 will be a new series of blogs where I will try to cover the core concepts of Computer Science from Operating Systems and databases to the theory of computation and computer networks and probably a lot more. So let’s get started-

Memory Management in Operating Systems refers to the working of RAM along with the CPU and how all the processes are allocated and deallocated. In general, there are two kinds of memory management practices:

a) Contiguous Memory Management-

b) Non-Contiguous Memory Management-

But before learning how these two kinds of memory management techniques are used, we will have to get some of our basic concepts regarding the working of the memory cleared

In this blog, we will try to get an understanding of how the memory looks logically, how addressing works, and finally how linking and loading are done

1. Abstract View of Memory

Every one of us might have encountered something called a 32-bit CPU or a 64-bit CPU. Not only CPU but we may also have heard about 32 or 64-bit software. So if we have a 32-bit CPU, it means that the CPU can request and fetch 32-bits of data from the main memory in one go. Similar is the case for a 64-bit CPU


CPU is sending the address to RAM and the RAM is sending the data present at that address location

In the case of a 32-bit CPU, the CPU will send the address to the RAM and the RAM will send the 32-bit data present at that address. Now depending upon the CPU’s architecture, whether it can fetch 32-bit or 64-bit data from the RAM, these 32-bit or 64-bit data are called words. To ease this thing, a word can be thought of as a size in bits that can be accessed by the CPU in one go. For a 32-bit RAM: 1 word=32-bit and for a 64-bit RAM: 1 word=64-bit

2. Memory Addressing

Let’s try to understand the concept of addressing through various examples.

eg 1:

Let N=number of words in memory=16

To address all these 16 words, we need 4-bits. This is because the address is in binary and 2⁴=16. So 4-bis can help us represent all those 16 words

eg 2:

Let N=256

To address all the 256 words, we need 8-bits because 2⁸=256

eg 3:

Let total memory size =4GB and 1 word = 1 Byte

As 1 word = 1 byte, the processor is an 8-bit processor (1 byte = 8 bits)

So, the number of words in memory is 4GW ( because 1 word=1 byte, W here means word)

4GW=4 x 2³⁰ words = 2³² words

So to address 2³² words, we need 32 bits.

3. Loading and Linking

After a program is compiled into Machine Language, the OS performs something called Loading and Linking. Let’s understand loading first

Loading

For a piece of code, there could be multiple modules present in it. By modules, we mean numerous functions could be present. For eg: in a code we could have a main() , func1() , func2() and many more and each of these are a module

There are two kinds of Loading:

a) Static Loading

In the case of Static Loading, we load all modules of code into memory before runtime but there are a lot of drawbacks to Static Loading

  • Memory Utilization in this case is very inefficient, It might happen that we are calling a module under an if condition and that condition is satisfied rarely, so its a bad utilization of memory
  • The size of the program will become huge if we load every module before runtime
  • We also want to perform multiprocessing but if the size of a process increases, the degree of multiprocessing will reduce

So we use Dynamic Loading

b) Dynamic Loading

Here we only load those modules which are currently needed, every other part of memory which s not needed is deallocated. Because of this though the speed of execution decreases but memory utilization is efficient.

Now let’s focus on Linking-

Linking

Suppose we have a piece of code like this

main(){ f(){
  ------ ------    
  ------ ------
  ------ }
  f();
  ------
  ------
 }
Enter fullscreen mode Exit fullscreen mode

In the part where main() is calling f() when translated into machine code., the equivalent instruction is BSA ( Branch and Save return address).

The BSA instruction enables us to call functions. BSA requires the address of where it has to start executing. So linking is binding the call function’s address in the call function. We have to fill the address parameter of the BSA with the address of the called function and BSA also stores the address where it has to return after the called function has executed completely.

There are further two kinds of Linking techniques:

a) Static Linking

In static linking, we compile both the called function and calling function at once, and instead of creating two separate Machine Level languages, we create one Machine Level Language. Here the address parameter of BSA is filled before the runtime.

Another strategy is to compile the called and calling functions separately and after both are loaded in memory, the linker will place the address of the called-in function in BSA.

Static Linking requires static loading because we need all the addresses of different functions. Though static linking is very fast it has poor memory utilization.

b) Dynamic Linking

Dynamic loading is the most used method nowadays

During the execution of the calling function when the BSA instruction is encountered, the loader is called. The loader loads the module of the called function. The linker then places the address in the BSA.

Though this method is comparatively slower than static linking but is highly efficient.


Top comments (0)