Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ; -----------------------------------------------------
- ; Brainfuck Interpreter 86
- ;
- ; A simple Brainfuck interpreter written entirely in 8086
- ; assembler for MS-DOS 2.0+
- ;
- ; To execute a BF program, just type "BFI86 file.bf"
- ; and it will begin running immediately.
- ;
- ; Written by Graham Downey (2021)
- CPU 8086
- ORG 100h
- %define SRC_BUFF_SZ 32768
- section .text
- start:
- XOR BX, BX ; Make cmd line arguments NULL terminated
- MOV BL, [80h] ; 80h is length of cmd line arguments in PSP
- MOV BYTE [BX + 81h], 00h
- openFile:
- MOV AX, DS ; DS=ES=CS=SS
- MOV ES, AX
- MOV AL, ' ' ; Skip all spaces at start of cmd line
- MOV DI, 81h
- MOV CL, [80h] ; Max length of search loop
- INC CL ; since [80h] is length excluding CR
- XOR CH, CH
- REPZ SCASB
- JCXZ .noParameter ; No parameters passed
- MOV AX, 3D02h ; Open file read/write
- DEC DI ; DI is 1 past start of string
- MOV DX, DI
- INT 21h
- JC .openError
- MOV [hSrcFile], AX ; Store file handle
- JMP loadFile
- .noParameter:
- LEA DX, [sNoParameter] ; Show no parameters passed
- MOV AH, 09h
- INT 21h
- JMP end
- .openError:
- LEA DX, [sOpenFailed] ; Show error
- MOV AH, 09h
- INT 21h
- MOV AH, 40h ; print file name
- MOV BX, 1 ; File handle 1 is STDOUT
- MOV CX, DI ; Calculate length of filename
- DEC CX
- SUB CX, 80h
- SUB CL, [80h]
- NEG CL
- MOV DX, DI
- INT 21h
- MOV AH, 02h ; print closing quote
- MOV DL, "'"
- INT 21h
- JMP end
- loadFile:
- MOV BX, AX ; BX = file handle
- LEA DX, [sourceBuff] ; DS:DX = dest buffer
- MOV CX, SRC_BUFF_SZ ; Read source into buffer
- MOV AH, 3Fh
- INT 21h ; Read data from source file
- MOV [srcFileLen], AX ; Store length of source file
- MOV BX, AX ; Put EOF at end of source
- ADD BX, sourceBuff
- MOV [BX], BYTE 26
- JNC runProgram ; No error? Start running prog
- .readError:
- LEA DX, [sReadFailed] ; Show error
- MOV AH, 09h
- INT 21h
- JMP end
- ; ======== Main program execution ========
- runProgram:
- MOV AH, 40h ; Echo source to screen
- MOV BX, 1
- MOV CX, [srcFileLen]
- LEA DX, [sourceBuff]
- INT 21h
- MOV AH, 02h ; Send \r\n
- MOV DL, 13
- INT 21h
- MOV DL, 10
- INT 21h
- ;JMP end
- LEA DI, [bfMemory] ; Initalize BF memory buffer
- MOV CX, 30000/2
- MOV AX, 0000h
- CLD
- REP STOSW
- LEA SI, [sourceBuff-1] ; Source code ptr
- LEA DI, [bfMemory] ; BF Memory ptr
- nextCommand:
- INC SI
- MOV AL, [SI]
- CMP AL, '>'
- JE incPtr
- CMP AL, '<'
- JE decPtr
- CMP AL, '+'
- JE incData
- CMP AL, '-'
- JE decData
- CMP AL, '['
- JE loopStart
- CMP AL, ']'
- JE loopEnd
- CMP AL, ','
- JE readChar
- CMP AL, '.'
- JE writeChar
- CMP AL, 26 ; EOF
- JE end
- JMP nextCommand
- incPtr:
- INC DI
- CMP DI, bfMemEnd ; Check for buffer overrun
- JGE errMemOver
- JMP nextCommand
- decPtr:
- DEC DI
- CMP DI, bfMemory ; Check for buffer underrun
- ;JL errMemUnder
- JMP nextCommand
- incData:
- INC BYTE [DI]
- JMP nextCommand
- decData:
- DEC BYTE [DI]
- JMP nextCommand
- loopStart:
- INC BYTE [stackDepth]
- PUSH SI ; Save location in source
- PUSH DI ; Save counter for loop
- JMP nextCommand
- loopEnd:
- DEC BYTE [stackDepth]
- JB errStackUnder ; If we have more ']' than '['
- POP BX ; Get loop counter
- POP AX ; Get return address for loop
- XOR DL, DL
- CMP [BX], DL
- JZ nextCommand ; if counter is zero, loop done
- MOV SI, AX ; Counter non-zero, loop again
- PUSH SI ; Save loop start again
- PUSH BX ; Save counter address again
- JMP nextCommand
- readChar:
- MOV AH, 01h
- INT 21h
- MOV [DI], AL
- JMP nextCommand
- writeChar:
- MOV AH, 02h
- MOV DL, [DI] ; Get character to echo to stdout
- INT 21h
- JMP nextCommand
- ; ======== Error handling ========
- errMemUnder:
- LEA DX, [sMemUnder] ; Show error and exit
- MOV AH, 09h
- INT 21h
- JMP end
- errMemOver:
- LEA DX, [sMemOver] ; Show error and exit
- MOV AH, 09h
- INT 21h
- JMP end
- errStackUnder:
- LEA DX, [sStackUnder] ; Show error and exit
- MOV AH, 09h
- INT 21h
- JMP end
- end:
- MOV AX, 4C00h ; DOS quit and clean up resources
- INT 21h
- ; ======== Data Section ========
- section .data
- stackDepth: db 00h
- psFileName: dw 0000h ; Address of filename
- srcFileLen: dw 0000h ; Length of source file
- hSrcFile: dw 0000h
- sReadFailed: db "Failed to read file!", '$'
- sOpenFailed: db "Failed to open file: '", '$'
- sNoParameter: db "No file passed to interpreter!", '$'
- sMemUnder: db "Error: BF buffer underrun!", '$'
- sMemOver: db "Error: BF buffer overrun!", '$'
- sStackUnder: db "Error: Stack underrun in script!", '$'
- section .bss
- sourceBuff: resb SRC_BUFF_SZ ; source code buffer
- sourceBuffEnd:
- bfMemory: resb 30000 ; bf memory space
- bfMemEnd:
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement