Maecenas at ipsum quis massa rutrum gravida! Ut in varius orci. Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.
Phasellus sed lectus nec risus posuere rhoncus sed et ligula. Sed gravida ornare turpis vel euismod. Phasellus quis tortor non lacus sodales rutrum sit amet non est
Donec elit nulla, pulvinar nec porta sed, hendrerit eget metus. Suspendisse porttitor ligula non felis volutpat pretium? Praesent laoreet nisl a eros ultricies in lacinia


Understanding system programming has always been interesting, but never been easy. It always needs a "deep dive into" guts and interest in learn system programming.


image: visualparadox.com

Today we are starting tutorials on system programming in linux with c/c++ . Since these topics go in par with each other we shall be taking the topic from the basic concept.

The first thing we shall talk about is about low level memory mechanics so that we have the basic understanding of it.

This is important as it allows you to understand how data (boolean ,struct,int ,etc ) is represented in the memory and how everything is represented in 0s and 1s. We will become much better c and c++ programmers by understanding how things are represented in such a low level.

Lets start with the binary digit (bit) which is a very small unit of memory that can distinguish between two values. A single bit can store 0 or 1
bits and are more interesting taken in groups.

Lets take a group of 8 bits (1 byte). Consider this group to be of 8 boxes placed side by side and each box can have either a 0 or a 1.

0/1
0/1
0/1
0/1
0/1
0/1
0/1
0/1

That means that this group as a whole can distinguish between 2 to the power 8 values or 256 values.

Lets start with characters. Now we know that every single character that is printed on the screen is backed by sum number in the memory .

Lets take the example of A . When we look in the memory to see how A is represented, it is "65"
but we should not look at the number as 65 , but as the sum of powers of 2.

65 = 64 +1
65 = 2^6 + 2^0

Therefore A looks like this in the memory

0
1
0
0
0
0
0
1

Lets move to short, which is 2 byte. This mean it will be represented in the memory in 16 boxes. Lets consider the number 519. The number is represented in the memory in the following way;

0
0
0
0
0
0
1
0
0
0
0
0
0
1
1
1

2^9+ 2^2 + 2^1 + 2^0
= 512+4+2+1=519

Now consider the following number;
0
1
1
1
1
1
1
1
1
1
1
1
1
1
1
1

Individually counting the number in sum of powers of 2 will be very tedious.
When we look at this now we notice that it has a 0 followed by all 1s. This is similar to a decimal in a number starting with 0 followed by all 9. Thus adding 1 to it would give us a great big number.

So we can also view this number as a great number minus one and that number is 2^15 -1.

Normally the first number in the left indicates the sign zero for a positive number and 1 for a negative number.
Hence a seven is represented by;

0
0
0
0
0
0
0
0
0
0
0
0
0
1
1
1

Similarly we can argue that -7 should be represented by;

1
0
0
0
0
0
0
0
0
0
0
0
0
1
1
1

The magnitude is same and the left most bit has a 1,
but actually it not this way. That is because we want addition and subtraction to follow few simple rules which cannot be followed in this method of representation.



Lets consider the addition of 7 and 1 in binary.
11
-----
0111
+0001
----------------
1000

Lets see what happens when we add positive 7 and -7.

111
------------------------
00000000 00000111
10000000 00000111
------------------------
10000000 00001110

But we did not get 0 we got -14.

Therefore we have to engineer so that we represent the negative number in such a way that when we add the negative number and the positive number we get all 0s and
in this case we need 16 zeros
It is difficult to get all zeros there. Lets try getting all ones there.
Lets take this example of 15.

00000000 00001111 ...

Now we need to think what numbers must be added so that we get all 1s in the sum,

00000000 00001111
?
------------------------
11111111 11111111

Hence we need to put 0s where there are 1s and 1s where there are zeros,

00000000 00001111
111111111 11110000
------------------------
11111111 11111111

The sum we have gotten consists of all 1s and is just 1 number away from turning all the 16 bits to zero.

Now if we add 1 to the sum we get a domino effect and all the numbers become 0 and the left most bit (17th bit ) becomes 0 . But the 17th bit doesn't count as it overflows the 2 bytes.

Thus we get 1 00000000 00000000,
but the 1 doesn't count as there no space in memory
hence 00000000 00000000.

So using this principle, what we can do is take the positive 15 and invert all the zeros and 1s and then add one to it to get -15.

111111111 11110000 +1 = 11111111 11110001 which is -15.
This method is called twos compliment;

char ch = 'A' ;
short s = ch;
cout << s << endl ; // same as printf statement

output : 65

What happens here is that
ch [65] //boxes []
s[0][65]
65 is there in ch which is 1 byte, which is copied into s which is 2 byte. So the right byte has 65 and the left 1 is zero.



short s =67 ;
char ch = s;
cout << s << endl ;

output :C

Here what happens is that 67 is stored in 2 bytes like
s=[0][01000011].
When it is copied to ch only the right byte is copied as there is no space to accommodate the left byte.
Hence ch = [01000011].
This value is the binary representation of C.


Similarly if we declare the a number to be int which is 4 bytes and then equate it to a short,
the 2 left most bytes will be ignored and only the 2 bytes in the right will be copied into short.

Now lets see this case where

short s =-1; // [11111111][11111111]
int i =s; // What we expect to happen is [0][0][11111111][11111111],
but this wouldn't give us -1 so what happens is that the left most bit in short
i.e 1 is replicated throughout to all the raining bits in the left so we get
[11111111][11111111][11111111][11111111] adding 1 to this will give us 0.

Leave a Reply