This blog is under construction

Sunday, 22 December 2013

Far and huge pointers

Far pointer:
Size of the far pointer is 4 bytes and it can point to 1MB of memory.
4 bytes = 32 bits

Far pointer has a 16 bit segment address and a 16 bit offset value.  Below is the declaration for far pointer
char far *ptr;

Consider, a 32 bit address is stored in far pointer.
char far *ptr = 0x82340005

Here, the 16 bit segment address is 0x8234 and offset value is 0x0005.  So, below is the segment offset pair for 0x82340005
segment:offset = 0x8234:0x0005

Let us see how to convert segment offset pair to 20-bit physical address.
Left shift the segment address by 4 bit = 0x8234 << 0x4 = 0x82340

Now, add the left shifted segment address and offset value to get 20 bit physical address.
20 bit physical address = (left shifted segment address)0x82340 + (offset)0x0005 
                                  = 0x82345

The above expression can also be written as follows:
20 bit physical address = (segment address) * (0x10) + offset value
                                    = 0x8234 * 0x10 + 0x0005
                            = 0x82340 + 0x0005 = 0x82345

Consider the following,
char far *ptr1 = 0x82300045;
char far *ptr2 = 0x82200145;

If we convert the above 32 bit addresses to 20 bit physical addressing, both of them points to same location.

But, if you check whether ptr1 equals to ptr2, the condition would fail.  Because, the whole 32 bit address would be used for comparing far pointers using == or !=.

Only offset value will be used for far pointer comparison if the conditional operator is other than ==(equal to) or !=(not equal to). (ie) >, <, >=, <=.  Huge pointer is used in order to overcome the above limitation.


  #include <stdio.h>
  int main() {
       char far *ptr1 = (char far *)0x82340015;
       char far *ptr2 = (char far *)0x82350005;
       printf("Size of far pointer is %d\n", sizeof(ptr1));
       if (ptr1 == ptr2)
              printf("ptr1 and ptr2 are same!!\n");
       else
              printf("ptr1 and ptr2 are not same!!\n");
       if (ptr1 < ptr2)
              printf("ptr1 is less than ptr2!!\n");
       else
              printf("ptr2 is less than ptr1!!\n");
       return 0;
  }



  Output:
  Size of far pointer is 4
  ptr1 and ptr2 are not same!!
  ptr2 is less than ptr1!!



Huge pointer: 
Size of huge pointer is 4 bytes and it can also point to 1 MB of data.
4 bytes = 32 bits

Below is the declaration for huge pointer.
char huge *ptr;

Huge pointer has 16 bit segment address and 16 bit offset value similar to far pointers.

But, huge pointers are normalized pointers.  Let us see how the normalization takes place from the below example.
char huge *ptr1 = 0x82300045;
char huge *ptr2 = 0x82200145;

Convert the above addresses to 20 bit addressing format.
20 bit address of 0x82300045  = 0x8230 * 0x10 + 0x0045 = 0x82345
20 bit address of 0x82200145  = 0x8220 * 0x10 + 0x0145 = 0x82345

Now, split 20 bit address into two parts.  16 bits for segment address and remaining 4 bits for offset.

20 bit address of 0x82300045 is 0x82345
Splitting 20 bit address into two parts - 0x8234(segment address):0x0005(offset value)
Then, the segment offset value pair for 0x82300045 is 0x8234:0x0005

Similarly, 20 bit address of 0x82300145 is 0x82345
Splitting 20 bit address into two parts - 0x8234(segment address):0x0005(offset value)
Then, the segment offset value for 0x82200145 is 0x8234:0x0005

So, the normalized value for 0x82300045 and 0x82200145 is 0x82340005

Now, if you check whether ptr1 is equal to ptr2, the result would be positive.  Because, the normalized value for both 0x82300045 and 0x82200145 is 0x82340005(32 bit address). The same is applicable(32 bit comparison) for other conditional operators too.

In huge pointer, most of the address part is available in segment address.  Whereas, offset has only 4 bit information(ie) offset will have any value from 0 to 0xF.  In our case, offset is 0x0005.  This resolves the limitation of far pointer.


  #include <stdio.h>
  int main() {
      char huge *ptr1 = (char huge *)0x82340015;
      char huge *ptr2 = (char huge *)0x82350005;
      printf("Size of huge pointer is %d\n", sizeof(ptr1));
      if (ptr1 == ptr2)
           printf("ptr1 and ptr2 are same!!\n");
      else
           printf("ptr1 and ptr2 are not same!!\n");
      if (ptr1 <= ptr2)
           printf("ptr1 is less than or equal to ptr2!!\n");
      else
           printf("ptr2 is less than ptr1!!\n");
      return 0;
  }



  Output:
  Size of huge pointer is 4
  ptr1 and ptr2 are not same!!
  ptr1 is less than or equal to ptr2!!



No comments:

Post a Comment