-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathprimitives.asm
467 lines (384 loc) · 6.66 KB
/
primitives.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
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
BITS 64
global _start
global emit
%include "macros.mac"
%include "math.asm"
section .text
header "b", bye
mov rax, 60 ;sys_exit
mov rdi, 0 ;exit code
syscall
header "e", emit
dpop rax
push rax
mov rax, 1 ;sys_write
mov rdi, 1 ;file descriptor
mov rsi, rsp ;buf
mov rdx, 1 ;len
syscall
pop rax
ret
header "k", key
push rax
mov rax, 0 ;sys_read
mov rdi, 0 ;file descriptor
mov rsi, rsp ;buf
mov rdx, 1 ;len
syscall
pop rcx
and rcx, 0xFF
dpush rcx
ret
header "d", dup
dpop rax
dpush rax
dpush rax
ret
header "s", swap
dpop rax
dpop rcx
dpush rax
dpush rcx
ret
header "r", rot
dpop rax
dpop rcx
dpop rsi
dpush rcx
dpush rax
dpush rsi
ret
header "D", drop
dpop rax
ret
header "'", tick
call key
dpop rcx
;check for end of file/transmision
cmp rax, 0
je .bye
mov rax, [dict]
.loop: cmp rax, 0
je .end
mov byte dil, [rax]
and dil, 0x7F
cmp cl, dil
je .end
mov rax, [rax+1]
jmp .loop
.end: dpush rax
ret
.bye: call bye
header "x", execute
dpop rax ;xt
add rax, 9 ;byte + qword
jmp rax
header ",", comma
dpop rax
mov rbx, [heapptr]
mov [rbx], rax
add qword [heapptr], 8
ret
header "@", @
dpop rax
mov rax, [rax]
dpush rax
ret
header "!", exclam
dpop rcx
dpop rax
mov [rcx], rax
ret
header "h", here
mov rax, [heapptr]
dpush rax
ret
header "c", create
call key
call comma
sub qword [heapptr], 7
mov rax, [dict]
dpush rax
call comma
mov rax, [heapptr]
sub rax, 9
mov [dict], rax
;write machine code to put address on stack at runtime
add rax, 9
;write: mov rax, body
mov word [rax], 0xB848
add rax, 2
mov rcx, rax
add rcx, 17 ;calculate body address
mov qword [rax], rcx
add rax, 8
;write: mov [rbp], rax
mov dword [rax], 0x00458948
add rax, 4
;write: add rbp, 8
mov dword [rax], 0x08C58348
add rax, 4
;write: ret
mov byte [rax], 0xC3
add qword [heapptr], 19 ;allot
ret
header "v", variable
call create
dpush 0
call comma
ret
header immediate "l", literal
dpop rcx
mov rax, [heapptr]
;write: mov rax, literal
mov word [rax], 0xB848
add rax, 2
mov [rax], rcx
add rax, 8
;write: mov qword [rbp], rax
mov dword [rax], 0x00458948
add rax, 4
;write: add rbp, 8
mov dword [rax], 0x08C58348
add rax, 4
mov [heapptr], rax
ret
header immediate "[", open_bracket
mov byte [state], 0x00
ret
header "]", close_bracket
mov byte [state], 0xFF
ret
;used to compile a word or number/literal
header immediate "p", compile
call tick
dpop rax
cmp rax, 0
jne .wrd
;check if blankspace
cmp cl, 0x0A
je .ign
cmp cl, ' '
je .ign
;check if dec number and convert
cmp rax, 0
jne .wrd
cmp rcx, '9'
ja .err
cmp rcx, '0'
jb .err
sub rcx, '0'
;compile literal
dpush rcx
call literal
ret
.wrd: ;check if immediate
mov cl, [rax]
test cl, 0x80
jnz .ex
;compile word
add rax, 9
mov rcx, [heapptr]
;write: mov rax, xt+9
mov word [rcx], 0xB848
add rcx, 2
mov [rcx], rax
add rcx, 8
;write: call rax
mov word [rcx], 0xD0FF
add rcx, 2
mov [heapptr], rcx
ret
.ex: dpush rax
call execute
ret
.ign: ret
.err: mov rax, 1 ;sys_write
mov rdi, 1 ;file descriptor
mov rsi, err ;buf
mov rdx, [errlen] ;len
syscall
ret
header ":", colon
call key
call comma
sub qword [heapptr], 7
mov rax, [dict]
dpush rax
call comma
mov rax, [heapptr]
sub rax, 9
mov [dict], rax
call close_bracket
ret
header immediate ";", semi_colon
mov rcx, [heapptr]
;write: ret
mov byte [rcx], 0xC3
add qword [heapptr], 1
mov byte [state], 0
ret
header "i", interpret
call tick
;check if blankspace
dpop rax
cmp cl, 0x0A
je .ign
cmp cl, ' '
je .ign
dpush rax
;check if dec number and convert
cmp rax, 0
jne .ex
cmp rcx, '9'
ja .err
cmp rcx, '0'
jb .err
sub rcx, '0'
dpop rax
dpush rcx
ret
.ex: call execute
ret
.ign: ret
.err: dpop rax
mov rax, 1 ;sys_write
mov rdi, 1 ;file descriptor
mov rsi, err ;buf
mov rdx, [errlen] ;len
syscall
header immediate "?", when
mov rax, [heapptr]
;write: sub rbp, 8
mov dword [rax], 0x08ED8348
add rax, 4
;write: mov rax, qword [rbp]
mov dword [rax], 0x00458B48
add rax, 4
;write: cmp rax, 0
mov dword [rax], 0x00F88348
add rax, 4
;write: je 0x00 relative jump forward
mov word [rax], 0x0074
add rax, 2
mov [heapptr], rax
push rax ;save address to write to
call compile
pop rax
mov rcx, [heapptr] ;address to jump to if 0
sub rcx, rax
;write the difference for the je instrunction
sub rax, 1
mov byte [rax], cl ;difference can not be over 127
ret
header immediate "W", while
mov rax, [heapptr]
dpush rax ;push for "repeat" word
;write: sub rbp, 8
mov dword [rax], 0x08ED8348
add rax, 4
;write: mov rax, qword [rbp]
mov dword [rax], 0x00458B48
add rax, 4
;write: cmp rax, 0
mov dword [rax], 0x00F88348
add rax, 4
;write: je 0x00000000 relative jump forward (32 bit version)
mov word [rax], 0x840F
add rax, 2
add rax, 4 ;space for address
mov [heapptr], rax
ret
header immediate "R", repeat
mov rax, [heapptr]
dpop rcx ;address from while
push rcx
;write: jmp adrs
sub rcx, rax ;calculate relative jump
sub rcx, 5
mov byte [rax], 0xE9
add rax, 1
mov dword [rax], ecx
add rax, 4
mov [heapptr], rax
pop rcx
;write jump address at the while
sub rax, rcx
sub rax, 18
add rcx, 14
mov dword [rcx], eax
ret
header "X", exit
pop rax
ret
header "m", imm ;make last defined word immediate
mov rax, [dict]
mov cl, byte [rax]
or cl, immediate 0
mov byte [rax], cl
ret
header immediate "I", if
mov rax, [heapptr]
;write: sub rbp, 8
mov dword [rax], 0x08ED8348
add rax, 4
;write: mov rax, qword [rbp]
mov dword [rax], 0x00458B48
add rax, 4
;write: cmp rax, 0
mov dword [rax], 0x00F88348
add rax, 4
;write: je 0x00000000 relative jump forward (32 bit version)
mov word [rax], 0x840F
add rax, 2
dpush rax ;push for "else" word
add rax, 4 ;space for address
mov [heapptr], rax
ret
header immediate "E", else
mov rax, [heapptr]
;write rel32 for the "if" jump
push rax
dpop rcx
mov rsi, rcx
add rsi, 4
sub rax, rsi
add rax, 5
mov dword [rcx], eax
pop rax
;write: jmp rel32 (for "then" word)
mov byte [rax], 0xE9
add rax, 1
dpush rax ;push for "then" word
add rax, 4 ;space for address
mov [heapptr], rax
ret
header immediate "T", then
mov rax, [heapptr]
;write rel32 for the "else" or "if" jump
dpop rcx
mov rsi, rcx
add rsi, 4
sub rax, rsi
mov dword [rcx], eax
ret
header "a", allot
dpop rax
add [heapptr], rax
ret
_start: mov rbp, dstack ;init stack pointer
.repl: cmp byte [state], 0
je .int
call compile
jmp .repl
.int: call interpret
jmp .repl
section .bss
heap: resb 8192*2
dstack: resq 256
section .data
dict: dq link
heapptr:dq heap
err: db "ERROR: char not defined or number", 0xA
errlen: dq $-err
state: db 0