Category: dosnear pointer and far pointer
In DoS (real mode), the address is segmented. The length of each segment is 64 KB, Which is exactly 16 bits (16 bits in binary format ).
The length of the near pointer is 16 bits, so the address range can be 64 KB. Generally, the addressing range of the near pointer is 64 KB.
The far pointer is a 32-bit pointer that contains a 16-bit base address and a 16-bit offset. The base address is multiplied by 16 and then added to the offset, (In fact, the far pointer is a 20-bit length .) The offset of 1 MB of the far pointer is obtained. Therefore, the addressing range of the far pointer is 1 MB, exceeding the capacity of a 64 K segment. For example, if the segment address of a far pointer is 0x7000 and the offset is 0x1244, the Pointer Points to the address 0x71224. if the segment address of an far pointer is 0x7122 and the offset is 0x0004, the pointer also points to the address 0x71224.
If no pointer is specified as near or far, the default value is near. Therefore, the far pointer must be explicitly specified. Far pointers work slowly because every time you access a far pointer Data Segment or program segment data exchange. In addition, the far pointer operation is also abnormal. For example, the far pointer mentioned above points to the same address, but the comparison results are different.
9. When to use the far pointer
When using the small code or small data storage mode, you cannot compile a program with a lot of code or data. Because in a 64 K segment, all code and data cannot be put down. To solve this problem, you need to specify the far function or far pointer to use this part of space (space other than 64 KB ). Many library functions are explicitly specified as far functions. Far pointers are usually used together with memory allocation functions such as farmalloc.
Far pointer is | segment address: Offset address | format
Huge pointerAlso | segment address: Offset address | format
Because each segment can be 64 KB and multiple segments can be addressable,
Therefore, this pointer has a large addressing range.
If your program code or data exceeds 64 KB
You can only use the far pointer orHuge pointer.
They are also different.
Huge pointerIt is normalized and can be compared directly. However, the computation speed is slow because it is compared after processing.
Far pointers cannot be compared directly, but since only the offset is compared, the far pointer operation speed is faster.
You can choose
I. Near (near) pointer
A near pointer is a single data segment or code segment that cannot exceed 64 KB. For data
The Data Pointer generated in micro-, small-, and mid-compilation mode is near pointer, because only
There is a data segment of no more than 64 KB. For code (that is, function pointer) pointers,
The Code pointer generated in the small and compact compilation mode is a near pointer, because only one code pointer cannot exceed
64 K bytes. This chapter only discusses data pointers.
The near pointer is a 16-bit pointer that only contains the offset of the address. To form a 32-bit
The complete address of the compiled program is generally the combination of the reverse near pointer and the segment address of the program's Data Segment
. In most cases, the segment address of the program's data segment is in the DS register,
Therefore, it is generally unnecessary to load this register. In addition, when mixed with C language
In combination, the Assembly Language always assumes that DS contains the address of the Data target.
Although the near pointer occupies the minimum space and the execution speed is the fastest, it has a strict limit.
That is, only data within 64 kB can be accessed, and only data within the data segment of the program can be accessed.
If a program is compiled in small mode, the program attempts to increment a near pointer
If the length exceeds 65,536th bytes, the near pointer is reset to 0. The following is
Example:
Char _ near * P = (char _ near *) 0 xFFFF;
P ++;
Due to this severe restriction of near pointers, all of them are in large or complex programs,
Cannot be used.
2. Far (FAR) pointer
The remote pointer does not allow the compiler to take the data segment address of the program as the segment address of the pointer,
Instead, the segment address and the offset of the pointer are directly stored in the pointer. Therefore
A needle consists of four bytes. It can point to any target in the memory and can be used for any
In the compilation mode, the remote pointer is the default data pointer only in the Compact, large, and giant modes.
Because the segment address of the remote pointer is in the pointer, anyone familiar with 80x86 assembly languages knows that
This means that the segment register needs to be reloaded every time the remote pointer is used, which obviously reduces the speed.
Degree.
Note: although a remote pointer can address any unit in the memory, it can address
The destination cannot exceed 64 KB. This is because the remote pointer is incremental or reduced.
During arithmetic operations, only the offset part is involved in the operation, while the segment address remains unchanged. Therefore,
An error occurs when the value of the remote pointer is increased or reduced to the limit of 64 K bytes. For example, char far * fp = (char far *) 0xb800ffff;
FP ++; after the pointer is added with 1, FP will point to b800: 0000, instead of the expected
C800: 0000.
In addition, the far pointer may cause some other problems during pointer comparison. Far
The pointer is represented by a pair of 16 digits such as the offset and segment address.
Memory Address, far pointer is not unique, for example, far pointer 1234: 0005, 1230: 0045,
, And 0900: 9345 indicate the actual address 12345.
It will cause a lot of trouble.
First, to facilitate comparison with the NULL pointer (0000: 0000), when
Relational operators "=" and "! = "Is used to compare the far pointer.
32-bit. Otherwise, if only the 16-bit offset is compared, any pointer whose offset is 0
All will be "null" (null) pointers, which obviously does not meet general usage requirements. However
For 32-bit comparison, the segment address and offset are not compared by 20-bit actual addresses.
Compare it with a 32-bit unsigned long integer. For the above example, assume that these pointers
These five far pointers point to the same memory
Element, but the results of the following expression operations are "false", so as to draw a wrong conclusion:
If (A = B )....
If (B = C )....
If (C = d )....
If (D = e )....
If (A = C )....
If (A = d )....
Second, when ">", "> =", "<", and "<=" Relational operators are used
During the row comparison operation, only the offset is compared, that is, it is entered according to the unsigned 16-bit integer.
Row comparison. Therefore, for the above example, the result of the following expression operation will be
"True", also came to the wrong conclusion:
If (E> d )....
If (D> C )....
If (C> B )....
If (B> )....
If (E> )....
3. Giant (huge) pointer
Only the giant pointer is the pointer mentioned in General C language textbooks.
4 bytes. A significant difference from a remote pointer is that when the increment or decrement exceeds 64 K bytes
When the parameter is specified, the giant pointer automatically modifies the base address value of the segment. Therefore, the giant pointer can not only be inside the addressing
Any region in memory, and the data target can exceed 64 KB. For example:
Char huge * HP = (char huge *) 0xb800ffff;
HP ++; after the pointer is added with 1, HP points to c800: 0000. However, giant pointers are always slow,
Because the compilation must generate a small program to perform a 32-bit addition and subtraction operation on the pointer instead of a 16-bit operation.
In additionHuge pointerIs a regular pointer. Each actual memory address has only one
Huge pointer, No errors will be generated during pointer comparison.
Iv. base pointer
As mentioned above, the giant pointer combines the advantages of near and far pointers. Near pointer
Similarly, the base pointer occupies only two bytes, which are the offset of the address. Image remote pointer
Similarly, the base pointer can be used to address any region in the memory. The segment address of the near pointer is implicitly obtained.
From the data segment of the program, the segment address of the remote pointer is taken from the pointer itself, and the segment address of the base pointer is taken
For many technical and Application Problems of the method and the base pointer, see Chapter 11th.
5. Conversion between various pointers
The far pointer can be forcibly converted to a near pointer, which is easy to use.
Reserved offset. Near pointers can also be converted to far pointers.
The segment address should be obtained in the segment register.
Far pointers sometimes need to be converted to huge pointers for comparison or
Other operations. One way is to use the following regularization function: void normalize (void far ** p ){
* P = (void far *) (long) * P ^ 0xffff000f) +
(Long) * P ^ 0x0000fff0) <12 ));
}
You can reference this article through this link: http://xpddk.bokee.com/tb. B? Diaryid = 17907924