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
|
; sanctuary
; macros {{{
; TODO: error handling (once i add that)
%macro pspush 1
lea r14, [r14-8]
mov qword [r14], r15
mov r15, %1
%endmacro
%macro pspop 1
mov %1, r15
mov r15, qword [r14]
lea r14, [r14+8]
%endmacro
%macro psdrop 0
lea r14, [r14+8]
%endmacro
%define s_latest 0
%macro defdict 3 ; name label flags
%strlen slen %1
global lfa_%2
lfa_%2: dq s_latest
%define s_latest lfa_%2
ffa_%2: db %3
nfa_%2: db slen
db %1
%endmacro
%macro defcode 3
defdict %1, %2, %3
%2:
%endmacro
; this is just taken from jewelforth, and does not correspond
; to how user variables are planned to work in sanctuary
; so todo make better later? i don't know if it really matters
; because it will only apply to builtin variables.
%macro defvar 4
%2: dq %4
defdict %1, %2, %3
pspush qword %2
%endmacro
; }}}
%assign INTERPRET 0x0
%assign COMPILING (~0x1)
%assign __NR_mprotect 10
%assign __NR_brk 12
%assign __NR_exit 60
section .bss
resq 4091
wstk: resq 1
section .text
global _start
_start:
lea r14, [wstk + 8]
call brk@
mov qword [dp], r15
mov qword [dp0], r15
mov r15, 0x9c400
call grow
call bye
defcode "brk@", brk@, 0
xor rdi, rdi
mov rax, __NR_brk
syscall
pspush rax
ret
defcode "grow", grow, 0
call brk@
pspop rdi
pspop r13
add rdi, r13
mov rax, __NR_brk
syscall
mov qword [dp$], rax
ret
defcode "executable", executable, 0
mov rdx, 0x7 ; PROT_{READ,WRITE,EXEC}
pspop rdi ; addr
pspop rsi
mov rax, __NR_mprotect
syscall
ret
defcode "here", here, 0
pspush qword [dp]
ret
defcode "bye", bye, 0
mov rdi, 0
mov rax, __NR_exit
syscall
ret
defvar "state", state, 0, INTERPRET
defvar "dp", dp, 0, 0
defvar "dp0", dp0, 0, 0
defvar "dp$", dp$, 0, 0
defvar "tib", tib, 0, 0 ; todo set correct initial value
defvar "#tib", n_tib, 0, 0 ; todo set correct initial value
defvar ">in", to_in, 0, 0
defvar "latest", latest, 0, lfa_latest
|