[CALL] コマンド
Memory上にLoad済みの機械語、または実行Programを呼び出し実行します。
文法 CALL <変数名>[(<引数> [,<引数>…])]
文例 CALL ASM86(X, Y)
CALL M(ARG1$, ARG2$, ARG3$)
呼び出したい機械語SubroutineProgramや C言語などの他の実行Programは、
あらかじめMemory上にLoadまたは作成しておかねばなりません。
このためには でProgramのLOAD、
または[POKE] で機械語の直接書き込みを行います。
[SAMPLE41]実行ProgramのLoad
または を参照。
および、
[MACHINEWORD] 参照。
<変数名>には、呼び出したい機械語Subroutineの実行開始addressの、
あらかじめDEF SEGで宣言してあるBaseAddressからのOffsetが代入された
変数の名前を指定します。この変数には配列変数を用いることは出来ません。
<引数>には、機械語Subroutineに渡す変数を指定します。
引数としてはすべての型の変数を指定出来ますが、定数や式の指定は出来ません。
数値を渡すのではなく、変数のMemory上でのaddressを引き渡すためです。
CALLにより呼び出された機械語Subroutineは機械語のRET命令によりBASICに制御を返します。
引数の受け渡し方法については、[ARGUMENT]引数の受け渡し および、
[SAMPLE41]実行ProgramのLoad
または[SAMPLE42]機械語Programの書き込み[SAMPLE42]機械語Programの書き込み を参照。
[註]機械語Subroutineでの浮動小数点演算については、
8087プロセッサーとの関連について、[USR] を参照してください。
8086ASMでのProgram作成には困難がありますが、
VisualStudioでのC言語Programを使用すれば、簡単にProgram出来ますが、
Program内部での変数の扱いに8087プロセッサーについて、注意すべき点があります。
サンプル1
10 CLS
20 DIM A%(100)
30 OPEN "D:\DATA.DAT" FOR INPUT AS #2
35 DEF SEG = DEFUSER:M%=&H2000
40 I%=0
50 I%=I%+1
60 INPUT #2,A%(I%)
70 IF A%(I%) =9999 THEN 200
80 GOTO 50
100 BLOAD "D:\SORT.EXE", M%
120 B%=0
210 CALL B%(A%(0))
220 I%=0
230 I%=I%+1
240 IF A%=9999 THEB 900
250 PRINT I%,A%(I%)
260 GOTO 230
900 CLOSE #2
910 END
この例では "D:\DATA.DAT" から読み込まれた整数値DataのA%(I%)
がBLOAD された実行Program "D:\SORT.EXE" で昇順にSortされて帰ってきます。
"D:\SORT.EXE" はRET命令で終わる機械語ProgramかRET命令で終わるC言語Programです。
引数は配列A%の最初のADDRESSが渡されます。
[BLOAD][BLOAD] 命令ではBaseAddressからのOffsetとしてM%を指定します。
B%はProgramの実行開始番地のLOAD開始PointからのOffsetです。
サンプル2
10 CLS
20 DEF SEG=DEFUSER
30 MAX=&H0
40 FOR ADR=MAX TO (MAX+40)
50 READ BYTE:POKE ADR, BYTE
60 NEXT ADR
70 C%=0
80 INPUT A%,B%
90 IF A%=9999 THEN 900
100 CALL MAX(A%, B%, C%)
140 PRINT C%
150 GOTO 120
900 END
1000 DATA &H8B, &H4C, &H24, &H04 // mov ecx,dword ptr [esp+4]
1010 DATA &H66 ,&H56 // push si
1020 DATA &H8B ,&H41 ,&H04 // mov eax,dword ptr [ecx+4]
1030 &H8B ,&H11 // mov edx,dword ptr [ecx]
1040 &H8B ,&H49 ,&H08 // mov ecx,dword ptr [ecx+8]
1050 &H66 ,&H8B &H00 // mov ax,word ptr [eax]
1060 DATA &H66 ,&H8B ,&H32 //mov si,word ptr [edx]
1070 DATA &H66 ,&H3B ,&HC6 // cmp ax,si
1080 DATA &H7D ,&H03 // jge next
1090 DATA &H66 ,&H8B ,&HC6 // mov ax,si
1100 &H66 ,&H5E // next: pop si
1200 &H66 ,&H89 ,&H01 // mov word ptr [ecx],ax
1300 &HC3 // ret
1400 DATA &H90,&H90,&H90, &H90,&H90,&H90, &H90,&H90,&H90 // NOP
これを実行します。
RUN
? 100,200
200
? 100,-200
100
? 9999,0
OK
DEFUSERはMBASICWの予約語で、機械語Subroutine書き込みAreaのBaseAddressで、開始
ADDRESSの4Byte整数値です。
Userの書き込むAreaはDEFUSER以降&H1000000000=約1MBのAreaとなります。このArea内であ
れば、複数の機械語Subroutineの書き込みが出来ます。
本問ではDEFUSERからOffsetがMAXのところ、即ち、(DEFUSER+MAX)の点に書き込んでいます。
引数の対応はA%のPointerが[ECX]から4Byte、B%のPointerが4[ECX]から4Byte、
C%のPointerが8[ECX]から4Byteとなっています。CALL文の順になります。
で、この機械語ProgramはA%とB%の比較をして、
大きい方の整数値をC%に格納してBASICに帰っています。