-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathProgram.asm
193 lines (178 loc) · 4.15 KB
/
Program.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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
segment .data
enter_code_str db "Enter BrainFudge code: (press enter twice to run)",10,0
nl db 10,0
d_fmt db "%d ",0
c_fmt db "%c",0
start_curly db "{ ",0
end_curly db "}",10,0
segment .bss
buffer resb 1024
current resq 1 ; the stack wasn't working ok
left_anchor resq 1 ; ^
segment .text
global main
extern fgets
extern scanf
extern printf
extern stdin
extern malloc
main:
push rbp
mov rbp, rsp
; print_start prompt
mov rdi, enter_code_str
call printf
; fgets(buffer, 1024, stdin)
mov rdx, QWORD stdin[0]
lea rax, buffer
mov esi, 1024
mov rdi, rax
call fgets
; current = malloc(24); all values init to 0
mov edi, 24
call malloc
mov QWORD [current], rax ; current
mov QWORD [left_anchor], rax ; left_anchor
mov DWORD [rax], 0 ; val
mov DWORD [rax + 8], 0 ; left
mov DWORD [rax + 16], 0 ; right
; execute BF code in buffer
mov r15, 0 ; i = 0
code_start:
mov cl, BYTE [buffer + r15] ; cl = buffer[i]
cmp cl, 0
mov r10, QWORD [current] ; r10 = current
je code_end
cmp cl, '+' ; switch (cl)
je plus
cmp cl, '-'
je minus
cmp cl, '<'
je left
cmp cl, '>'
je right
cmp cl, '['
je l_brace
cmp cl, ']'
je r_brace
cmp cl, ','
je input
cmp cl, '.'
je output
jmp code_inc ; default: continue
plus:
add QWORD [r10], 1 ; current++
jmp code_inc
minus:
sub QWORD [r10], 1 ; current--
jmp code_inc
left:
cmp QWORD [r10 + 8], 0
je make_left
mov r10, QWORD [r10 + 8] ; current = current->left
mov QWORD [current], r10
jmp code_inc
make_left:
mov edi, 24
call malloc
mov r10, QWORD [current] ; restore r10
mov QWORD [r10 + 8], rax ; left = new
mov QWORD [current], rax ; current
mov QWORD [left_anchor], rax ; left_anchor = current
mov QWORD [rax], 0 ; val
mov QWORD [rax + 8], 0 ; left
mov QWORD [rax + 16], r10 ; right
jmp code_inc
right:
cmp QWORD [r10 + 16], 0
je make_right
mov r10, QWORD [r10 + 16] ; current = current->right
mov QWORD [current], r10
jmp code_inc
make_right:
mov edi, 24
call malloc
mov r10, QWORD [current] ; restore r10
mov QWORD [r10 + 16], rax ; right = new
mov QWORD [current], rax ; current
mov QWORD [rax], 0 ; val
mov QWORD [rax + 8], r10 ; left
mov QWORD [rax + 16], 0 ; right
jmp code_inc
l_brace:
cmp QWORD [r10], 0 ; if current == 0
jne code_inc
mov r14, 1 ; open = 1
l_brace_start:
cmp r14, 0 ; if open == 0
jle code_inc
inc r15 ; i++
mov cl, BYTE [buffer + r15] ; cl = buffer[i]
cmp cl, '[' ; switch cl
je l_brace_l
cmp cl, ']'
je l_brace_r
jmp l_brace_start
l_brace_l: ; [ -> open++
inc r14
jmp l_brace_start
l_brace_r: ; ] -> open--
dec r14
jmp l_brace_start
r_brace:
cmp QWORD [r10], 0 ; if current != 0
je code_inc
mov r14, 1 ; open = 1
r_brace_start:
cmp r14, 0 ; if open == 0
jle code_inc
dec r15 ; i--
mov cl, BYTE [buffer + r15] ; cl = buffer[i]
cmp cl, '[' ; switch cl
je r_brace_l
cmp cl, ']'
je r_brace_r
jmp r_brace_start
r_brace_l: ; [ -> open--
dec r14
jmp r_brace_start
r_brace_r: ; ] -> open++
inc r14
jmp r_brace_start
input:
mov rdi, c_fmt ; scanf("%c", current)
mov rsi, QWORD [current]
call scanf
jmp code_inc
output:
mov rdi, c_fmt ; printf("%c", current)
mov rsi, QWORD [current]
mov rsi, QWORD [rsi]
call printf
jmp code_inc
code_inc:
inc r15 ; i++
jmp code_start
code_end:
mov rax, QWORD [left_anchor] ; current = left_anchor
mov QWORD [current], rax
mov rdi, start_curly ; printf("{ ")
call printf
print_start:
mov rdi, d_fmt ; printf("%d", current->val)
mov rsi, QWORD [current]
mov rsi, QWORD [rsi]
call printf
mov r10, QWORD [current] ; fix r10
cmp QWORD [r10 + 16], 0 ; stop if current->right == NULL
je print_end
mov r10, QWORD [r10 + 16] ; current = current->right
mov QWORD [current], r10
jmp print_start
print_end:
mov rdi, end_curly ; printf("}\n")
call printf
mov rax, 0
mov rsp, rbp
pop rbp
ret