Borland C++ Compiler 5.5(BCC)でマシン語ファイルを作成

その1:準備と作成方法 (その2) (HSPでMAKE)

必要な準備

BCCはこちらから入手できます。

BCCには.com形式の実行ファイルを作る機能はありません。
そのため、リンカには16ビット版のLink.exeを使用します。

16ビット版リンカはここここから入手して下さい。(自己解凍ファイル)
アーカイブを解凍したあとで、LINK.EXEをLINK16.EXEに名前変更してからBCCのBINフォルダ(通常はC:\Borland\bcc55\Bin)に入れてください。

注意点

マシン語ファイルを作成する上で注意すべき点は、変数は全て自動変数を使用して、静的なデータ(静的変数や文字列など)は使用しないことです。これは、静的なデータのアドレスが分からないため、それを使用できないからです。
他にも、標準ライブラリ(マクロやインライン展開されるものは除く)やAPIは使用出来ません。
どうしても静的なデータやAPIを使いたい場合は、それをHSP側で用意してそのアドレスを引数として渡すようにします。
ウインドウプロシージャなどのように引数を渡せない関数の場合は、HSP側でリロケート(再配置)する必要があります。その場合でも、構造体を利用してリロケートする位置を一カ所ですむようにすれば、手間を最小限に出来ます。
また、作成されるオブジェクトファイルの互換性の問題から、C++は使用できません。

作成方法

簡単なサンプルとして、渡された数値の絶対値を記憶しておき、その合計を返すマシン語ファイルを作成します。
ソースは以下の通りです。


ファイル名:absadd.c

#include <windows.h>

//いままでに渡された絶対値の合計を返す
// i      加算する値
// all    HSP側で用意した変数へのポインタ
// 戻り値 合計値

int absadd(int i,int *all)
{
        return *all+=abs(i);
}

前述の通り静的変数は使用できないので、HSP側で用意した変数を使用するようにします。abs()はライブラリ関数ですが、インライン展開されるので使用できます。
関数の型にWINAPIはつけてもつけなくてもかまいません。(ll_callfuncは両方に対応しています)
関数を複数使う場合はHSPから直接呼び出される関数を1番上に持ってきてください。

以下のバッチファイルを実行することでマシン語ファイル(拡張子 BIN)を作成できます。
LINK : warning L4055: start address not equal to 0x100 for /TINY
という警告が出ますが気にしないでください。

バッチファイルではなく、HSPを使って作成したい場合はこちら


ファイル名:MAKE.BAT
ソースのファイル名(拡張子除く)BCCのインストール先を赤字部分に設定してください。
OSが Win9x,Meの場合はバッチファイルの「プロパティ」->「メモリ」->「環境変数の初期サイズ」を1024以上にしてください。

@echo off
set file=absadd
set bccpath=c:\borland\bcc55
set path=%bccpath%\bin;%path%
bcc32 -c -O2 -I"%bccpath%\include" %file%.c
if errorlevel 1 goto error
link16 /TINY /NODEFAULTLIBRARYSEARCH /NOIGNORECASE %file%.obj,%file%.bin,nul,,,
if errorlevel 1 goto error
echo ====================作成成功=====================
goto end
:error
echo =====================エラー======================
if exist %file%.bin del %file%.bin
:end
if exist %file%.obj del %file%.obj
if "%OS%"=="Windows_NT" pause>nul

マシン語ファイルの使用例

#include "llmod.as"
#module 
#deffunc init
        ;マシン語ファイルを読み込む
        filename="absadd.bin"
        exist filename
        if strsize==-1:dialog filename+"がみつかりません。":end
        sdim func,strsize
        bload filename,func
        getptr pfunc,func

        ;HSP側で用意する変数
        getptr pAll,all
        return
#deffunc absadd int
        mref p1,0
        para=p1,pAll
        ll_callfunc para,2,pfunc
        return
#global
init

absadd -100
absadd 256
absadd -5000
mes "|-100|+|256|+|-5000|="+dllret
stop

次へ