1 ;;; This file define/describes the "machine"
4 ;;; https://en.wikibooks.org/wiki/X86_Assembly/X86_Architecture
6 ;;; General Purpose Registers ( * marks those used in syscalls )
7 ;;; *rax = ( -, eax = ( -, ax = ( ah, al) )) "accumulator"
8 ;;; rbx = ( -, ebx = ( -, bx = ( bh, bl) )) "base"
9 ;;; *rcx = ( -, ecx = ( -, cx = ( ch, cl) )) "counter"
10 ;;; *rdx = ( -, edx = ( -, dx = ( dh, dl) )) "data"
11 ;;; rsp = ( -, esp = ( -, sp = ( -, spl) )) "stack pointer"
12 ;;; rbp = ( -, ebp = ( -, bp = ( -, bpl) )) "stack base pointer"
13 ;;; *rsi = ( -, esi = ( -, si = ( -, sil) )) "source"
14 ;;; *rdi = ( -, edi = ( -, di = ( -, dil) )) "destination"
23 ;;; clobbers rdi rsi rdx rcx r8 r9 r11
27 ;;; SS "Stack Segment"
30 ;;; ES "Extra Segment"
31 ;;; FS "more Extra Segment"
32 ;;; GS "more more Extra Segment"
35 ;;; 0,0,0,0,0,0,0,0,0,0,ID,VIP,VIF,AC,VM,RF,
36 ;;; 0,NT,[IOPL,IOPL],OF,DF,IF,TF,SF,ZF,0,AF,0,PF,1,CF
38 ;;; Instruction pointer
41 ;;; Syscall allocations
42 ;;; clobbers rdi rsi rdx rcx r8 r9 r11
46 ;;; ######################################################################
48 ;;; ============================================================
49 ;;; FORTH machine model
50 ;;; rsp = data stack pointer
51 ;;; rbp = return stack pointer
52 ;;; rsi = instruction pointer
54 ;;; ========================================
55 ;;; The pushr macro pushes x onto the return stack
56 ;;; The popr macro pops x from the return stack
67 ;;; ========================================
68 ;;; The next macro "moves" execution to the next FORTH instruction,
69 ;;; using rsi as instruction pointer. It points to the doer field of a
70 ;;; word, which points to the assembly code that implements the
71 ;;; execution effect of the word. That doer code is entered with rsi
72 ;;; referring to the subsequent address in the colling word, and rax
73 ;;; referring to the doer field of the called word.
76 lodsq ; mov rax, [rsi] + add rsi,8
78 jmp qword [rax] ; goto code of that FORTH word (64 bit jump)
81 ;;; ========================================
82 ;;; The FORTH macro transitions to inline FORTH execution.
91 ;;; ========================================
92 ;;; The ENDFORTH macro transitions back to inline assembler after FORTH
98 ;;; ========================================
99 ;;; The DOFORTH lays out a single FORTH call
101 macro DOFORTH [label] {
110 ;;; ========================================
111 ;;; Macro WORD starts a FORTH word definition in this code.
112 ;;; The layout of a word is as follows:
113 ;;; TFA: [8 bytes] pointer to previous word in the word list
114 ;;; [8 bytes] pointer to the word's CFA
115 ;;; [8 bytes] a flags field
116 ;;; [8 bytes] the length of the word's pname
117 ;;; [varying] the word's pname
118 ;;; [1 byte] NUL -- making an asciiz of the pname
119 ;;; ;;[? bytes] 0-7 bytes for address alignment to [disabled]
120 ;;; [8 bytes] pointer to the word's TFA
121 ;;; OFF: [8 bytes] the DOES offset for the word
122 ;;; CFA: [8 bytes] pointer to the word's "doer" code
123 ;;; DFA: [? bytes] the word's data field
125 IMMEDIATE = 1 ; optional flag (symbol)
127 macro WORD label, name, doer, flags, previous, offset {
137 previous_word = label#_TFA
140 dq label#_CFA ; link to CFA of word
145 pname: db 0 ; extra NUL byte
148 dq label#_TFA ; link to TFA of word
150 dq offset + 0 ; The DOES offset. Defaults to 0.
151 ;; also CFA = pointer to "doer"
158 dq dofasm ; label#_DFA
168 mov reg,qword [reg+8]
178 macro tfa2flags reg {
184 macro tfa2pname reg {
201 ;;; Code snippet to push a pname string with address and 64-bit length field.
202 ;;; The register is advanced to point at the text part.
203 macro pushpname reg {
208 ;;; ========================================
209 ;;; The BLOCK macro lays out the length for a subsequent block to the
211 macro BLOCK endlabel {
213 dq endlabel - datastart
217 ;;; ========================================
218 ;;; The STRING macro lays out length cell and data for several string
220 macro STRING [data] {
222 local datastart, dataend
223 dq dataend - datastart
231 ;;; ========================================
232 ;;; The BRANCH macro lays out FORTH words BRANCH and 0BRANCH with offset
233 macro BRANCH zero,label {
242 ;;; ========================================
243 ;;; The STREAM macro starts an in-core FORTH STREAM area. See WORD
244 ;;; STREAM for details.
245 macro STREAM endlabel {
249 dq endlabel - datastart