まずは、たとえばPascalなどの高水準言語でインタープリターを作成しましょう。
キックオフするには、 +の合計を独自のASCIIコードとして使用して文字を出力するプログラムを作成します。
したがって、bf-commands +と。のみが必要です。
var data_mem: array[1..10] of integer; // data array command_mem: string; // command array i: integer; // index of command array j: integer; // index of data array begin j:=1; readln(command_mem); for i:=1 to length(command_mem) do begin // in the cycle we process the string if (command_mem[i]='+') then data_mem[j]:= data_mem[j]+1; if (command_mem[i]='.') then write(chr(data_mem[j])); end; end.
bf-code +++++++++++++++++++++++++++++++++++++。 発行します!
(記号!のアスキーコードは33です )。
リンクを介してプログラムが正しいことを確認できます。
次に、 for演算子をgoto演算子に置き換え、bf-commands -<>を追加します。
LABEL prev,next; var data_mem: array[1..10] of integer; command_mem: string; i,j,k: integer; begin j:=1; i:=1; readln(command_mem); prev: if i>length(command_mem) then goto next; if (command_mem[i]='+') then data_mem[j]:= data_mem[j]+1; if (command_mem[i]='-') then data_mem[j]:= data_mem[j]-1; if (command_mem[i]='>') then j:=j+1; if (command_mem[i]='<') then j:=j-1; if (command_mem[i]='.') then write(chr(data_mem[j])); i:=i+1; goto prev; next: for k:=1 to 10 do begin write(data_mem[k]); write(' '); end; end.
ideone.com
次に、 [と]を追加しましょう
ブラケット[]ループに別の変数i_storを追加します。
現在のアイテムが[のチェックに成功した場合、 iをi_storにロードします (現在のアイテムがゼロより大きい場合)。
閉じ括弧]の処理により( data_memがゼロでない場合)開き括弧[のアドレスをi_storからiにロードします
LABEL prev,next; var data_mem: array[1..10] of integer; command_mem: string; i,j,k: integer; i_stor: integer; begin j:=1; i:=1; readln(command_mem); prev: if i>length(command_mem) then goto next; if (command_mem[i]='+') then data_mem[j]:= data_mem[j]+1; if (command_mem[i]='-') then data_mem[j]:= data_mem[j]-1; if (command_mem[i]='>') then j:=j+1; if (command_mem[i]='<') then j:=j-1; if (command_mem[i]='.') then write(chr(data_mem[j])); if (command_mem[i]='[') then begin if data_mem[j]>0 then i_stor:=i; end; if (command_mem[i]=']') then begin if data_mem[j]>0 then begin i:=i_stor; end; end; i:=i+1; goto prev; next: for k:=1 to 10 do begin write(data_mem[k]); write(' '); end; end.
bf-code +++++ [> + <-]は、数値5を隣接セルに転送します0 5 0 0 0 0 0 0 0 0
ideone.com
「Hello、World!」プログラムはideone.comのように見えます
TASMへの移行
ループを整理するには、CXレジスタにループステージの数を入れてから、コマンドループでステージの最後にラベルprev:(遷移が行われる)を入れます。
mov CX, 28h ; count of the stages of the loop prev: ; label ; do stuff loop prev ; go back to label prev
データ配列data_memを作成しましょう。
コマンド配列command_memを作成しましょう。
要素がどのように見えるかを説明するために、 1でデータ配列にコンテンツを追加します。
ループ内で 、現在のシンボルとシンボル+を比較し、文字が等しい場合は、現在のセルの値をインクリメントします
text segment ; bf1.asm assume cs:text, ds:data, ss:stk begin: mov AX,data ; set the data segment mov DS,AX mov DL, command_mem ; load the 1st command in the DL mov CX, 0Ah ; 10 stages prev: cmp DL, '+' ; the cell contains + jne next ; no, go to the label next: mov BL, 00h ; load into BL the index of data_mem inc data_mem[BX] ; yes, we increase the value in the cell by 1 (inc means increment) next: inc i ; go to the next character in the array of commands mov BL, i mov DL, command_mem [BX] loop prev mov AX, 4c00h ; terminate the program int 21h text ends data segment command_mem DB '+', '+', '+', '$' data_mem DB 1,1,1,1,1,1,1,1,1,1,'$' i DB 0 ; command_mem index data ends stk segment stack db 100h dup (0) ; reserve 256 cells stk ends end begin
組み立て(翻訳)は、コマンドtasm.exe bf1.asmによって実行されます。
リンクは、コマンドtlink.exe bf1.objで行われます。
実行が完了すると、アドレス0130から始まるコマンド+++があり、データ配列data_memが来て、 TurboDebuggerで変数iが 0Ahになります 。
![](https://habrastorage.org/webt/x4/8c/nl/x48cnlebuoswjtyt8qjveh5xira.jpeg)
次に、bf-commands -<>を追加します。
割り込みint 21hの関数02hを使用して、単一の文字を出力します。
割り込みを呼び出す前に、レジスタDLに文字コードを入れます。
mov AH,2 mov DL, character_code int 21h
完全にプログラムを書きましょう
text segment ; bf2.asm assume cs:text, ds:data, ss:stk begin: mov AX,data ; set the data segment mov DS,AX mov DL, command_mem mov CX, 0Ah prev: cmp DL, '+' jne next mov BL, j inc data_mem[BX] next: cmp DL, '-' jne next1 mov BL, j dec data_mem[BX] next1: cmp DL, '>' jne next2 inc j next2: cmp DL, '<' jne next3 dec j next3: cmp DL, '.' jne next4 mov AH,2 mov BL, j mov DL, data_mem[BX] int 21h next4: inc i mov BL, i mov DL, command_mem [BX] loop prev mov AX, 4c00h ; terminate the program int 21h text ends data segment command_mem DB '+', '>', '+', '+', '$' ; data_mem DB 0,0,0,0,0,0,0,0,0,0,'$' i DB 0 ; command_mem index j DB 0 ; data_mem index data ends stk segment stack db 100h dup (0) ; reserve 256 cells stk ends end begin
![](https://habrastorage.org/webt/ux/go/pu/uxgopu8kbhaufpbzl_sri2os1om.jpeg)
サイクルは次のように機能します。
command-memの現在の要素が+に等しくない場合、 次のラベルにジャンプします (それ以外の場合は、 +を実行します)。
command-memの現在の要素が等しくない場合-ラベルnext1にジャンプします。
command-memの現在の要素が>でない場合は、ラベルnext2にジャンプします。
command-memの現在の要素が<でない場合は、ラベルnext3にジャンプします。
command-memの現在の要素が等しくない場合。 次にラベルnext4にジャンプします。
ラベルnext4の後: command_memのインデックスをインクリメントし、ラベルprev:(サイクルの始まり)にジャンプします
次に、 [と]を追加します
変数i_storを追加します
現在のアイテムが[のチェックに成功した場合、現在のdata_mem要素のゼロをチェックし、現在のアイテムがゼロに等しい場合は、さらにジャンプします(次のラベル)。 それ以外の場合、 iをi_storにロードします
next4: cmp DL, '[' ; the cell contains [ jne next5 ; no, go to the label next5 mov BL, j mov DL, data_mem[BX] cmp DL, 00h ; yes, check current data_mem element for zero jz next5 ; if zero, jump further mov DL, i ; otherwise load i to i_stor mov i_stor, DL next5:
閉じかっこ]の処理により( data_memがゼロに等しくない場合 )開きかっこ[のアドレスをi_storからiにロードします
next5: cmp DL, ']' ; the cell contains ] jne next6 ; no, go to the label next6 mov BL, j mov DL, data_arr[BX] cmp DL, 00h ; yes, check current data_mem element for zero jz next6 ; if zero, jump further mov DL, i_stor ; otherwise load i_stor to i mov i, DL next6:
bf-code ++++ [> + <-]を確認してください
text segment ; bf3.asm assume cs:text, ds:data, ss:stk begin: mov AX,data ; set the data segment mov DS,AX mov DL, command_mem mov CX, 50h prev: cmp DL, '+' jne next mov BL, j inc data_mem[BX] next: cmp DL, '-' jne next1 mov BL, j dec data_mem[BX] next1: cmp DL, '>' jne next2 inc j next2: cmp DL, '<' jne next3 dec j next3: cmp DL, '.' jne next4 mov AH,2 mov BL, j mov DL, data_mem[BX] int 21h next4: cmp DL, '[' ; the cell contains [ jne next5 ; no, go to the label next5 mov BL, j mov DL, data_mem[BX] cmp DL, 00 ; yes, check the current data_mem element for zero jz next5 ; if zero, jump further mov DL, i ; otherwise load i to i_stor mov i_stor, DL next5: cmp DL, ']' ; the cell contains ] jne next6 ; no, go to the label next6 mov BL, j mov DL, data_mem[BX] cmp DL, 00 ; yes, check current data_mem element for zero jz next6 ; if zero, jump further mov DL, i_stor ; otherwise load i_stor to i mov i, DL next6: inc i mov BL, i mov DL, command_mem[BX] loop prev mov AX, 4c00h ; terminate the program int 21h text ends data segment command_mem DB '+','+','+','+','[','>','+','<','-',']', '$' data_mem DB 0,0,0,0,0,0,0,0,0,0,'$' i DB 0 ; command_mem index j DB 0 ; data_mem index i_stor DB 0 data ends stk segment stack db 100h dup (0) ; reserve 256 cells stk ends end begin
![](https://habrastorage.org/webt/ar/0w/49/ar0w49wleplzlbnl0k3rrrxo8-a.jpeg)
入力関数3fh割り込み21hを追加します
mov ah, 3fh ; input function mov cx, 100h ; the number of bytes you want to read from the input mov dx,OFFSET command_mem int 21h
現在の文字/コマンドが「$」になるとループが終了します
cmp DL, '$' je exit_loop
ループをjmpに変更
mov ah, 3fh ; input function mov cx, 100h ; the number of bytes you want to read from input mov dx,OFFSET command_mem int 21h mov DL, command_mem ; load the 1st command in the DL ;mov CX, 100h prev: cmp DL, '$' ; check the current command for '$' je exit_loop ; jump if the check has successfully passed
JUMPSディレクティブを追加します。
JUMPSディレクティブは、TASMでの自動条件ジャンプ拡張を有効にします。 条件付きジャンプのターゲットが範囲外の場合、TASMはジャンプをローカルジャンプ/ JMPペアに変換します。 例:
JE EQUAL_PLACE becomes: JNE @@A JMP EQUAL_PLACE @@A:
やっぱり
JUMPS ; bf4.asm text segment assume cs:text,ds:data, ss: stk begin: mov AX,data mov DS,AX ;;; mov ah, 3fh mov cx, 100h mov dx,OFFSET command_mem int 21h ;;; mov DL, command_mem ;mov CX, 100h prev: cmp DL, '$' je exit_loop cmp DL, '+' jne next mov BL, j inc data_mem[BX] next: cmp DL, '-' jne next1 mov BL, j dec data_mem[BX] next1: cmp DL, '>' jne next2 inc j next2: cmp DL, '<' jne next3 dec j next3: cmp DL, '.' jne next4 mov AH,2 mov BL, j mov DL, data_mem[BX] int 21h next4: cmp DL, '[' jne next5 mov BL, j mov DL, data_mem[BX] cmp DL, 00 jz next5 mov DL, i mov i_stor, DL next5: cmp DL, ']' jne next6 mov BL, j mov DL, data_mem[BX] cmp DL, 00 jz next6 mov DL, i_stor mov i, DL next6: inc i mov BL, i mov DL, command_mem[BX] jmp prev exit_loop: MOV AH,2 MOV DL,0Ah INT 21h mov AX, 4c00h int 21h text ends data segment command_mem DB 256h DUP('$') data_mem DB 0,0,0,0,0,0,0,0,0,0,'$' i DB 0,'$' j DB 0,'$' i_stor DB 0,'$' data ends stk segment para stack db 100h dup (0) stk ends end begin
github.com