SECTION .data
fopen_errm: db "Can't open", 0x0a
fopen_errl: equ $-fopen_errm
fread_errm: db "Can't read", 0x0a
fread_errl: equ $-fread_errm
dbg_msg: db "dbg msg", 0x0a
dbg_msg_l: equ $-dbg_msg
SECTION .bss
code: resb 4096 ; reserve 4K for code
mem: resb 4096 ; reserve 4K for memory
mem_p: resw 1
curr: resw 1 ; reserve 16 bits for current index
SECTION .text
global _start
_start:
; initialise stuff
MOV word [curr], 0x00 ; start at 0
MOV word [mem_p], 0x00
; read file
open:
; open it
POP ebx ; argc
POP ebx ; arg #1 (executable name)
POP ebx ; arg #2 (filename)
MOV eax, 0x05
XOR ecx, ecx ; O_RDONLY = 0
XOR edx, edx ; mode is ignored when O_CREAT is not specified
INT 0x80
TEST eax, eax
JNS read
JMP fopen_err
; read into buffer
read:
MOV ebx, eax
MOV eax, 0x03
MOV ecx, code
MOV edx, 4096
INT 0x80
TEST eax, eax ; check for errors / EOF
JMP run_code ; if EOF, then write our buffer out.
; JS fread_err ; if read failed, we exit.
; we failed reading the file
fread_err:
MOV eax, 0x04
MOV ebx, 0x01
MOV ecx, fread_errm
MOV edx, fread_errl
INT 0x80
JMP exit
fopen_err:
MOV eax, 0x04
MOV ebx, 0x01
MOV ecx, fopen_errm
MOV edx, fopen_errl
INT 0x80
JMP exit
run_code:
loop_start:
MOVZX esi, word [curr]
CMP byte [code+esi], '+'
JE case_plus
CMP byte [code+esi], '-'
JE case_minus
CMP byte [code+esi], '>'
JE case_up
CMP byte [code+esi], '<'
JE case_down
CMP byte [code+esi], '.'
JE case_dot
CMP byte [code+esi], ','
JE case_comma
CMP byte [code+esi], '['
JE case_open
CMP byte [code+esi], ']'
JE case_close
JMP chk_loop ; was not a valid brainfuck char
case_plus:
MOVZX esi, word [mem_p]
ADD byte [mem+esi], 0x01
JMP chk_loop
case_minus:
MOVZX esi, word [mem_p]
SUB byte [mem+esi], 0x01
JMP chk_loop
case_up:
ADD word [mem_p], 0x01
JMP chk_loop
case_down:
SUB word [mem_p], 0x01
JMP chk_loop
case_dot:
MOV eax, 0x04
MOV ebx, 0x01
MOVZX esi, word [mem_p]
ADD esi, mem
MOV ecx, esi
MOV edx, 0x01
INT 0x80
JMP chk_loop
case_comma:
MOV eax, 0x03
MOV ebx, 0x01
MOVZX esi, word [mem_p]
ADD esi, mem
MOV ecx, esi
MOV edx, 0x01
INT 0x80
; flush
PUSH ecx
MOV eax, 0x03
MOV ebx, 0x01
MOV ecx, esp
MOV edx, 0x01
INT 0x80
POP ecx
case_open:
MOVZX esi, word [mem_p]
ADD esi, mem
CMP word [esi], 0x00
JE skip_loop
JMP chk_loop
skip_loop:
PUSH 0x00 ; loop depth
XOR ebp, ebp
MOV bp, word [curr]
skiploop_it:
ADD ebp, 0x01
MOV esi, ebp
ADD esi, code
CMP byte [esi], '['
JE skiploop_inc_d
CMP byte [esi], ']'
JE skiploop_dec_d
skiploop_inc_d:
ADD word [esp], 0x01
JMP skiploop_chk
skiploop_dec_d:
SUB word [esp], 0x01
CMP word [esp], 0x00
JLE skiploop_done
JMP skiploop_chk
skiploop_chk:
CMP ebp, 4096
JL skiploop_it
skiploop_done:
MOV eax, ebp
SUB ax, word [curr]
ADD word [curr], ax
ADD word [curr], 0x01
JMP chk_loop
case_close:
XOR esi, esi
MOVZX esi, word [mem_p]
ADD esi, mem
MOV eax, 0x04
MOV ebx, 0x01
MOV ecx, esi
MOV edx, 0x01
INT 0x80
SUB esi, mem
CMP byte [mem+esi], 0x00
JE chk_loop
XOR ebp, ebp
MOV bp, word [curr]
revert_loop:
SUB ebp, 0x01
MOV esi, ebp
ADD esi, code
MOV eax, 0x04
MOV ebx, 0x01
MOV ecx, esi
MOV edx, 0x01
;INT 0x80
PUSH 0x0a
MOV eax, 0x04
MOV ebx, 0x01
MOV ecx, esp
MOV edx, 0x01
INT 0x80
POP ecx
CMP byte [esi], '['
JE revert_done
revertloop_chk:
CMP ebp, 0x01
JG revert_loop
JMP chk_loop
revert_done:
MOV eax, 0x04
MOV ebx, 0x01
MOV ecx, dbg_msg
MOV edx, dbg_msg_l
;INT 0x80
MOV eax, [curr]
SUB eax, ebp
MOV word [curr], ax
chk_loop:
ADD word [curr], 0x01
CMP word [curr], 4096
JNE loop_start
exit:
MOV eax, 0x04
MOV ebx, 0x01
PUSH 0x0a
MOV ecx, esp
MOV edx, 0x01
INT 0x80
POP ecx
MOV eax, 0x01
MOV ebx, 0x00
INT 0x80
U0VDVElPTiAuZGF0YQpmb3Blbl9lcnJtOiAgICBkYgkiQ2FuJ3Qgb3BlbiIsIDB4MGEKZm9wZW5fZXJybDoJZXF1CSQtZm9wZW5fZXJybQoKZnJlYWRfZXJybToJZGIJIkNhbid0IHJlYWQiLCAweDBhCmZyZWFkX2Vycmw6CWVxdQkkLWZyZWFkX2Vycm0KCmRiZ19tc2c6CWRiCSJkYmcgbXNnIiwgMHgwYQpkYmdfbXNnX2w6CWVxdQkkLWRiZ19tc2cKClNFQ1RJT04gLmJzcwpjb2RlOglyZXNiCTQwOTYJOyByZXNlcnZlIDRLIGZvciBjb2RlCm1lbToJcmVzYgk0MDk2CTsgcmVzZXJ2ZSA0SyBmb3IgbWVtb3J5Cm1lbV9wOglyZXN3CTEKY3VycjoJcmVzdwkxCTsgcmVzZXJ2ZSAxNiBiaXRzIGZvciBjdXJyZW50IGluZGV4CgpTRUNUSU9OIC50ZXh0Cmdsb2JhbCBfc3RhcnQKCl9zdGFydDoKCTsgaW5pdGlhbGlzZSBzdHVmZgoJTU9WCXdvcmQgW2N1cnJdLCAweDAwCTsgc3RhcnQgYXQgMAoJTU9WCXdvcmQgW21lbV9wXSwgMHgwMAoKCTsgcmVhZCBmaWxlCglvcGVuOgoJCTsgb3BlbiBpdAoJCVBPUCAJZWJ4IAkJOyBhcmdjCgkJUE9QIAllYnggCQk7IGFyZyAjMSAoZXhlY3V0YWJsZSBuYW1lKQoJCVBPUCAJZWJ4IAkJOyBhcmcgIzIgKGZpbGVuYW1lKQoJCU1PViAJZWF4LCAweDA1CgkJWE9SIAllY3gsIGVjeCAJOyBPX1JET05MWSA9IDAKCQlYT1IgCWVkeCwgZWR4IAk7IG1vZGUgaXMgaWdub3JlZCB3aGVuIE9fQ1JFQVQgaXMgbm90IHNwZWNpZmllZAoJCUlOVCAJMHg4MAoKCQlURVNUIAllYXgsIGVheAoJCUpOUyAJcmVhZAoJCUpNUAlmb3Blbl9lcnIKCgk7IHJlYWQgaW50byBidWZmZXIKCXJlYWQ6CgkJTU9WIAllYngsIGVheAoJCU1PViAJZWF4LCAweDAzCgkJTU9WIAllY3gsIGNvZGUKCQlNT1YgCWVkeCwgNDA5NgoJCUlOVCAJMHg4MAoKCQlURVNUCWVheCwgZWF4IDsgY2hlY2sgZm9yIGVycm9ycyAvIEVPRgoJCUpNUCAJcnVuX2NvZGUgOyBpZiBFT0YsIHRoZW4gd3JpdGUgb3VyIGJ1ZmZlciBvdXQuCgkJOyBKUyAJZnJlYWRfZXJyIDsgaWYgcmVhZCBmYWlsZWQsIHdlIGV4aXQuCgoJOyB3ZSBmYWlsZWQgcmVhZGluZyB0aGUgZmlsZQoJZnJlYWRfZXJyOgoJCU1PVgllYXgsIDB4MDQKCQlNT1YJZWJ4LCAweDAxCgkJTU9WCWVjeCwgZnJlYWRfZXJybQoJCU1PVgllZHgsIGZyZWFkX2VycmwKCQlJTlQJMHg4MAoJCUpNUCAJZXhpdAoKCWZvcGVuX2VycjoKCQlNT1YgICAgIGVheCwgMHgwNAogICAgICAgIAlNT1YgICAgIGVieCwgMHgwMQogICAgICAgIAlNT1YgICAgIGVjeCwgZm9wZW5fZXJybQogICAgICAgIAlNT1YgICAgIGVkeCwgZm9wZW5fZXJybAogICAgICAgIAlJTlQgICAgIDB4ODAKICAgICAgICAJSk1QICAgICBleGl0CgoJcnVuX2NvZGU6CgkJbG9vcF9zdGFydDoKCQkJTU9WWlgJZXNpLCB3b3JkIFtjdXJyXQoJCQlDTVAJYnl0ZSBbY29kZStlc2ldLCAnKycKCQkJCUpFCWNhc2VfcGx1cwoKCQkJQ01QCWJ5dGUgW2NvZGUrZXNpXSwgJy0nCgkJCQlKRQljYXNlX21pbnVzCgoJCQlDTVAJYnl0ZSBbY29kZStlc2ldLCAnPicKCQkJCUpFCWNhc2VfdXAKCgkJCUNNUAlieXRlIFtjb2RlK2VzaV0sICc8JwoJCQkJSkUJY2FzZV9kb3duCgoJCQlDTVAJYnl0ZSBbY29kZStlc2ldLCAnLicKCQkJCUpFCWNhc2VfZG90CgoJCQlDTVAJYnl0ZSBbY29kZStlc2ldLCAnLCcKCQkJCUpFCWNhc2VfY29tbWEKCgkJCUNNUAlieXRlIFtjb2RlK2VzaV0sICdbJwoJCQkJSkUJY2FzZV9vcGVuCgoJCQlDTVAJYnl0ZSBbY29kZStlc2ldLCAnXScKCQkJCUpFCWNhc2VfY2xvc2UKCgkJCUpNUCAJY2hrX2xvb3AJOyB3YXMgbm90IGEgdmFsaWQgYnJhaW5mdWNrIGNoYXIKCgkJCWNhc2VfcGx1czoKCQkJCU1PVlpYCWVzaSwgd29yZCBbbWVtX3BdCgkJCQlBREQJCWJ5dGUgW21lbStlc2ldLCAweDAxCgoJCQkJSk1QIAljaGtfbG9vcAoKCQkJY2FzZV9taW51czoKCQkJCU1PVlpYCWVzaSwgd29yZCBbbWVtX3BdCgkJCQlTVUIJYnl0ZSBbbWVtK2VzaV0sIDB4MDEKCgkJCQlKTVAJY2hrX2xvb3AKCgkJCWNhc2VfdXA6CgkJCQlBREQJd29yZCBbbWVtX3BdLCAweDAxCgkJCQlKTVAgCWNoa19sb29wCgoJCQljYXNlX2Rvd246CgkJCQlTVUIJd29yZCBbbWVtX3BdLCAweDAxCgkJCQlKTVAJY2hrX2xvb3AKCgkJCWNhc2VfZG90OgoJCQkJTU9WCWVheCwgMHgwNAoJCQkJTU9WCWVieCwgMHgwMQoJCQkJTU9WWlgJZXNpLCB3b3JkIFttZW1fcF0KCQkJCUFERAllc2ksIG1lbQoJCQkJTU9WCWVjeCwgZXNpCgkJCQlNT1YJZWR4LCAweDAxCgkJCQlJTlQgCTB4ODAKCQkJCUpNUCAJY2hrX2xvb3AKCgkJCWNhc2VfY29tbWE6CgkJCQlNT1YJZWF4LCAweDAzCgkJCQlNT1YJZWJ4LCAweDAxCgkJCQlNT1ZaWAllc2ksIHdvcmQgW21lbV9wXQoJCQkJQURECWVzaSwgbWVtCgkJCQlNT1YJZWN4LCBlc2kKCQkJCU1PVgllZHgsIDB4MDEKCQkJCUlOVCAJMHg4MAoKCQkJCTsgZmx1c2gKCQkJCVBVU0gJZWN4CgkJCQlNT1YJZWF4LCAweDAzCgkJCQlNT1YJZWJ4LCAweDAxCgkJCQlNT1YJZWN4LCBlc3AKCQkJCU1PVgllZHgsIDB4MDEKCQkJCUlOVAkweDgwCgkJCQlQT1AJZWN4CgoJCQljYXNlX29wZW46CgkJCQlNT1ZaWAllc2ksIHdvcmQgW21lbV9wXQoJCQkJQURECWVzaSwgbWVtCgkJCQlDTVAJd29yZCBbZXNpXSwgMHgwMAoJCQkJCUpFIAlza2lwX2xvb3AKCQkJCUpNUAljaGtfbG9vcAoKCQkJCXNraXBfbG9vcDoKCQkJCQlQVVNICTB4MDAJOyBsb29wIGRlcHRoCgkJCQkJWE9SCWVicCwgZWJwCgkJCQkJTU9WCWJwLCB3b3JkIFtjdXJyXQoKCQkJCQlza2lwbG9vcF9pdDoKCQkJCQkJQURECWVicCwgMHgwMQoJCQkJCQlNT1YJZXNpLCBlYnAKCQkJCQkJQURECWVzaSwgY29kZQoJCQkJCQlDTVAJYnl0ZSBbZXNpXSwgJ1snCgkJCQkJCQlKRSAJc2tpcGxvb3BfaW5jX2QKCQkJCQkJQ01QCWJ5dGUgW2VzaV0sICddJwoJCQkJCQkJSkUJc2tpcGxvb3BfZGVjX2QKCgkJCQkJCXNraXBsb29wX2luY19kOgoJCQkJCQkJQURECXdvcmQgW2VzcF0sIDB4MDEKCQkJCQkJCUpNUAlza2lwbG9vcF9jaGsKCgkJCQkJCXNraXBsb29wX2RlY19kOgoJCQkJCQkJU1VCCXdvcmQgW2VzcF0sIDB4MDEKCQkJCQkJCUNNUAl3b3JkIFtlc3BdLCAweDAwCgkJCQkJCQkJSkxFIAlza2lwbG9vcF9kb25lCgkJCQkJCQlKTVAgCXNraXBsb29wX2NoawoKCQkJCQkJc2tpcGxvb3BfY2hrOgoJCQkJCQkJQ01QCWVicCwgNDA5NgoJCQkJCQkJSkwJc2tpcGxvb3BfaXQKCgkJCQkJCXNraXBsb29wX2RvbmU6CgkJCQkJICAgICAgICAJTU9WCWVheCwgZWJwCgkJCQkJCQlTVUIJYXgsIHdvcmQgW2N1cnJdCgkJCQkJCQlBREQJd29yZCBbY3Vycl0sIGF4CgkJCQkJCQlBREQJd29yZCBbY3Vycl0sIDB4MDEKCgkJCQkJCQlKTVAJY2hrX2xvb3AKCgkJCWNhc2VfY2xvc2U6CiAgICAgICAgICAgICAgICBYT1IgICAgIGVzaSwgZXNpCgkJCQlNT1ZaWAllc2ksIHdvcmQgW21lbV9wXQoJCQkJQURECWVzaSwgbWVtCgoJCQkJTU9WICAgICBlYXgsIDB4MDQKICAgICAgICAgICAgICAgIE1PViAgICAgZWJ4LCAweDAxCiAgICAgICAgICAgICAgICBNT1YgICAgIGVjeCwgZXNpCiAgICAgICAgICAgICAgICBNT1YgICAgIGVkeCwgMHgwMQogICAgICAgICAgICAgICAgSU5UICAgICAweDgwCgoJCQkJU1VCCWVzaSwgbWVtCgoKCQkJCUNNUAlieXRlIFttZW0rZXNpXSwgMHgwMAogICAgICAgICAgICAgICAgICAgIAkJCUpFIGNoa19sb29wCgoJCQkJWE9SICAgICBlYnAsIGVicAogICAgICAgICAgICAgICAgCQlNT1YgICAgIGJwLCB3b3JkIFtjdXJyXQoKCQkJCXJldmVydF9sb29wOgoJCQkJCVNVQgllYnAsIDB4MDEKCQkJCQlNT1YJZXNpLCBlYnAKCQkJCQlBREQJZXNpLCBjb2RlCgoJCQkJCU1PViAgICAgZWF4LCAweDA0CiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1PViAgICAgZWJ4LCAweDAxCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1PViAgICAgZWN4LCBlc2kKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTU9WICAgICBlZHgsIDB4MDEKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAJO0lOVCAgICAgMHg4MAoKCQkJCQlQVVNICTB4MGEKCQkJCQlNT1YgICAgIGVheCwgMHgwNAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgCU1PViAgICAgZWJ4LCAweDAxCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE1PViAgICAgZWN4LCBlc3AKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTU9WICAgICBlZHgsIDB4MDEKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgSU5UICAgICAweDgwCgkJCQkJUE9QCWVjeAoKCgoJCQkJCUNNUAlieXRlIFtlc2ldLCAnWycKCQkJCQkJSkUJICByZXZlcnRfZG9uZQoKCQkJCQlyZXZlcnRsb29wX2NoazoKCQkJCQkJQ01QCSAgZWJwLCAweDAxCgkJCQkJCQlKRwkgIHJldmVydF9sb29wCgkJCQkJCUpNUAkgIGNoa19sb29wCgoJCQkJCXJldmVydF9kb25lOgogICAgICAgICAgICAgICAgICAgIAkJCQlNT1YgICAgIGVheCwgMHgwNAogICAgICAgICAgICAgICAgICAgIAkJCQlNT1YgICAgIGVieCwgMHgwMQogICAgICAgICAgICAgICAgICAgIAkJCQlNT1YgICAgIGVjeCwgZGJnX21zZwogICAgICAgICAgICAgICAgICAgIAkJCQlNT1YgICAgIGVkeCwgZGJnX21zZ19sCiAgICAgICAgICAgICAgICAgICAgCQkJCTtJTlQgICAgIDB4ODAKCgkJCQkJCU1PVgllYXgsIFtjdXJyXQoJCQkJCQlTVUIJZWF4LCBlYnAKCQkJCQkJTU9WCXdvcmQgW2N1cnJdLCBheAoKCQkJY2hrX2xvb3A6CgkJCQlBREQJd29yZCBbY3Vycl0sIDB4MDEKCQkJCUNNUAl3b3JkIFtjdXJyXSwgNDA5NgoJCQkJSk5FCWxvb3Bfc3RhcnQKCglleGl0OgoJCU1PViAgICAgZWF4LCAweDA0CiAgICAgICAgICAgICAgICBNT1YgICAgIGVieCwgMHgwMQoJCVBVU0ggCTB4MGEKICAgICAgICAgICAgICAgIE1PViAgICAgZWN4LCBlc3AKICAgICAgICAgICAgICAgIE1PViAgICAgZWR4LCAweDAxCiAgICAgICAgICAgICAgICBJTlQgICAgIDB4ODAKCQlQT1AJZWN4CgoJCU1PVgllYXgsIDB4MDEKCQlNT1YJZWJ4LCAweDAwCgkJSU5UIAkweDgwCg==