-
-
Save rrampage/9709c7c6110c4b2684d0e0f34ef8d3f6 to your computer and use it in GitHub Desktop.
Brainfuck in Assembly (~460 bytes)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Brainfuck interpreter | |
// as -o bf.o bf.S && ld -s -o bf bf.o && sstrip -z bf | |
.equ SYS_READ, 63 | |
.equ SYS_WRITE, 64 | |
.equ SYS_EXIT, 93 | |
.equ BUF_SIZE, 65536 | |
.equ MEM_SIZE, 65536 | |
.equ STDIN, 0 | |
.equ STDOUT, 1 | |
.bss | |
// buffer: .space BUF_SIZE | |
// memory: .space MEM_SIZE | |
.text | |
.global _start | |
_start: | |
sub sp, sp, #BUF_SIZE | |
mov x1, sp | |
mov x21, sp // x21 used for input buffer | |
sub sp, sp, #MEM_SIZE // Allocate memory on stack | |
mov x20, sp // x20 for mem_base | |
// read program from stdin | |
mov x8, #SYS_READ | |
mov x0, #STDIN | |
// adr x1, buffer | |
mov x2, #BUF_SIZE | |
svc #0 | |
mov x18, x0 // save bytes read | |
// Setup | |
// We use x19 for ptr | |
mov x19, xzr | |
// We use x20 for mem_base | |
mov x22, xzr // instruction pointer (ip) for the BF program | |
iloop: | |
cmp x22, x18 | |
b.ge exit | |
ldrb w23, [x21, x22] | |
cmp w23, #'.' | |
b.eq handle_dot | |
cmp w23, #',' | |
b.eq handle_comma | |
cmp w23, #'>' | |
b.eq handle_gt | |
cmp w23, #'<' | |
b.eq handle_lt | |
// In all below cases, we need mem[ptr] | |
ldrb w3, [x20, x19] | |
cmp w23, #'+' | |
b.eq handle_plus | |
cmp w23, #'-' | |
b.eq handle_minus | |
mov w4, #1 // Using this for bracket count matching | |
cmp w23, #'[' | |
b.eq handle_openb | |
cmp w23, #']' | |
b.eq handle_closeb | |
cont: | |
add x22, x22, #1 | |
b iloop | |
handle_dot: | |
bl putc | |
b cont | |
handle_comma: | |
bl getc | |
b cont | |
handle_gt: | |
add x19, x19, #1 | |
b cont | |
handle_lt: | |
sub x19, x19, #1 | |
b cont | |
handle_plus: | |
add w3, w3, #1 | |
strb w3, [x20, x19] | |
b cont | |
handle_minus: | |
sub w3, w3, #1 | |
strb w3, [x20, x19] | |
b cont | |
handle_openb: | |
cbnz w3, cont | |
oloop: | |
cbz w4, cont | |
add x22, x22, #1 | |
ldrb w23, [x21, x22] | |
/* | |
bcount = (prog[ip] == '[') ? bcount + 1 : bcount | |
bcount = (prog[ip] == ']') ? bcount - 1 : bcount | |
*/ | |
sub w5, w4, #1 | |
add w6, w4, #1 | |
cmp w23, #'[' | |
csel w4, w6, w4, eq | |
cmp w23, #']' | |
csel w4, w5, w4, eq | |
b oloop | |
handle_closeb: | |
cbz w3, cont | |
cloop: | |
cbz w4, cont | |
sub x22, x22, #1 | |
ldrb w23, [x21, x22] | |
/* | |
bcount = (prog[ip] == ']') ? bcount + 1 : bcount | |
bcount = (prog[ip] == '[') ? bcount - 1 : bcount | |
*/ | |
sub w5, w4, #1 | |
add w6, w4, #1 | |
cmp w23, #']' | |
csel w4, w6, w4, eq | |
cmp w23, #'[' | |
csel w4, w5, w4, eq | |
b cloop | |
putc: | |
mov x8, #SYS_WRITE | |
mov x0, #STDOUT | |
add x1, x20, x19 | |
mov x2, #1 | |
svc #0 | |
ret | |
getc: | |
mov x8, #SYS_READ | |
mov x0, #STDIN | |
add x1, x20, x19 | |
mov x2, #1 | |
svc #0 | |
ret | |
exit: | |
mov x8, #SYS_EXIT | |
svc #0 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
bf-mandelbrot.mp4
Mandelbrot running on the interpreter