-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbootstrap.asm
More file actions
311 lines (245 loc) · 3.56 KB
/
Copy pathbootstrap.asm
File metadata and controls
311 lines (245 loc) · 3.56 KB
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
format ELF64 executable 3
segment readable writeable executable
magic:
.name: dd "blue"
.ver: dd 5
CELL_SIZE = 8
DICT_ENTRY_SIZE = CELL_SIZE * 3
DICT_SIZE = DICT_ENTRY_SIZE * 256
DST_SIZE = 8192
SRC_SIZE = 8192
DS_SIZE = CELL_SIZE * 16
DS_MASK = DS_SIZE - 1
DS_BASE = $ - DS_SIZE
K_ORG = DS_BASE
assert DS_SIZE and DS_MASK = 0
assert DS_BASE and DS_MASK = 0
REG_LVL equ ebp
REG_SRC equ rsi
REG_DST equ rdi
REG_DSTB equ r11
REG_LAST equ r12
REG_DS equ r13
;;; kernel
ds_push:
mov [REG_DS], rax
add REG_DS, CELL_SIZE
and REG_DS, DS_MASK
or REG_DS, DS_BASE
ret
ds_push2:
call ds_push
mov rax, rcx
jmp ds_push
ds_pop:
sub REG_DS, CELL_SIZE
and REG_DS, DS_MASK
or REG_DS, DS_BASE
mov rax, [REG_DS]
ret
ds_pop2:
call ds_pop
mov rcx, rax
jmp ds_pop
find:
push REG_LAST
lodsq
.check:
cmp rax, [REG_LAST]
jne .prev
mov rax, REG_LAST
pop REG_LAST
ret
.prev:
sub REG_LAST, DICT_ENTRY_SIZE
jmp .check
xt:
call find
mov rax, [rax + CELL_SIZE]
ret
;;; opcode handlers
fin:
mov rdx, REG_DST
mov rsi, REG_DSTB
xor edi, edi
inc edi
sub rdx, rsi
mov eax, edi
syscall
xor edi, edi
mov eax, 60
syscall
word_define:
lodsq
add REG_LAST, DICT_ENTRY_SIZE
mov [REG_LAST], rax
mov [REG_LAST + CELL_SIZE], REG_DST
mov [REG_LAST + (CELL_SIZE * 2)], REG_SRC
jmp next
word_end:
test REG_LVL, REG_LVL
jz .top_level
dec REG_LVL
pop REG_SRC
jmp .done
.top_level:
cmp byte [REG_DST - 5], 0xE8
jne .cret
inc byte [REG_DST - 5]
jmp .done
.cret:
mov al, 0xC3
stosb
.done:
jmp next
word_ccall:
call xt
call rax
jmp next
word_rcall:
mov al, 0xE8
stosb
call xt
sub rax, REG_DST
sub rax, 4
stosd
jmp next
word_interp:
call find
push REG_SRC
inc REG_LVL
mov REG_SRC, [rax + (CELL_SIZE * 2)]
jmp next
word_caddr:
call xt
call ds_push
jmp next
word_raddr:
call xt
raddr:
sub rax, REG_DSTB
add rax, K_ORG
call ds_push
jmp next
num_comp:
movsq
jmp next
num_push:
lodsq
call ds_push
jmp next
swap:
call ds_pop2
xchg rax, rcx
call ds_push2
jmp next
k_dup:
call ds_pop
call ds_push
call ds_push
jmp next
k_add:
call ds_pop2
add rax, rcx
call ds_push
jmp next
k_sub:
call ds_pop2
sub rax, rcx
call ds_push
jmp next
k_or:
call ds_pop2
or rax, rcx
call ds_push
jmp next
k_shl:
call ds_pop2
shl rax, cl
call ds_push
jmp next
tor:
call ds_pop
push rax
jmp next
fromr:
pop rax
call ds_push
jmp next
dollar_caddr:
mov rax, REG_DST
call ds_push
jmp next
dollar_raddr:
mov rax, REG_DST
jmp raddr
dst_base:
mov rax, REG_DSTB
call ds_push
jmp next
dst_base_set:
call ds_pop
mov REG_DSTB, rax
jmp next
set_b:
call ds_pop2
mov byte [rcx], al
jmp next
set:
call ds_pop2
mov [rcx], rax
jmp next
fetch:
call ds_pop
mov rax, [rax]
call ds_push
jmp next
comma_b:
call ds_pop
stosb
jmp next
comma_w:
call ds_pop
stosw
jmp next
comma_d:
call ds_pop
stosd
jmp next
comma:
call ds_pop
stosq
jmp next
dsp_nl:
jmp next
;;; interpreter
next:
xor eax, eax
lodsb
jmp qword [bc_tbl + (rax * CELL_SIZE)]
;;; main
entry $
xor edi, edi
mov rsi, _src
mov edx, SRC_SIZE
xor eax, eax
syscall
mov REG_SRC, _src
mov REG_DSTB, _dst
mov REG_DST, REG_DSTB
mov REG_DS, DS_BASE
mov REG_LAST, _dict - DICT_ENTRY_SIZE
jmp next
;;; opcode table
bc_tbl:
dq fin
dq word_define, word_end, word_ccall, word_rcall, word_interp, word_caddr, word_raddr
dq num_comp, num_push
dq tor, fromr, swap, k_dup, k_add, k_sub, k_or, k_shl
dq dollar_caddr, dollar_raddr, dst_base, dst_base_set
dq set_b, set, fetch, comma_b, comma_w, comma_d, comma
dq dsp_nl
;;; reserved
_dict rb DICT_SIZE
_dst rb DST_SIZE
_src rb SRC_SIZE