関数,変数の宣言時に,__near/__far型修飾子を追加することにより,関数,変数の配置場所を明示的に指定することができます。
nearを指すポインタ(2 バイト),およびfarを指すポインタ(4 バイト)の内部表現は,ポインタ型を参照してください。 |
整数型などを含むキャスト全般の詳細については,キャストを参照してください。
空ポインタ定数(NULL)の内部表現は,「関数ポインタ」,「変数ポインタ」ともにゼロとします。 |
宣言を右から左に見て,「変数,関数,*」から次の「*,(,宣言の左端」の間に__near/__farがあれば,それを「変数,関数,*」の__near/__far属性とします。 |
変数宣言に対する__near と__farの記述位置,および意味は次のとおりとします。 |
関数宣言に対する__nearと__farの記述位置,及び意味は次のとおりとします。 |
void (__far func1)( ); //func1はfarセクション(.textf)に出力 //sizeof(&func1)は4 void __far func2( ); //func2はfarセクション(.textf)に出力 //sizeof(&func2)は4 |
キーワードおよび#pragmaとの関係 |
nearポインタおよびfarポインタを含むキャストは,次のとおりとします。
near*からfar*への変換は,下位から3バイト目に0x0fを追加します。
ただし,NULLのみnear*,far*ともに0であるため,下位から3バイト目に0x00を追加します。
変換先の型サイズに当てはまるように上位を切り捨てる。残ったバイトの値を維持して変換。変換先の型がfar*の場合は,型サイズを3バイトとして上位を切り捨て |
farポインタに拡張<f>してから,上位バイト注(farポインタの不定部分を含む)をゼロで拡張 |
near*からfar*への変換は,下位から3バイト目に0x00を追加します。
far*からnear*への変換は,上位2バイトを切り捨てます。
ポインタからポインタへの変換以外は,変数ポインタと同じとします。
オプション-ansi不使用時は,変数ポインタと関数ポインタの型変換は警告を出して変換します。 |
(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(符号なし2バイト) } |
__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 } |
オプション-ansi指定時は,ポインタと整数間で直接比較できません。しかし,オプション-ansi非指定時は,警告を出して直接比較を可能とします。 |
farポインタの関係演算は,下位2バイトのみで比較します。上位の2バイトは演算結果に影響しません。 |
nearポインタ,farポインタの演算に関わらず常にsigned int型(2バイト)とします。
__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) |