summaryrefslogtreecommitdiff
path: root/sanctuary.s
blob: b511d6817f97eb4d1da8b8a288ff4b02290fb22a (plain)
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