Skip to content

Instantly share code, notes, and snippets.

@rrampage
Last active August 11, 2025 14:21
Show Gist options
  • Save rrampage/9709c7c6110c4b2684d0e0f34ef8d3f6 to your computer and use it in GitHub Desktop.
Save rrampage/9709c7c6110c4b2684d0e0f34ef8d3f6 to your computer and use it in GitHub Desktop.
Brainfuck in Assembly (~460 bytes)
// 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
@rrampage
Copy link
Author

bf-mandelbrot.mp4

Mandelbrot running on the interpreter

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment