Brainfuck de bajo nivel. Continúa ...

Parte 1
Parte II
Parte III

Creación de un traductor de idiomas brainfuck en TurboAssembler'e.

Agregue la salida de la matriz data_arr (la "cinta" de la máquina Turing) a la pantalla.

Escribamos un programa que muestre los elementos de una matriz arbitraria mediante la función de interrupción 09h 21h

.model tiny ; ascii-decoder.asm jumps .data data_arr DB 1,0,2,0,3,0,4,0,5,0,6,0,7,'$' ;  .code ORG 100h start: ;   mov AX, @data ;    mov DS,AX ;;;;;;;;;;;;;;;; MOV AH,2 ;     MOV DL,0Ah INT 21h mov dx,offset data_arr ;     mov ah,09h ;   int 21h ;;;;;;;;;; MOV AH,2 ;     MOV DL,0Ah INT 21h mov AX, 4c00h ;   int 21h end start 

En la pantalla veremos códigos ascii de elementos de la matriz data_arr DB 1,0,2,0,3,0,4,0,5,0,6,0,7, '$'



Para representar los elementos de la matriz como números, utilizaremos el operador div .

El comando div NUMBER divide el registro AX por NUMBER y coloca la parte entera de la división en AL , y el resto de la división en AH (el NUMBER puede ser un área de memoria o un registro general)

Imprime el primer y segundo elemento de la matriz

 .model tiny ; ascii-decoder.asm jumps .data data_arr DB 10,12,0,0,0,0,0,0,0,0,'$' ;  .code ORG 100h start: ;   mov AX, @data ;    mov DS,AX ;;;;;;;;;;;;;;;; MOV AH,2 ;     MOV DL,0Ah INT 21h ;mov dx,offset data_arr ;     ;mov ah,09h ;   ;int 21h ;;   sub AH, AH ;  AH mov AL, data_arr ;  mov BL, 10 ;  div BL ;   AL=,  AH= mov BX,AX add BX,3030h mov AH,2 ;     21h mov DL,BL ;    int 21h mov DL, BH ;    int 21h ;   sub AH, AH ;  AH mov AL, data_arr+1 ;  mov BL, 10 ;  div BL ;   AL=,  AH= mov BX,AX add BX,3030h mov AH,2 ;     21h mov DL,BL ;    int 21h mov DL, BH ;    int 21h ;;;;;;;;;; MOV AH,2 ;     MOV DL,0Ah INT 21h mov AX, 4c00h ;   int 21h end start 

Para mostrar todos los elementos de la matriz, utilizaremos el comando de bucle .
Ponemos en el registro CX el número de medidas igual al número de elementos en la matriz y en cada medida agregaremos uno al índice de la matriz i .

 .model tiny ; ascii-decoder1.asm jumps .data data_arr DB 3,5,6,7,0,11,12,13,0,20,'$' ;  i DB 0,'$' .code ORG 100h start: ;   mov AX, @data ;    mov DS,AX ;;;;;;;;;;;;;;;; MOV AH,2 ;     MOV DL,0Ah INT 21h ;mov dx,offset data_arr ;     ;mov ah,09h ;   ;int 21h mov CX, 0Ah _prev: ;;  ; mov BL,i sub AH, AH ;  AH mov AL, data_arr[BX] ;  mov BL, 10 ;  div BL ;   AL=,  AH= mov BX,AX add BX,3030h mov AH,2 ;     21h mov DL,BL ;    int 21h mov DL, BH ;    int 21h ;    sub DL, DL int 21h ;;; sub BX,BX inc i ;   mov BL, i loop _prev ;;;;;;;;;; MOV AH,2 ;     MOV DL,0Ah INT 21h mov AX, 4c00h ;   int 21h end start 

A continuación, agregue un bucle que muestre los elementos de la matriz como números en el programa principal.

 .model tiny jumps .data str_arr DB 256h DUP('$') data_arr DB 0,0,0,0,0,0,0,0,0,0,'$' i DB 0,'$' j DB 0,'$' i_stor DB 0,'$' .code ORG 100h start: mov AX, @data mov DS,AX ;;; mov ah, 3fh mov cx, 100h mov dx,OFFSET str_arr int 21h ;;; mov DL, str_arr prev: cmp DL, 24h je exit_loop cmp DL, 2Bh jne next mov BL, j inc data_arr[BX] next: cmp DL, 2Dh jne next1 mov BL, j dec data_arr[BX] next1: cmp DL, 3Eh jne next2 inc j next2: cmp DL, 3Ch jne next3 dec j next3: cmp DL, 2Eh jne next4 mov AH,2 mov BL, j mov DL, data_arr[BX] int 21h next4: cmp DL, 5Bh jne next5 ;mov BL, j ;mov DL, data_arr[BX] ;cmp DL, 00 ;jz next5 mov DL, i mov i_stor, Dl next5: cmp DL, 5Dh jne next6 mov BL, j mov DL, data_arr[BX] cmp DL, 00 jz next6 mov DL, i_stor mov i, DL next6: inc i mov BL, i mov DL, str_arr[BX] ; loop prev jmp prev exit_loop: ;;;;;;;;;;;;;;;; MOV AH,2 ;   MOV DL,0Ah ;   INT 21h ;   ; output data_arr mov CX, 0Ah ; 10  sub AL,AL ;  AL mov i, AL ;   sub BX,BX ;  BX _prev: ; incorrect 1st element sub AH, AH ;  AH mov AL, data_arr[BX] ;  ;mov AL, data_arr+1 mov BL, 10 ;  div BL ;  AL=  AH= mov BX,AX add BX,3030h mov AH,2 ;   2  21h mov DL,BL ;   int 21h mov DL, BH ;   int 21h ;   ( ) sub DL, DL int 21h ;;; sub BX,BX inc i ;    mov BL, i loop _prev ;;;;;;;;;; MOV AH,2 ;   MOV DL,0Ah ;   INT 21h ;   mov AX, 4c00h ;   int 21h end start 

HelloWorld ahora se ve así



Como no procesamos números mayores que 99 , el número 100 se muestra incorrectamente, los números restantes se muestran correctamente.

Soportes anidados


Para procesar los corchetes anidados, colocaremos los corchetes de apertura en la pila y los de cierre en la pila.

Escribiremos un programa simple para trabajar con la pila en Pascal.

 var a : array[1..10] of integer; size : integer; procedure push(c : integer); begin size := size + 1; a[size] := c; end; procedure pop; begin size := size - 1; end; begin size := 0; Push(1); writeln(a[size]); Push(2); writeln(a[size]); Push(3); writeln(a[size]); Pop(); writeln(a[size]); Pop(); writeln(a[size]); end. 

Tomó desde aquí .

Puedes consultar aquí o aquí .

Cambie el procedimiento de inserción para que cuando el tamaño sea cero, obtengamos un enlace al primer elemento.

 procedure push(c : integer); begin a[size+1] := c; size := size + 1; end; 

Agregue una "pila" al programa principal.

 Program bf5_stack; LABEL prev,next; var a : array[1..10] of integer; size : integer; data_arr:array[1..10] of integer; //   str_arr: string; //  i,j,k: integer; //     i_stor: integer; //Stack procedure push(c : integer); begin a[size+1] := c; size := size + 1; end; procedure pop; begin size := size - 1; end; {---------------------------------------------------} begin j:=1; //       i:=1; size := 0; {  } //readln(str_arr); //  //str_arr:='+++[>+++[>+<-]<-]'; // 3*3=9 str_arr:='+++[> +++[>+++[>+<-]<-] <-]'; //3^3=27; 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 Push(i); if (str_arr[i]=']') then begin Pop(); if (data_arr[j]>0) then begin i := a[size+1]; goto prev; end; end; i:=i+1; goto prev; next: for k:=1 to 10 do begin write(data_arr[k]); write(' '); end; end. 

ideone.com
Si nos encontramos con un paréntesis de apertura, simplemente colocamos su dirección en la pila, cuando nos encontramos con un paréntesis de cierre, luego extraemos su dirección de la pila, si el valor en la celda actual es más de cero, luego volvemos al paréntesis de apertura.

Un ejemplo de uso de una pila normal / "estándar" se muestra en el programa bf51_stack.pas

"Agregar" una pila al programa ensamblador principal

 .model tiny ; bf7_stack_decoder.asm jumps .data 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,'$' .code ORG 100h start: ;   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 ;sub DX,DX mov AL, i ;   push AX next5: cmp DL, 5Dh ;   ] jne next6 ; ,    next6 sub AX,AX pop AX mov BL, j mov DL, data_arr[BX] cmp DL, 00 ; ,    data_arr   jz next6 ;  ,   mov i, AL ;  i_stor   i mov BL, i mov DL, str_arr[BX] jmp prev next6: inc i ;     mov BL, i mov DL, str_arr[BX] jmp prev exit_loop: ; ascii-  MOV AH,2 ;   MOV DL,0Ah ;   INT 21h ;   ; output data_arr mov CX, 0Ah ; 10  sub AL,AL ;  AL mov i, AL ;   sub BX,BX ;  BX _prev: ; incorrect 1st element sub AH, AH ;  AH mov AL, data_arr[BX] ;  ;mov AL, data_arr+1 mov BL, 10 ;  div BL ;  AL=  AH= mov BX,AX add BX,3030h mov AH,2 ;   2  21h mov DL,BL ;   int 21h mov DL, BH ;   int 21h ;   ( ) sub DL, DL int 21h ;;; sub BX,BX inc i ;    mov BL, i loop _prev ;;;;;;;;;; MOV AH,2 ;   MOV DL,0Ah ;   INT 21h ;   ;;;;;;;;;;;;;;; mov AX, 4c00h ;   int 21h END start 



Enlace a github.

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


All Articles