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