Difference between long and long pointers:
As we know by default near pointers, for example: int *p is a near pointer. The size of the near pointer is 2 bytes in the case of a 16-bit compiler. And we already know very well that the size of the compiler compiler depends on the compiler; they save only the offset address of the pointer to which it refers. An address consisting only of an offset has a range from 0 to 64 Kbytes.
Far and huge pointers:
Far and huge pointers are 4 bytes in size. They store both the segment and the offset of the address pointed to by the pointer. Then what is the difference between the two?
Far pointer limit:
We cannot change or change the segment address of a given remote address by applying any arithmetic operation to it. That is, using the arithmetic operator, we cannot move from one segment to another segment.
If you increase the far address beyond the maximum value of its offset address instead of increasing the segment address, it will repeat its offset address in a cyclic order. This is also called a wrapper, i.e. If the offset is 0xffff , and we add 1, then it is 0x0000 and similarly, if we decrease 0x0000 by 1, then it is 0xffff and remember that there is no change in the segment.
Now I'm going to compare the huge and far pointers:
1. When the far pointer increases or decreases ONLY , the pointer offset actually increases or decreases, but in the case of a huge pointer, the value of the segment and the offset changes.
Consider the following example, taken from HERE :
int main() { char far* f=(char far*)0x0000ffff; printf("%Fp",f+0x1); return 0; }
then output:
0000:0000
Changing a segment value does not change.
And in the case of huge pointers:
int main() { char huge* h=(char huge*)0x0000000f; printf("%Fp",h+0x1); return 0; }
Exit:
0001:0000
This is due to the increase operation, not only the offset value, but the segment value also changes. This means that the segment will not change in the case of Far pointers, but in the case of the huge pointer, it can move from one segment to another.
2. When relational operators are used on far pointers, only offsets are compared. In other words, relational operators will only work on far pointers if the values of the segments of the pointers being compared are the same. And in the case of a huge this will not happen, in fact, a comparison of absolute addresses is performed. Let's look at an example of a Far pointer:
int main() { char far * p=(char far*)0x12340001; char far* p1=(char far*)0x12300041; if(p==p1) printf("same"); else printf("different"); return 0; }
Output:
different
In huge pointer:
int main() { char huge * p=(char huge*)0x12340001; char huge* p1=(char huge*)0x12300041; if(p==p1) printf("same"); else printf("different"); return 0; }
Output:
same
Explanation: As we can see, the absolute address for p and p1 is 12341 ( 1234*10+1 or 1230*10+41 ), but they are not considered equal in the first case, since in the case of Far pointers only offsets are compared, i.e. it checks if 0001==0041 . This is not true.
And in the case of huge pointers, the comparison operation is performed at absolute addresses equal to.
The far pointer is never normalized, but the huge pointer is normalized. A normalized pointer is one that has as many addresses in the segment as possible, which means that the offset will never be greater than 15.
Suppose that if 0x1234:1234 , then its normalized form is 0x1357:0004 (absolute address 13574 ). The huge pointer is normalized only when some arithmetic operation is performed on it and is not standardized at the destination.
int main() { char huge* h=(char huge*)0x12341234; char huge* h1=(char huge*)0x12341234; printf("h=%Fp\nh1=%Fp",h,h1+0x1); return 0; }
Output:
h=1234:1234 h1=1357:0005
Explanation: huge pointer is not normalized in case of assignment. But if an arithmetic operation is performed on it, it will be normalized. So h is 1234:1234 and h1 is 1357:0005 , which is normalized.
4. The offset of a huge pointer is less than 16 due to normalization, and not in the case of distant pointers.
lets take an example to understand what I want to say:
int main() { char far* f=(char far*)0x0000000f; printf("%Fp",f+0x1); return 0; }
Output:
0000:0010
In the case of a huge pointer:
int main() { char huge* h=(char huge*)0x0000000f; printf("%Fp",h+0x1); return 0; } Output: 0001:0000
Explanation: as we increase the pointer by 1, it will be 0000:0010 . And as we increase the huge pointer by 1, then it will be 0001:0000 , because its offset cannot exceed 15, in other words, it will be normalized.