Bagian IBagian IIBagian IIIPada artikel ini, kita akan menulis kompiler Brainfuck di TurboAssembler
Di sini Anda dapat men-debug program bf dalam mode langkah-demi-langkah.
Pertama, kita akan menulis penerjemah dalam beberapa bahasa tingkat tinggi, misalnya, dalam Pascal.
Array 
data_arr akan mewakili memori data, string 
str_arr akan berisi perintah-perintah.
Kami akan menulis sebuah program yang menampilkan karakter yang kode ascii-nya sesuai dengan angka 
+ (jadi kita hanya perlu 
+ dan 
. Perintah)
var data_arr:array[1..10] of integer; //   str_arr: string; //  i, j: integer; //     begin j:=1; //       readln(str_arr); //  for i:=1 to length(str_arr) do begin //     if (str_arr[i]='+') then data_arr[j]:= data_arr[j]+1; if (str_arr[i]='.') then write(chr(data_arr[j])); end; end. 
kode bf ++++++++++++++++++++++++++++++++++++. akan memberi 
! (kode ascii karakter 
! adalah 33).
Program ini dapat diperiksa di online ide 
ideone.comSelanjutnya, ganti 
for loop dengan 
goto dan tambahkan perintah 
Pada akhirnya, kita akan menampilkan array 
data_arr LABEL prev,next; var data_arr:array[1..10] of integer; //   str_arr: string; //  i,j,k: integer; //     begin i:=1; j:=1; readln(str_arr); //  prev: if i>length(str_arr) then goto next; if (str_arr[i]='+') then data_arr[j]:= data_arr[j]+1; if (str_arr[i]='-') then data_arr[j]:= data_arr[j]-1; if (str_arr[i]='>') then j:=j+1; if (str_arr[i]='<') then j:=j-1; if (str_arr[i]='.') then write(chr(data_arr[j])); i:=i+1; goto prev; next: for k:=1 to 10 do begin write(data_arr[k]); write(' '); end; end. 
Kode 
akan memberikan 1 2 3 0 0 0 0 0 0 0
Kode 
akan memberi 1 2 2 0 0 0 0 0 0 0
ideone.comSelanjutnya, tambahkan 
[ dan 
]Tambahkan variabel 
i_stor lain.
Jika elemen saat ini lulus tes pada 
[ , maka kami memeriksa elemen saat ini dari array 
data_arr ke nol, dan jika elemen lebih besar dari nol, muat nilai dari variabel 
i ke 
i_stor .
Saat memproses braket penutup 
] , jika 
data_arr tidak nol, 
kami memuat alamat braket pembuka di variabel 
i dari variabel 
i_stor [Selanjutnya, buka perintah 
i: = i + 1;Jika sebelum itu nilai dari 
i_stor dimuat ke 
i (saat verifikasi 
] ), maka setelah dump kita akan berada di 
[ (kalau tidak kita akan berada di 
] )
 LABEL prev,next; var data_arr:array[1..10] of integer; //   str_arr: string; //  i,j,k: integer; //     i_stor: integer; begin j:=1; i:=1; readln(str_arr); //  prev: if i>length(str_arr) then goto next; if (str_arr[i]='+') then data_arr[j]:= data_arr[j]+1; if (str_arr[i]='-') then data_arr[j]:= data_arr[j]-1; if (str_arr[i]='>') then j:=j+1; if (str_arr[i]='<') then j:=j-1; if (str_arr[i]='.') then write(chr(data_arr[j])); if (str_arr[i]='[') then begin if data_arr[j]>0 then i_stor:=i; end; if (str_arr[i]=']') then begin if data_arr[j]>0 then begin i:=i_stor; end; end; i:=i+1; goto prev; next: for k:=1 to 10 do begin write(data_arr[k]); write(' '); end; end. 
Kode 
mentransfer angka 5 ke sel berikutnya 0 5 0 0 0 0 0 0 0 0
ideone.comKode HelloWorld terlihat seperti 
ideone.comMari kita beralih ke assembler
Untuk mengatur satu loop (loop), Anda perlu memasukkan CX register jumlah siklus dari siklus dan memberi label yang transisi akan dibuat pada akhir siklus (dengan perintah loop).
 mov CX, 28h ; -   prev: ;   ;  ;  ;   loop prev ;    prev 
Buat array perintah 
str_arr , taruh di sana 
Buat data array 
data_arr , (untuk kejelasan) letakkan di sana 1,1,1,1,1,1,1,1,1,1,1,1
Dalam satu lingkaran, bandingkan karakter saat ini dengan karakter 
dan, jika karakternya sama, tambahkan nilainya dalam sel saat ini sebesar 1.
 text segment ; bf1.asm assume cs:text, ds:data, ss:stk begin: ;   mov AX,data ;    mov DS,AX mov DL, str_arr ;   DL 1  mov CX, 0Ah ; 10  prev: cmp DL, 2Bh ;   + jne next ; ,    next mov BL, 00h ;   BL  inc data_arr[BX] ; ,      1 next: inc i ;       mov BL, i mov DL, str_arr [BX] loop prev mov AX, 4c00h ;   int 21h text ends data segment str_arr DB 2Bh,2Bh,2Bh,'$' ;  +++ data_arr DB 1,1,1,1,1,1,1,1,1,1,'$' ;  i DB 0 ;    data ends stk segment stack db 100h dup (0) ;  256  stk ends end begin 
Perakitan (terjemahan) dilakukan oleh perintah 
tasm.exe bf1.asmMenghubungkan dilakukan oleh 
tlink.exe bf1.objSetelah menjalankan program di debugger TurboDebagger, Anda dapat melihat bahwa mulai dari alamat 0130, perintahnya berada 
Berikutnya adalah array data di mana kita mengubah elemen pertama, lalu variabel 
i , yang setelah eksekusi loop menjadi sama dengan 0Ah.

Tambahkan perintah 
Untuk menghasilkan karakter tunggal menggunakan fungsi interupsi 
02j ke 21j , perlu (sebelum memanggil interupsi) untuk menempatkan kode karakter dalam register 
DL .
  mov AH,2 mov DL,   int 21h 
Kami akan menulis seluruh program
 text segment ; bf2.asm assume cs:text,ds:data, ss:stk begin: ;   mov AX,data ;    mov DS,AX mov DL, str_arr ;   DL 1  mov CX, 0Ah ; 10  prev: cmp DL, 2Bh ;   + jne next ; ,    next mov BL, j ;   BL   inc data_arr[BX] ; ,      1 next: cmp DL, 2Dh ;   - jne next1 ; ,    next1 mov BL, j dec data_arr[BX] next1: cmp DL, 3Eh ;   > jne next2 ; ,    next2 inc j ; ,      data_arr next2: cmp DL, 3Ch ;   < jne next3 ; ,    next3 dec j ; ,      data_arr next3: cmp DL, 2Eh ;   . jne next4 ; ,    next4 mov AH,2 ; ,    mov BL, j mov DL, data_arr[BX] int 21h next4: inc i ;       mov BL, i mov DL, str_arr [BX] loop prev mov AX, 4c00h ;   int 21h text ends data segment str_arr DB 2Bh,3Eh,2Bh,2Bh,'$' ;  +>++ data_arr DB 0,0,0,0,0,0,0,0,0,0,'$' ;  i DB 0, '$' ;    j DB 0, '$' ;    data ends stk segment stack db 100h dup (0) ;  256  stk ends end begin 

Loopnya bekerja seperti ini:
jika elemen 
str_arr saat ini tidak 
lalu lompat ke label 
berikutnya: (jika tidak, jalankan 
)
jika elemen 
str_arr saat ini tidak 
lalu lompat ke label 
next1:jika elemen 
str_arr saat ini tidak 
lalu lompat ke label 
next2:jika elemen 
str_arr saat ini tidak 
lalu lompat ke label 
next3:jika elemen 
str_arr saat ini tidak 
lalu lompat ke label 
next4:Setelah label 
next4: tingkatkan indeks string 
str_arr dan lompat ke awal loop - ke label 
prev:Selanjutnya, tambahkan 
[ dan 
]Tambahkan variabel 
i_stor .
Jika elemen saat ini lulus tes pada 
[ , maka kita memeriksa elemen saat ini dari array 
data_arr ke nol, dan jika elemennya nol, kita melompat lebih jauh (ke label berikutnya), jika tidak kita memuat nilai dari variabel 
i ke 
i_stor .
 next4: cmp DL, 5Bh ;   [ jne next5 ; ,    next5 mov BL, j mov DL, data_arr[BX] cmp DL, 00 ; ,    data_arr   jz next5 ;  ,   mov DL, i ;   mov i_stor, Dl ;  i_stor   i next5: 
Saat memproses braket penutup 
] , jika 
data_arr tidak nol, maka muat alamat braket pembuka dalam variabel 
i dari variabel 
i_stor [ next5: cmp DL, 5Dh ;   ] jne next6 ; ,    next6 mov BL, j mov DL, data_arr[BX] cmp DL, 00 ; ,    data_arr   jz next6 ;  ,   mov DL, i_stor ;   mov i, Dl ;  i_stor   i next6: 
Periksa kodenya 
 text segment ; bf4.asm assume cs:text, ds:data, ss:stk begin: ;   mov AX,data ;    mov DS,AX mov DL, str_arr ;   DL 1  mov CX, 50h ; 80  prev: cmp DL, 2Bh ;   + jne next ; ,    next mov BL, j ;   BL   inc data_arr[BX] ; ,      1 next: cmp DL, 2Dh ;   - jne next1 ; ,    next1 mov BL, j dec data_arr[BX] ;BX,   Bl next1: cmp DL, 3Eh ;   > jne next2 ; ,    next2 inc j ; ,      data_arr next2: cmp DL, 3Ch ;   < jne next3 ; ,    next3 dec j ; ,      data_arr next3: cmp DL, 2Eh ;   . jne next4 ; ,    next4 mov AH,2 ; ,    mov BL, j mov DL, data_arr[BX] int 21h next4: cmp DL, 5Bh ;   [ jne next5 ; ,    next5 mov BL, j mov DL, data_arr[BX] cmp DL, 00 ; ,    data_arr   jz next5 ;  ,   mov DL, i ;   mov i_stor, Dl ;  i_stor   i next5: cmp DL, 5Dh ;   ] jne next6 ; ,    next6 mov BL, j mov DL, data_arr[BX] cmp DL, 00 ; ,    data_arr   jz next6 ;  ,   mov DL, i_stor ;   mov i, Dl ;  i_stor   i next6: inc i ;     mov BL, i mov DL, str_arr[BX] loop prev ;    prev: mov AX, 4c00h ;   int 21h text ends data segment str_arr DB 2Bh,2Bh,2Bh,2Bh,5Bh, 3Eh,2Bh,3Ch,2Dh ,5Dh, '$' ;  ++++[>+<-] data_arr 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 stack db 100h dup (0) ;  256  stk ends end begin 

Tambahkan fungsi ke baris input 
3 jam interupsi 
21 jam  mov ah, 3fh ;   mov cx, 100h ; 256  mov dx,OFFSET str_arr int 21h 
Kami akan keluar dari loop setelah mencapai akhir string 
'$' .
Untuk melakukan ini, kami akan membandingkan karakter saat ini dengan karakter 
'$' cmp DL, 24h ;  '$' je exit_loop 
Ganti loop loop dengan perintah jmp.
 text segment assume cs:text,ds:data, ss: stk begin: ;   mov AX,data ;    mov DS,AX ;   mov ah, 3fh mov cx, 100h ; 256  mov dx,OFFSET str_arr int 21h ; mov DL, str_arr ;   DL 1  ;mov CX, 100h ; 256  prev: cmp DL, 24h ;    '$' je exit_loop cmp DL, 2Bh ;   + jne next ; ,    next mov BL, j ;   BL   inc data_arr[BX] ; ,      1 next: cmp DL, 2Dh ;   - jne next1 ; ,    next1 mov BL, j dec data_arr[BX] ;BX,   Bl next1: cmp DL, 3Eh ;   > jne next2 ; ,    next2 inc j ; ,      data_arr next2: cmp DL, 3Ch ;   < jne next3 ; ,    next3 dec j ; ,      data_arr next3: cmp DL, 2Eh ;   . jne next4 ; ,    next4 mov AH,2 ; ,    mov BL, j mov DL, data_arr[BX] int 21h next4: cmp DL, 5Bh ;   [ jne next5 ; ,    next5 mov BL, j mov DL, data_arr[BX] cmp DL, 00 ; ,    data_arr   jz next5 ;  ,   mov DL, i ;   mov i_stor, Dl ;  i_stor   i next5: cmp DL, 5Dh ;   ] jne next6 ; ,    next6 mov BL, j mov DL, data_arr[BX] cmp DL, 00 ; ,    data_arr   jz next6 ;  ,   mov DL, i_stor ;   mov i, Dl ;  i_stor   i ;       prev: next6: inc i ;     mov BL, i mov DL, str_arr[BX] ; loop prev ;    prev: jmp prev exit_loop: MOV AH,2 ;     MOV DL,0Ah INT 21h mov AX, 4c00h ;   int 21h text ends data segment str_arr DB 256h DUP('$') ;   256  data_arr 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) ;  256  stk ends end begin 
Selama kompilasi, kami mendapatkan kesalahan
Lompatan relatif di luar kisaran oleh 0001j byte
Faktanya adalah bahwa perintah 
je / jne hanya dapat melompat setelah beberapa baris program (setiap baris membutuhkan 1 hingga 5 byte dalam memori).

Lompat jauh ke akhir program 
je / jne tidak dapat dilakukan.
Karena itu, kami mengganti ekspresi
  cmp DL, 24h ;  '$' je exit_loop ... exit_loop: 
ekspresi
 cmp DL, 24h ;  '$' jne exit_ jmp exit_loop exit_ ... exit_loop: 
Jadi, jika karakter saat ini cocok dengan 
$ , maka pergi ke 
exit_loop: label dengan perintah 
jmp , kalau tidak kita melompati perintah 
jmp .
Perintah 
jmp dapat membuat transisi 
pendek relatif intra segmen (transisi kurang dari 128 byte, mis. IP: = IP + i8) atau 
transisi panjang relatif intra segmen (transisi kurang dari 327 byte, mis. IP: = IP + i16).
Secara default, perintah 
jmp membuat lompatan yang relatif lama, yang kami butuhkan (secara umum, Anda bisa menambahkan arahan lompatan ke awal program sebagai gantinya).
 ;jumps text segment assume cs:text,ds:data, ss: stk begin: ;   mov AX,data ;    mov DS,AX ;;; mov ah, 3fh ;   mov cx, 100h ; 256  mov dx,OFFSET str_arr int 21h ;;; mov DL, str_arr ;   DL 1  ;mov CX, 100h ; 256  prev: cmp DL, 24h ;  '$' ;je exit_loop jne l1 jmp SHORT exit_loop l1: cmp DL, 2Bh ;   + jne next ; ,    next mov BL, j ;   BL   inc data_arr[BX] ; ,      1 next: cmp DL, 2Dh ;   - jne next1 ; ,    next1 mov BL, j dec data_arr[BX] ;BX,   Bl next1: cmp DL, 3Eh ;   > jne next2 ; ,    next2 inc j ; ,      data_arr next2: cmp DL, 3Ch ;   < jne next3 ; ,    next3 dec j ; ,      data_arr next3: cmp DL, 2Eh ;   . jne next4 ; ,    next4 mov AH,2 ; ,    mov BL, j mov DL, data_arr[BX] int 21h next4: cmp DL, 5Bh ;   [ jne next5 ; ,    next5 mov BL, j mov DL, data_arr[BX] cmp DL, 00 ; ,    data_arr   jz next5 ;  ,   mov DL, i ;   mov i_stor, Dl ;  i_stor   i next5: cmp DL, 5Dh ;   ] jne next6 ; ,    next6 mov BL, j mov DL, data_arr[BX] cmp DL, 00 ; ,    data_arr   jz next6 ;  ,   mov DL, i_stor ;   mov i, Dl ;  i_stor   i ;       prev: next6: inc i ;     mov BL, i mov DL, str_arr[BX] ; loop prev ;    prev: jmp prev exit_loop: MOV AH,2 ;     MOV DL,0Ah INT 21h mov AX, 4c00h ;   int 21h text ends data segment str_arr DB 256h DUP('$') ;   256  data_arr 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) ;  256  stk ends end begin 
Tautan ke github dengan daftar program.
PS Berikut adalah 
artikel tentang cara membuat kalkulator notasi Polandia terbalik (RPN) x86.