far関数ポインターの使用
-
08-07-2019 - |
質問
これまでのところコンパイラ固有であることがわかっていますが、私の予想では、far指示子の配置は実際にポインタを理解している人にとって意味があるはずです。
つまり、プロセッサのメモリスペース全体を共有する2つのアプリケーションがあります。
アプリAは、アプリBに存在する関数fooを呼び出す必要があります。
関数fooのメモリ位置を知っています。
これはアプリAで機能するはずです:
typedef int (* __far MYFP)(int input);
void somefunc(void)
{
int returnvalue;
MYFP foo;
foo = (MYFP) 0xFFFFFA;
returnvalue = foo(39);
}
- __ farはtypedefの正しい場所にありますか?
- (MYFP)キャストに__farを追加する必要がありますか?
- いくつかの情報は、fooへの呼び出しを逆参照する必要がないことを示唆していますが、あなたの経験はどうですか?
-
これについて他に間違っているように見えるもの、またはこれを達成しようとするかもしれませんか?
-
これを行うためのより良い方法はありますか?
編集:
これは、Code Warriorを使用した組み込みデバイス(Freescale S12XEQデバイス)上にあります。 24ビットのメモリ空間を持つ16ビットのデバイスなので、はい、セグメント化/バンクされます。
-アダム
解決
__ farはtypedefの適切な場所にありますか?
[ChrisNのコメントに応じて編集-ありがとう]
これはANSI Cの一部ではないため、コンパイラに依存する機能です。コンパイラマニュアル<!> lt; http://www.freescale.com/files/soft_dev_tools/doc/ref_manual/CW_Compiler_HC12_RM.pdf <!> gt ;、第8章、正しく配置されました。他のコンパイラでは、順序を逆にする必要がある場合があります。ただし、2つのオプションのいずれか1つが特定のコンパイラでコンパイルされるため、これは非常に簡単に理解できるはずです。
(MYFP)キャストに__farを追加する必要がありますか
いや、それは型の一部です。
fooへの呼び出しを逆参照する必要がないことを示唆する情報もありますが、あなたの経験はどうですか?
関数ポインターは、Cでオプションで逆参照できます。次の行は両方ともまったく同じことを行うのに有効です。
foo = (MYFP)0xFFFFFA;
returnvalue = foo(39); // 1
returnvalue = (*foo)(39); // 2
これについて他に間違っていると思われるもの、またはこれを達成しようとするものはありますか?
正確に完了しました。
他のヒント
セグメント化されたメモリを使用するバイナリを作成するときに、少なくともMSの世界では__far
キーワードが使用されました。これを理解するには、8086メモリシステムを理解する必要があります。 8086はメモリをセグメントに分割し、各セグメントは64Kの長さであったため、セグメント内の各アドレスには16ビットが必要でした。住所には2つの形式があります。近くと遠くです。ニアアドレスは16ビットで、現在のセグメントへのオフセットであり、命令に応じてCS、DS、ES、SSのいずれか、ファーは32ビットで、セグメントとオフセットで構成されていました。 8086では、絶対アドレスは16 *セグメント+オフセットで、1Mbのアドレス可能な範囲を提供していました。
セグメントメモリシステムを使用しておらず、使用していないように見える場合、すべてのアドレスのビット数は同じであるため、ニア/ファーの区別は不要です。つまり、キーワードはおそらくコンパイラによって無視されます。 。
これは、私が取り組んでいるプロジェクトで動作するコードのスニペットです。 Paradigm C ++であるため、Borlandの何らかのバージョンを使用します。使用するCPUは8086クローンなので、セグメント化された20ビットメモリです。
void softSerial0SR(unsigned16);
void (__far *softHandler)(unsigned16);
私は文句なしにsoftHandlerを0に初期化します。
次に、
softHandler = softSerial0SR;
セットアップコード内。
呼び出すには、通常の関数のようにsoftHandlerを呼び出すだけです。
このコードは、実際に使用しているコードから少し調整されていることに注意してください。
両方のプログラムは同じコンパイラ/オプションでビルドされたため、同じOBIを使用しますか?
コードが正常に見えることに同意します-この場合、生成されたコードの逆アセンブリを取得し、正しく出力されたかどうかを確認します。せいぜい10個の命令しかないはずです-そして、それが機能したかどうかを確実に知ることができます。