[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[WitchTech 00291] Re: LSI-CforWitch の関数ポインタ



なるなると申します。

# 引用は、川俣さんの [WitchTech 00285] から

 > <200008120114.CCE02720.VVBNOU@piedey.co.jp>
 > From: autumn@piedey.co.jp
 > Date: Sat, 12 August 2000 01:14:39 +0900

 > ・ WonderWitchではfarアドレスに対する静的な参照はすべて機能しない
 > ・ 動的に実行時にfarポインタを得る場合は、OSから直接値をもらうか、ある
 > いは、セグメントレジスタの値を参照してアドレスのセグメント値を得なければ
 > ならない
 > ・ 上記の条件からコードセグメントを複数持つことはできない(正しい?)

ふと思い出したんですが、MS の exe2bin には、絶対アドレスを指定したバイナリ
イメージを作成する機能がありますよね。(lld も -Fc -T xxxxx でアドレスを指
定すると *たまたまかもしれませんが* 同様の振る舞いをするようです。)

このとき、先頭アドレスとして 0 を指定すれば、コード中のセグメント値は先頭
セグメントからのオフセットになります。


ということで、実行時に動的に先頭セグメントの値で補正してやれば far 関数ポ
インタ経由で他のセグメントの far 関数を呼び出すことはできるかもしれません。


以下に(疑似)コードを示します。

--foo.c
char (far *tmp_func)(int no);
char far t1(int no);

#ifdef LSI_C
unsigned int _asm_c(char *);
#define _CS _asm_c("\n\tmov\tax, cs\n");
#endif

int foo()
{
    unsigned long top;
    tmp_func = t1;

    /* 仮に先頭セグメントがコードだと仮定する */
    top = _CS;
    top <<= 16;
    tmp_func = (char (far *)(int))
    			((unsigned long) tmp_func + top);
    return (*tmp_func)(1);
}
--

--t1.a86
text2	cseg
_t1::
	retf
	end
--

本当は、補正部分はインラインアセンブラで書いたほうが簡単でしょう。

# 実機を持っていないので確認できませんが NT の debug.exe 上では上記のコー
ドで動作しました。(LSI C-86 試食版)


 > b002.bin:	b002.obj
 > 	tlink /m /c $(C0WW) b002, b002, b002, $(LIBWW)
 > 	exe2fbin b002.exe b002.bin

exe2fbin が特殊なイメージを作成しているのであれば、この方法は使えませんが、
ただのバイナリイメージなら exe2fbin のかわりに exe2bin を起動して先頭アド
レスに 0 を入力します。(lld なら -Fc -T 0)

# でも、他のセグメントの far 関数呼ぶような状況ってあるんでしょうか ?



ML Archives