forked from chocabloc/bf-repl
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbf.asm
159 lines (131 loc) · 2.13 KB
/
bf.asm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
section .text
global _start
BUFF_MAX_SIZE equ 0x10000
PP_BUFF_MAX_SIZE equ BUFF_MAX_SIZE * 8
PP_BUFF equ PROG_BUFF + BUFF_MAX_SIZE
CELLS equ PP_BUFF + PP_BUFF_MAX_SIZE
strWelcome: db "Brainfuck Interpreter v1.0", 10, 10
strWelcomeLen equ $-strWelcome
strPrompt: db "bf> "
strPromptLen equ $-strPrompt
_start:
xor ebp, ebp ; cell pointer
cmp qword [rsp], 1
je repl
; open file
mov rax, 2
mov rdi, [rsp + 16]
xor esi, esi
syscall
mov rdi, rax
jmp readInput
repl:
; say hello
mov rax, 1
mov rdi, 1
mov rsi, strWelcome
mov rdx, strWelcomeLen
syscall
mainLoop:
; print prompt
mov rax, 1
mov rdi, 1
mov rsi, strPrompt
mov rdx, strPromptLen
syscall
xor edi, edi
readInput:
xor eax, eax
mov rsi, PROG_BUFF
mov rdx, BUFF_MAX_SIZE
syscall
cmp rax, 1
je exit
mov r8, rax
; preprocess program
; go backwards
lea rbx, [r8 - 1]
ppLoop:
cmp byte [PROG_BUFF + rbx], ']'
jne .nst
push rbx
jmp .nnd
.nst:
cmp byte [PROG_BUFF + rbx], '['
jne .nnd
pop rsi
mov qword [PP_BUFF + rbx*8], rsi
.nnd:
dec rbx
jns ppLoop
xor ebx, ebx ; instruction pointer
mov rdx, 1 ; bytes to read/write
execLoop:
mov cl, [PROG_BUFF + rbx]
cmp cl, '>'
jne .notRight
inc bp
jmp .next
.notRight:
cmp cl, '<'
jne .notLeft
dec bp
jmp .next
.notLeft:
cmp cl, '+'
jne .notInc
inc byte [CELLS + rbp]
jmp .next
.notInc:
cmp cl, '-'
jne .notDec
dec byte [CELLS + rbp]
jmp .next
.notDec:
cmp cl, '.'
jne .notPrt
mov rax, 1
mov rdi, 1
lea rsi, [CELLS + rbp]
syscall
jmp .next
.notPrt:
cmp cl, ','
jne .notInp
xor eax, eax
xor edi, edi
lea rsi, [CELLS + rbp]
syscall
jmp .next
.notInp:
cmp cl, '['
jne .notLBR
cmp byte [CELLS + rbp], 0
jne .notZero
mov rbx, [PP_BUFF + rbx*8]
jmp .next
.notZero:
push rbx
jmp .next
.notLBR:
cmp cl, ']'
jne .next
cmp byte [CELLS + rbp], 0
je .isZero
mov rbx, [rsp]
jmp .next
.isZero:
pop rsi
.next:
inc rbx
cmp rbx, r8
jl execLoop
cmp qword [rsp], 1
je mainLoop
exit:
mov rax, 60
xor edi, edi
syscall
section .bss
PROG_BUFF:
resb 0xA0000