commit 7414efe4b501bfa7e18c6fda66dc40a552d313b2
parent db82d2ef7f3e6a4c1e04b1aedf7cb003a34e38f3
Author: Virgil Dupras <hsoft@hardcoded.net>
Date: Wed, 1 Jun 2022 13:51:41 -0400
Put all assembler source in the same file
My one-file-per-word scheme earlier was because I planned to implement some
of the core words in C to make porting easier, but I ended up decising against
it. Only a small number of those words carry a speed penalty in C that is small
enough to make C worth it. These small number of words are not worth the extra
mechanism.
Words written in C will be only for "userland" in Dusk OS. It will be simpler
that way.
Diffstat:
27 files changed, 223 insertions(+), 252 deletions(-)
diff --git a/Makefile b/Makefile
@@ -1,21 +1,15 @@
TARGETS = dusk
-WORDOBJS = xcomp.o $(addsuffix .o,$(addprefix words/, \
- bye emit drop dup swap over rot \
- aset aget acfetch acstore ainc adec \
- to inc dec cfetch cstore fetch store add sub))
-
all: $(TARGETS)
-%.o: %.asm
- nasm -f elf32 -p word_macros.asm $< -o $@
-
-xcomp.asm: xcomp2.txt f2asm.py
- ./f2asm.py xcomp2.txt > $@
+xcomp.asm: dusk.asm xcomp2.txt f2asm.py
+ echo "; This file is autogenerated" > $@
+ cat dusk.asm >> $@
+ ./f2asm.py xcomp2.txt >> $@
-dusk: dusk.asm $(WORDOBJS)
- nasm -f elf32 -p word_macros.asm dusk.asm -o dusk.o
- ld -m elf_i386 dusk.o $(WORDOBJS) -o $@
+dusk: xcomp.asm
+ nasm -f elf32 xcomp.asm -o dusk.o
+ ld -m elf_i386 dusk.o -o $@
.PHONY: clean
clean:
- rm -f $(TARGETS) dusk.o $(WORDOBJS) xcomp.asm
+ rm -f $(TARGETS) dusk.o xcomp.asm
diff --git a/aliases.txt b/aliases.txt
@@ -0,0 +1,42 @@
+>r ps2rs
+r> rs2ps
+r@ rsget
+r~ rsdrop
++ add
+- sub
+A>r a2rs
+r>A rs2a
+rot> rotr
+>A aset
+A> aget
+Ac@ acfetch
+Ac! acstore
+A+ ainc
+A- adec
+Ac@+ acfetchplus
+Ac!+ acstoreplus
+in> inptr
+'curword curword
+1+ inc
+1- dec
+c@ cfetch
+c! cstore
+@ fetch
+! store
+c@+ cfetchplus
+c!+ cstoreplus
+, write
+c, cwrite
+= eq
+< lt
+> gt
+0< isneg
+0>= isnotneg
+>= gte
+<= lte
+-^ subinv
+<<c shlc
+>>c shrc
+<< shl
+>> shr
+move, movewr
diff --git a/dusk.asm b/dusk.asm
@@ -3,21 +3,70 @@ BITS 32
%define PS_SZ 0x1000
%define RS_SZ 0x1000
%define MEMSIZE 0x40000
+
+%macro pspush 1 ; src
+ sub ebp, 4
+ mov dword [ebp], %1
+%endmacro
+
+%macro pspop 1 ; dst
+ mov %1, dword [ebp]
+ add ebp, 4
+%endmacro
+
+%macro defword 4 ; name namelen lbl prevlbl
+db %1
+dd %4
+db %2
+%3:
+%endmacro
+
+%macro sysval 1 ; lbl
+mov eax,%1
+test byte [toflag], 0xff
+jnz to_is_set
+mov eax,[eax]
+pspush eax
+ret
+%endmacro
+
+%macro constant 1 ; val
+pspush %1
+ret
+%endmacro
+
+%macro ps2rs 0
+push dword [ebp]
+add ebp,4
+%endmacro
+
+%macro rs2ps 0
+sub ebp,4
+pop dword [ebp]
+%endmacro
+
+%define rsdrop pop eax
+
+%macro _begin_ 0
+%push begin
+%$begin:
+%endmacro
+
+%macro _next_ 0
+dec dword [esp]
+jnz %$begin
+%pop
+pop eax
+%endmacro
+
SECTION .bss
-GLOBAL areg
areg: resd 1
-GLOBAL toflag
toflag: resb 1
resd RS_SZ
-GLOBAL current
current: resd 1
-GLOBAL here
here: resd 1
-GLOBAL compiling
compiling: resd 1
-GLOBAL curword
curword: resb 6
-GLOBAL inptr
inptr: resd 1
rs_top:
resd PS_SZ
@@ -33,27 +82,137 @@ _start:
mov ebp, ps_top
mov byte [toflag], 0
mov dword [here], herestart
- EXTERN word_lastxcomp
mov dword [current], word_lastxcomp
- EXTERN word_boot
jmp word_boot
-GLOBAL cellword
cellword:
pop eax
pspush eax
ret
-GLOBAL to_is_set
to_is_set: ; eax=cell addr
mov byte [toflag], 0
pspop ebx
mov [eax], ebx
ret
-GLOBAL aliasword
aliasword:
pop eax
test byte [toflag], 0xff
jnz to_is_set
jmp [eax]
+
+defword 'bye', 3, word_bye, 0
+ mov eax,1 ; 'exit' system call
+ mov ebx,0 ; exit with error code 0
+ int 80h ; call the kernel
+
+defword 'emit', 4, word_emit, word_bye
+ mov eax,4 ; 'write' syscall
+ mov ebx,1 ; stdout
+ mov ecx,ebp ; top of PS, little endian
+ mov edx,1
+ int 80h
+ pspop eax
+ ret
+
+defword 'drop', 4, word_drop, word_emit
+ add ebp, 4
+ ret
+
+defword 'dup', 3, word_dup, word_drop
+ mov eax, [ebp]
+ sub ebp, 4
+ mov [ebp], eax
+ ret
+
+defword 'swap', 4, word_swap, word_dup
+ mov eax, [ebp]
+ mov ebx, [ebp+4]
+ mov [ebp], ebx
+ mov [ebp+4], eax
+ ret
+
+defword 'over', 4, word_over, word_swap
+ mov eax, [ebp+4]
+ sub ebp, 4
+ mov [ebp], eax
+ ret
+
+defword 'rot', 3, word_rot, word_over
+ mov eax, [ebp]
+ mov ebx, [ebp+4]
+ mov ecx, [ebp+8]
+ mov [ebp], ecx
+ mov [ebp+4], eax
+ mov [ebp+8], ebx
+ ret
+
+defword 'Ac@', 3, word_acfetch, word_rot
+ mov eax, [areg]
+ mov eax, [eax]
+ pspush eax
+ ret
+
+defword 'Ac!', 3, word_acstore, word_acfetch
+ pspop eax
+ mov eax, [areg]
+ mov [eax], eax
+ ret
+
+defword 'A+', 2, word_ainc, word_acstore
+ inc dword [areg]
+ ret
+
+defword 'A-', 2, word_adec, word_ainc
+ dec dword [areg]
+ ret
+
+defword 'to', 2, word_to, word_adec
+ mov byte [toflag], 1
+ ret
+
+defword '1+', 2, word_inc, word_to
+ inc dword [ebp]
+ ret
+
+defword '1-', 2, word_dec, word_inc
+ dec dword [ebp]
+ ret
+
+defword 'c@', 2, word_cfetch, word_dec
+ mov esi, [ebp]
+ mov eax, 0
+ mov al, [esi]
+ mov [ebp], eax
+ ret
+
+defword 'c!', 2, word_cstore, word_cfetch
+ pspop eax
+ pspop ebx
+ mov [eax], bl
+ ret
+
+defword '@', 1, word_fetch, word_cstore
+ mov esi, [ebp]
+ mov eax, [esi]
+ mov [ebp], eax
+ ret
+
+defword '!', 1, word_store, word_fetch
+ pspop eax
+ pspop ebx
+ mov [eax], ebx
+ ret
+
+defword '+', 1, word_add, word_store
+ pspop eax
+ add [ebp], eax
+ ret
+
+defword '-', 1, word_sub, word_add
+word_asmlast:
+ pspop eax
+ sub [ebp], eax
+ ret
+
diff --git a/f2asm.py b/f2asm.py
@@ -9,36 +9,8 @@ prevword = 'asmlast'
nasmmacros = {'ps2rs', 'rs2ps', 'rsget', 'rsdrop', 'a2rs', 'rs2a'}
anoncount = 0 # avoid label redefinitions
-aliases = {
- '>r': 'ps2rs',
- 'r>': 'rs2ps',
- 'r@': 'rsget',
- 'r~': 'rsdrop',
- '+': 'add',
- '-': 'sub',
- 'A>r': 'a2rs',
- 'r>A': 'rs2a',
- 'rot>': 'rotr',
- '>A': 'aset',
- 'A>': 'aget',
- 'Ac@': 'acfetch',
- 'Ac!': 'acstore',
- 'A+': 'ainc',
- 'A-': 'adec',
- 'Ac@+': 'acfetchplus',
- 'Ac!+': 'acstoreplus',
- 'in>': 'inptr',
- "'curword": 'curword',
- '1+': 'inc',
- '1-': 'dec',
- 'c@': 'cfetch',
- 'c!': 'cstore',
- '@': 'fetch',
- '!': 'store',
- 'c@+': 'cfetchplus',
- 'c!+': 'cstoreplus',
-}
-knownwords = set()
+pairs = (line.split() for line in open('aliases.txt', 'r').read().splitlines())
+aliases = {name: alias for name, alias in pairs}
def out(*args):
print(*args, end='')
@@ -74,7 +46,6 @@ def newword(name=None, imm=False):
if imm:
count |= 0x80
alias = aliases.get(name, name)
- knownwords.add(alias)
if alias == '_':
anoncount += 1
alias = f'_{anoncount}'
@@ -147,7 +118,6 @@ def _const_():
def _syscell_():
newword()
lbl = nextt()
- out(f'EXTERN {lbl}\n')
out(f'constant {lbl}\n')
def _alias_():
@@ -193,13 +163,6 @@ special = {
'pspushop': _pspushop_,
'exitop': _exitop_,
}
-out("""; This file is autogenerated
-
-EXTERN cellword
-EXTERN toflag
-EXTERN to_is_set
-EXTERN aliasword
-""")
t = nextt()
while t:
if t in special:
@@ -211,9 +174,6 @@ while t:
if name in nasmmacros:
out(f'{name}\n')
else:
- if name not in knownwords:
- out(f'EXTERN word_{name}\n')
- knownwords.add(name)
if name == '_':
name = f'_{anoncount}'
out(f'call word_{name}\n')
diff --git a/word_macros.asm b/word_macros.asm
@@ -1,65 +0,0 @@
-%macro pspush 1 ; src
- sub ebp, 4
- mov dword [ebp], %1
-%endmacro
-
-%macro pspop 1 ; dst
- mov %1, dword [ebp]
- add ebp, 4
-%endmacro
-
-%macro _word 4 ; name namelen lbl prevlbl
-GLOBAL %3
-db %1
-dd %4
-db %2
-%3:
-%endmacro
-
-%macro firstword 3 ; name namelen lbl
-_word %1,%2,%3,0
-%endmacro
-
-%macro defword 4
-EXTERN %4
-_word %1,%2,%3,%4
-%endmacro
-
-%macro sysval 1 ; lbl
-EXTERN %1
-mov eax,%1
-test byte [toflag], 0xff
-jnz to_is_set
-mov eax,[eax]
-pspush eax
-ret
-%endmacro
-
-%macro constant 1 ; val
-pspush %1
-ret
-%endmacro
-
-%macro ps2rs 0
-push dword [ebp]
-add ebp,4
-%endmacro
-
-%macro rs2ps 0
-sub ebp,4
-pop dword [ebp]
-%endmacro
-
-%define rsdrop pop eax
-
-%macro _begin_ 0
-%push begin
-%$begin:
-%endmacro
-
-%macro _next_ 0
-dec dword [esp]
-jnz %$begin
-%pop
-pop eax
-%endmacro
diff --git a/words/acfetch.asm b/words/acfetch.asm
@@ -1,6 +0,0 @@
-defword 'Ac@', 3, word_acfetch, word_rot
-EXTERN areg
- mov eax, [areg]
- mov eax, [eax]
- pspush eax
- ret
diff --git a/words/acstore.asm b/words/acstore.asm
@@ -1,6 +0,0 @@
-defword 'Ac!', 3, word_acstore, word_acfetch
-EXTERN areg
- pspop eax
- mov eax, [areg]
- mov [eax], eax
- ret
diff --git a/words/add.asm b/words/add.asm
@@ -1,4 +0,0 @@
-defword '+', 1, word_add, word_store
- pspop eax
- add [ebp], eax
- ret
diff --git a/words/adec.asm b/words/adec.asm
@@ -1,4 +0,0 @@
-defword 'A-', 2, word_adec, word_ainc
-EXTERN areg
- dec dword [areg]
- ret
diff --git a/words/aget.asm b/words/aget.asm
@@ -1,6 +0,0 @@
-defword 'A>', 2, word_aget, word_rot
-EXTERN areg
- mov eax, [areg]
- pspush eax
- ret
-
diff --git a/words/ainc.asm b/words/ainc.asm
@@ -1,5 +0,0 @@
-defword 'A+', 2, word_ainc, word_acstore
-EXTERN areg
- inc dword [areg]
- ret
-
diff --git a/words/aset.asm b/words/aset.asm
@@ -1,7 +0,0 @@
-defword '>A', 2, word_aset, word_aget
-EXTERN areg
- pspop eax
- mov [areg], eax
- ret
-
-
diff --git a/words/bye.asm b/words/bye.asm
@@ -1,4 +0,0 @@
-firstword 'bye', 3, word_bye
- mov eax,1 ; 'exit' system call
- mov ebx,0 ; exit with error code 0
- int 80h ; call the kernel
diff --git a/words/cfetch.asm b/words/cfetch.asm
@@ -1,6 +0,0 @@
-defword 'c@', 2, word_cfetch, word_dec
- mov esi, [ebp]
- mov eax, 0
- mov al, [esi]
- mov [ebp], eax
- ret
diff --git a/words/cstore.asm b/words/cstore.asm
@@ -1,6 +0,0 @@
-defword 'c!', 2, word_cstore, word_cfetch
- pspop eax
- pspop ebx
- mov [eax], bl
- ret
-
diff --git a/words/dec.asm b/words/dec.asm
@@ -1,3 +0,0 @@
-defword '1-', 2, word_dec, word_inc
- dec dword [ebp]
- ret
diff --git a/words/drop.asm b/words/drop.asm
@@ -1,3 +0,0 @@
-defword 'drop', 4, word_drop, word_emit
- add ebp, 4
- ret
diff --git a/words/dup.asm b/words/dup.asm
@@ -1,5 +0,0 @@
-defword 'dup', 3, word_dup, word_drop
- mov eax, [ebp]
- sub ebp, 4
- mov [ebp], eax
- ret
diff --git a/words/emit.asm b/words/emit.asm
@@ -1,8 +0,0 @@
-defword 'emit', 4, word_emit, word_bye
- mov eax,4 ; 'write' syscall
- mov ebx,1 ; stdout
- mov ecx,ebp ; top of PS, little endian
- mov edx,1
- int 80h
- pspop eax
- ret
diff --git a/words/fetch.asm b/words/fetch.asm
@@ -1,6 +0,0 @@
-defword '@', 1, word_fetch, word_cstore
- mov esi, [ebp]
- mov eax, [esi]
- mov [ebp], eax
- ret
-
diff --git a/words/inc.asm b/words/inc.asm
@@ -1,3 +0,0 @@
-defword '1+', 2, word_inc, word_to
- inc dword [ebp]
- ret
diff --git a/words/over.asm b/words/over.asm
@@ -1,5 +0,0 @@
-defword 'over', 4, word_over, word_swap
- mov eax, [ebp+4]
- sub ebp, 4
- mov [ebp], eax
- ret
diff --git a/words/rot.asm b/words/rot.asm
@@ -1,9 +0,0 @@
-defword 'rot', 3, word_rot, word_over
- mov eax, [ebp]
- mov ebx, [ebp+4]
- mov ecx, [ebp+8]
- mov [ebp], ecx
- mov [ebp+4], eax
- mov [ebp+8], ebx
- ret
-
diff --git a/words/store.asm b/words/store.asm
@@ -1,5 +0,0 @@
-defword '!', 1, word_store, word_fetch
- pspop eax
- pspop ebx
- mov [eax], ebx
- ret
diff --git a/words/sub.asm b/words/sub.asm
@@ -1,7 +0,0 @@
-defword '-', 1, word_sub, word_add
-GLOBAL word_asmlast
-word_asmlast:
- pspop eax
- sub [ebp], eax
- ret
-
diff --git a/words/swap.asm b/words/swap.asm
@@ -1,6 +0,0 @@
-defword 'swap', 4, word_swap, word_dup
- mov eax, [ebp]
- mov ebx, [ebp+4]
- mov [ebp], ebx
- mov [ebp+4], eax
- ret
diff --git a/words/to.asm b/words/to.asm
@@ -1,5 +0,0 @@
-defword 'to', 2, word_to, word_adec
-EXTERN toflag
- mov byte [toflag], 1
- ret
-