An allocating place of the function and a variable can be designated specifically by adding the __near or __far type qualifier when a function or variable declared.
A declaration without __near or __far is handled according to the default __near and __far determined by the memory model. |
Address range 0x0F0000 to 0x0FFFFF for RAM data and ROM data. |
|
Address range 0x000000 to 0x0FFFFF for all RAM data, ROM data, and functions. |
|
__near and __far are added as type qualifiers. Explicitly specifying __near or __far for a variable or function declaration gives the compiler a direction regarding the allocation area. |
__near and __far indicate that the variables and functions qualified by them are allocated to the following areas. |
Explicit __near and __far specified in the source code take priority over the related option settings. |
For the internal representation of the pointer (2 bytes) pointing to the near area and that (4 bytes) pointing to the far area, see the "Pointer type" description. |
Extension from a pointer pointing to the near area to a pointer pointing to the far area is basically done as follows. |
The third byte from the least significant is set to 0x00. The most significant byte is undefined. |
|
The third byte from the least significant is set to 0x0f. The most significant byte is undefined. |
For details of general cast specifications including integer types, see the "Cast" description.
The internal representation of a null pointer constant (NULL) is 0, both for a function pointer and a variable pointer. |
A declaration is checked from the right to the left, and when __near or __far is found between a "variable, function, or * " and the next " *, (, or left end of declaration", it is set to the __near or __far attribute for the "variable, function, or *". |
The following shows the locations of __near and __far specifications for variable declarations and their meaning. |
The following shows the locations of __near and __far specifications for function declarations and their meaning. |
void (__far func1)( ); //func1 is output to the far section (.textf) //sizeof(&func1) is 4 void __far func2( ); //func2 is output to the far section (.textf) //sizeof(&func2) is 4 |
If both __near and __far are specified for declaration of a single variable or function, an error will occur. |
Relationship with keywords and #pragma |
Cast involving a near pointer or a far pointer is handled as follows.
For conversion from near* to far*, 0x0f is set in the third byte from the least significant.
Note that only for NULL, both near* and far* are 0 and 0x00 is set in the third byte from the least significant.
For conversion between an integer type and a pointer type, the value is kept unchanged in principle.
After being extended to a far pointer <f>, the upper-order bytes Note (including the undefined byte in the far pointer) are extended with zero. |
The upper-order bytes Note (including the undefined byte in the far pointer) are extended with zero. |
This is applied to the most significant byte for conversion to the long type or the upper-order five bytes for conversion to the long long type. |
For conversion from near* to far*, 0x00 is set in the third byte from the least significant.
For conversion from far* to near*, the upper-order 2 bytes are truncated.
Conversion is done in the same way as variable pointers except for conversion between pointers.
When the -ansi option is specified, type conversion between a variable pointer and a function pointer will cause an error. Note that explicit type conversion generates an error as well as implicit conversion. |
When the -ansi option is not used, conversion between a variable pointer and a function pointer is done with a warning being output. |
(char __near*)(char)0x12; //0x0012 (char __near*)0x34; //0x0034 (char __far*)0x56; //0x00000056 (char __far*)(char __near*)0x78; //0x000f0078 |
typedef void(FT)(void); void func2(__near FT* f_np, unsigned int i, unsigned char ch){ (__far FT*)f_np; //0xnn00, f_np (__far FT*)i; //0xnn00, i (__far FT*)ch; //0xnn00, ch (Unsigned 2 bytes) } |
Addition to a far pointer is done only in the lower-order 2 bytes. The upper-order bytes are not changed. |
Subtraction to a far pointer is done only in the lower-order 2 bytes. The upper-order bytes are not changed. |
For subtraction between a near pointer and a far pointer, the type of the right term is cast to the type of the left term before subtraction. |
__near int i; __far int j; void func( ) { &j - &i; //OK (&j) - ((int __far *)(&i)) &i - &j; //OK (&i) - ((int __near *)(&j)) &j - (__far int*)&i; //OK } |
When the -ansi option is specified, a pointer cannot be directly compared with an integer. However, when the -ansi option is not specified, direct comparison is done with a warning being output. |
When the -ansi option is specified, a variable pointer cannot be directly compared with a function pointer. However, when the -ansi option is not specified, direct comparison is done with a warning being output. |
When the near or far specification does not match between both sides, the near pointer is cast to the far pointer. |
Equality operation (== or !=) for a far pointer is done only in the lower-order three bytes. The most significant byte does not affect the operation result. |
Relational operation for a far pointer is done only in the lower-order 2 bytes. The upper-order 2 bytes do not affect the operation result. |
This type is always set to signed int (2-byte) regardless of the operation of near and far pointers.
__near int i1; (1) __far int i2; (2) __far int *__near p1; (3) __far int *__near *__far p2; (4) __far int func1( ); (5) __far int *__near func2 ( ); (6) int (__near *__far fp1 ) ( ); (7) __far int * (__near *__near fp2 ) ( ); (8) __near int * (__far *__near fp3 ) ( ); (9) __near int * (__near *__far fp4 ) ( ); (10) |
p1 is a 4-byte type variable that points to "an int type in the far area", and the variable itself is allocated to the near area. |
p2 is a 2-byte type variable that points to [a 4-byte type in the near area, which points to "an int type in the far area"], and the variable itself is allocated to the far area. |
func1 is a function that returns "an int type", and the function itself is allocated to the far area. |
func2 is a function that returns [a 4-byte type that points to "an int type in the far area", and the function itself is allocated to the near area. |
fp1 is a 2-byte type variable that points to [a function in the near area, which returns "an int type"], and the variable itself is allocated to the far area. |