Brainfuck tingkat rendah

Menulis interpreter Brainfuck (kompiler) di TurboAssembler.

Untuk mulai dengan, mari kita membangun penerjemah dalam bahasa tingkat tinggi, misalnya, dalam Pascal.

Untuk memulai, tulis sebuah program yang akan menampilkan karakter menggunakan jumlah + sebagai kode ascii sendiri.

Jadi, kita hanya perlu perintah bf + dan .

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 +++++++++++++++++++++++++++++++++++. akan menerbitkan !
(kode ascii dari simbol ! adalah 33 ).

Anda dapat memastikan bahwa program tersebut benar melalui tautan .

Selanjutnya, ganti operator dengan operator goto dan tambahkan perintah-bf - <> .

  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

Selanjutnya, mari kita tambahkan [ dan ]

Tambahkan variabel lain i_stor untuk loop braket [] .

Jika item saat ini telah berhasil melewati pemeriksaan untuk [ , muat i ke i_stor (jika item saat ini lebih besar dari nol).

Dengan memproses braket penutup ] (jika data_mem tidak sama dengan nol ) muat alamat braket pembuka [ ke i dari i_stor

  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 +++++ [> + <-] mentransfer angka 5 ke sel tetangga 0 5 0 0 0 0 0 0 0 0

ideone.com

"Hello World!" Program terlihat seperti ideone.com

Pindah ke TASM

Untuk mengatur loop, letakkan jumlah tahapan loop dalam register CX, lalu letakkan label prev: (di mana transisi akan dilakukan) di akhir stage - oleh loop perintah

 mov CX, 28h ; count of the stages of the loop prev: ; label ; do stuff loop prev ; go back to label prev 


Mari kita buat data_mem array data.
Mari kita membuat command_mem perintah array.
Isi larik data dengan 1 hingga ilustrasi sebagai elemen-elemennya.

Dalam loop, bandingkan simbol saat ini dengan simbol + dan, jika karakternya sama, tambahkan nilai sel saat ini

 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 

Perakitan (terjemahan) dilakukan oleh perintah tasm.exe bf1.asm .

Menghubungkan dilakukan dengan perintah tlink.exe bf1.obj .

Ketika eksekusi selesai, ada perintah +++ mulai dari alamat 0130, kemudian datang data array data_mem , kemudian datang variabel i sama dengan 0Ah di TurboDebugger .



Selanjutnya, tambahkan perintah-bf - <>.
Gunakan fungsi 02j dari int 21j interupsi untuk menghasilkan satu karakter.
Masukkan kode karakter dalam register DL sebelum memanggil interrupt.

  mov AH,2 mov DL, character_code int 21h 

Mari kita menulis program sepenuhnya

 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 



Siklusnya bekerja seperti ini:

jika elemen saat ini dari command-mem tidak sama + kemudian lompat ke label berikutnya: (jika tidak, lakukan + )
jika elemen saat ini dari command-mem tidak sama - lalu lompat ke label next1:
jika elemen saat ini dari command-mem tidak sama > lalu lompat ke label next2:
Jika elemen saat ini dari command-mem tidak sama < maka melompat ke label next3:
jika elemen saat ini dari command-mem tidak sama . lalu lompat ke label next4:
Setelah label next4: tambahkan indeks command_mem dan lompat ke label prev: (awal siklus)

Selanjutnya, tambahkan [ dan ]
Tambahkan variabel i_stor
Jika item saat ini telah berhasil melewati pemeriksaan untuk [ , periksa elemen data_mem saat ini untuk nol, dan, jika item saat ini sama dengan nol, melompat lebih jauh (pada label berikutnya); jika tidak memuat i ke 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: 

Dengan memproses braket penutup ] (jika data_mem tidak sama dengan nol ) muat alamat braket pembuka [ ke i dari i_stor

 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: 

Periksa kode-bf ++++ [> + <-]

 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 



Tambahkan fungsi input 3 jam interupsi 21 jam

 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 

loop selesai ketika karakter / perintah saat ini adalah '$'

 cmp DL, '$' je exit_loop 

Ubah loop ke 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 

Tambahkan arahan JUMPS .
Arahan JUMPS memungkinkan lompatan kondisional otomatis meluas di TASM. Jika target lompatan bersyarat berada di luar jangkauan, TASM mengubah lompatan menjadi pasangan lompatan / JMP lokal. Sebagai contoh:

  JE EQUAL_PLACE becomes: JNE @@A JMP EQUAL_PLACE @@A: 


Setelah semua

 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

Source: https://habr.com/ru/post/id428644/


All Articles