1 format ELF64 executable
3 ;; The code in this macro is placed at the end of each Forth word. When we are
4 ;; executing a definition, this code is what causes execution to resume at the
5 ;; next word in that definition.
7 ;; RSI points to the address of the definition of the next word to execute.
8 lodsq ; Load value at RSI into RAX and increment RSI
9 ;; Now RAX contains the location of the next word to execute. The first 8
10 ;; bytes of this word is the address of the codeword, which is what we want
12 jmp qword [rax] ; Jump to the codeword of the current word
15 ;; pushr and popr work on the return stack, whose location is stored in the
26 segment readable executable
29 cld ; Clear direction flag so LODSQ does the right thing.
30 mov rbp, return_stack_top ; Initialize return stack
37 ;; The codeword is the code that will be executed at the beginning of a forth
38 ;; word. It needs to save the old RSI and update it to point to the next word to
41 pushr rsi ; Save old value of RSI on return stack; we will continue execution there after we are done executing this word
42 lea rsi, [rax + 8] ; RAX currently points to the address of the codeword, so we want to continue at RAX+8
43 next ; Execute word pointed to by RSI
45 ;; This word is called at the end of a Forth definition. It just needs to
46 ;; restore the old value of RSI (saved by 'docol') and resume execution.
80 ;; Read a word from standard input and push it onto the stack as a pointer and a
81 ;; size. The pointer is valid until the next call to READ_WORD.
89 ;; Read characters into .char_buffer until one of them is not whitespace.
96 cmp [.char_buffer], ' '
98 cmp [.char_buffer], $A
102 ;; We got a character that wasn't whitespace. Now read the actual word.
106 mov al, [.char_buffer]
115 mov rsi, .char_buffer
119 cmp [.char_buffer], ' '
121 cmp [.char_buffer], $A
164 push you_typed_string
165 push you_typed_string.length
197 segment readable writable
199 you_typed_string db 'You typed: '
200 .length = $ - you_typed_string
204 READ_WORD.max_size = $FF
205 READ_WORD.buffer rb READ_WORD.max_size
206 READ_WORD.length db ?
207 READ_WORD.char_buffer db ?