~nch/onward

ref: 8e3c6f840c98f81e5a4efbb02270399d4c786878 onward/onward.s -rw-r--r-- 1.8 KiB
8e3c6f84 — nc added memory operators 4 years ago
                                                                                
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
; vi: ft=fasm
use64
format ELF64
public start as '_start'

; RSP = data stack
; RSI = virtual instruction stream

;; system calls
SYS_WRITE = 1
SYS_EXIT = 60

;; standard file handles
STDIN = 0
STDOUT = 1

;;

ADDR_SIZE = 8

macro defcode name {
    align ADDR_SIZE
name:
}

;; push/pop data stack
macro pushd r {
    lea rsp, [rsp + ADDR_SIZE]
    mov [rsp], r
}

macro popd r {
    mov r, [rsp]
    lea rsp, [rsp - ADDR_SIZE]
}

;; interpret next instruction pointed to by RSI
macro next {
    mov rax, qword [rsi]
    lea rsi, [rsi + ADDR_SIZE]
    jmp qword rax
}

IMMEDIATE = 0
COMPILE = 1
var_STATE: db IMMEDIATE

section '.text' ; readable executable

    defcode drop
    popd rax
    next

    defcode swap
    popd rax
    popd rbx
    pushd rbx
    pushd rax
    next

    defcode sdup
    popd rax
    pushd rax
    pushd rax
    next

    defcode lit
    mov rax, [rsi]
    pushd rax
    lea rsi, [rsi + ADDR_SIZE]
    next

    defcode lbrac
    mov [var_STATE], byte IMMEDIATE
    next

    defcode rbrac
    mov [var_STATE], byte COMPILE
    next

    defcode emit
    mov r8, rsi ; backup rsi since we'll clobber it
    mov rax, SYS_WRITE
    mov rdi, STDOUT
    lea rsi, [rsp]
    mov rdx, 1
    syscall
    popd rax
    mov rsi, r8 ; restore rsi
    next

    defcode mstore
    popd rbx ; addr to store at
    popd rax ; value to store at addr
    mov [rbx], rax
    next

    defcode mfetch
    popd rbx
    mov rax, [rbx]
    pushd rax
    next

    defcode mstoreb
    popd rbx
    popd rax
    mov [ebx], byte al
    next

    defcode mfetchb
    popd rbx
    xor rax, rax
    mov al, byte [ebx]
    pushd rax
    next

    defcode exit
    mov rax, SYS_EXIT
    mov rdi, 0
    syscall

    defcode branch
    add esi, [esi]
    next

start:
    cld
    mov rsi, instrs
    next

instrs:
    dq lit, '*'
    dq emit
    dq branch, -32
    dq exit