How assignment work in C language?

Once allocation is done in memory,  next is all about storage (assignment). The storage is all about CPU (Microprocessor) and Memory Interface.

               The CPU stores the variables in memory. Microprocessor is also having some small memory inside, which are called registers. So most of the time the variables are  stored in external memory.

               The Microprocessor performs executing using its local memory (registers). So before asking the Microprocessor to execute some thing the data should be moved from the External Memory (Main memory) to its local memory (Registers). Since the microprocessor is having very few registers, after every execution the result should be moved back to the External memory.

              Now let us start discussing about the assignment (storage) in C language.

 char i;i = 56;

              In the above code "char i"  allocates 8 bits (1 byte) storage in memory. Where it is allocated depends on the compiler. Let us assume the compiler allocate address 1000 for the variable i.

              The 2nd line "i = 56" can be divided into two parts. Left Hand Side (LHS or lvalue) and Right Hand Side (RHS or rvalue). First the compiler converts the RHS to binary.
                                        56  ->  0111000
                      
              A Zero is added  before the binary number because 56 is positive number. Since the char data type is 8 bit integer the compiler extends the MSB 0  and convert the binary number 56 to 00111000.

              The compiler first convert this line to assembly language as follows

mov r0,56  // r0 is local memory (register)st  r0,1000

              Then the assembler converts the above assembly code to machine code and the CPU (Microprocessor) executes this. So the data is first moved to the register then only moved to the memory.

                   Since it is easy to explain, I have used 8 bit integer data type (char) for our discussion. Now let us see 16 bit and 32 bit. I have avoided using int. int may be 16 bit (TurboC or some 8 bit microcontrollers) or 32 bit (GCC). So I am using short for 16 bit and long for 32 bit.

short i;i = 56;

           Since the short data type is 16 bit integer the compiler extends the MSB 0  and convert the binary number 56 (0111000)  to 00000000 00111000. These 16 bits are stored in memory as follows.

short i;i = 56;                 

              Since the long data type is 32 bit integer the compiler extends the MSB 0  and convert the binary number 56 (0111000)  to
00000000 00000000 00000000 00111000. These 32 bits are stored in memory as follows.

             We humans use decimal number system and Microprocessors use binary number system. There is no confustion on this. But some time if the programmmer want to store binary number to memory directly, that is not possible in C language. For example if we want to the binary number  is 111000. We can write a program as show below

char i;i = 111000;

             The above program will not work as we expect

            The compiler takes the RHS as only decimal value of  "One Lakh eleven thousand" and converts it to binary and then only stores it.

            In C language binary values can not be moved directly to memory. The binary value need to be converted to decimal and give it to compiler.

            Converting a binary to decimal takes more time and difficult also. So C language supports storing binary value in an easy way.  So the C language adopted the octal number system for converting binary number and store it in memory. Converting the binary to octal is much easier than converting binary to decimal.

             Ex. (01111000)2 =(120)10 = (170)8

             Convert the 0011100 binary number to decimal number
  (0 x 128) + (1 x 64) + (1 x 32) + (1 x 16) + (1 x 8) + (0 x 4) + (0 x 2) + (0 x 1)
                                                 = (120)10

             Convert the 01111000 binary number to octal number
                         01                     111                               000
              (0 x 2) + (1 x 1)     (1 x 4) + (1 x 2) + (1 x 1)     (0 x 4 ) + (0 x 2) + (0 x 1)
                           1                                       7                                               0
                                     = (170)8

          In Initial days, 8 bit CPUs were generally used so octal number systems was popular and used to convert the binary. But this octal systems was sligtly outdated for 16bit and 32 bit systems. So C language support a different number systems for storing binary. This number systems is called "Hexa Decimal" number systems.
            
            Ex.  (01111000) 2  (01111000)2 (01111000)_2  = (120) 1 0 (120)10 (120)_10   =  (170) 8  (170)8 (170)_8   = (78) 1 6 (78)16 (78)_16

             Convert the 01111000 binary number to hexa decimal number
                                       0111                                                         1000
             (0 x 8) + (1 x 4) + (1 x 2) + (1 x 1)     (1 x 8) + (0 x 4 ) + (0 x 2) + (0 x 1)
                                           7                                                             8       
                                                       =(78)16

                         Let us put all these 3 things in  below code.

char i,j,k;
i = 120;
j = 0170; //  Added 0 in the front to inform the 
                                                              C compiler this number is Octal
k = 0x78; // Added 0x in the front to inform the
                                                              C compiler that number is Hexa Decimal.

            The above 3 variables are stored in memory as follows.

            Since it is easy to explain, I have used 8 bit integer data type (char) for our
discussion. Now let us see how 16 bit and 32 bit integers.  I have avoided using int. int may be 16 bit (TurboC or some 8 bit microcontrollers) or 32 bit (GCC). So I am using short for 16 bit and long for 32 bit.

 short i,j,k;i = 120;j = 0170; k = 0x78;

                        
     

long i,j,k;i = 120;j = 0170;  k = 0x78;

                                         
             
                   Now let us try to understand how the C language stores the negative value on the memory.

char i;i = -5

                           Let us start from RHS or rvalue.
                                               RHS = =5

                                   Binary of 5 = 101.
                          C language store the twos complement of 101

                              binary number –  101
                       One's complement –  010
                       Two's complement –  010 + 1 = 011

                       Since it is the negative number 1 is added before 011.
                       So the binary value of -5 = 1011.

                  Now let see the LHS or lvaue. The LHS is variable "i"  which is a 8 bit integer (char). So the 1011 is extended to 11111011. Since the last bit was 1 that was
extended to all the remaining 4 bits.

                       Now let us try the same method for 16 bit and 32 bit.

 short i;i = -5

long i;i = -5

    So far we have seen how C languages stores Decimal, Octal, Hexa Decimal and Negative numbers.

 There is one more major type is there called "symbol". How C store the symbols

 Example Symbols – A, B C, a, b,z, $,#,&,*,0,1,9. Symbols are one letter in size. In C language  symbols are stored as shown below.

char i;i = 'A';

                    Let us start from RHS or rvalue.
                                    RHS = 'A'

                  Since this letter in between 2 single quotes the C language will treat this
as symbol. The C compiler refers the ASCII table and find the binary value for 'A'. Refer ASCII table for other symbols.

                       The binary value of symbol 'A' is 01000001

                            So 01000001 is stored in Memory

               Now let us try the same method for 16 bit and 32 bit.

short i;i = 'A';

long i;i = 'A';

                     Support while assigning the RHS to LHS, if the number of bits in RHS is more than the allocated bits in LHS, the C compiler truncate the extra bits in the MSB side. Let us try to understand this through an example.

char i;i = 300;
                                           
                    In the above code RHS is "300". The binary of the 300 is 100101100, which is having 9 bits . But the LHS variable "i" is allocated only 8 bits in memory. So the compiler will store only "00101100" in memory which is nothing but 44 in decimal.

How assignment work in C language?

Advertisements

Leave a comment

Filed under Life

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s