summaryrefslogtreecommitdiff
path: root/bismuth.asm
diff options
context:
space:
mode:
authorAleksey Veresov <aleksey@veresov.pro>2020-11-06 20:21:56 +0300
committerAleksey Veresov <aleksey@veresov.pro>2020-11-06 20:21:56 +0300
commitaaf2b78976f7740dbef32e0e538f1a1edd93456b (patch)
treeacc0d15f90c8645572a851a910360fd3da67d5d8 /bismuth.asm
downloadbismuth-aaf2b78976f7740dbef32e0e538f1a1edd93456b.tar
bismuth-aaf2b78976f7740dbef32e0e538f1a1edd93456b.tar.xz
bismuth-aaf2b78976f7740dbef32e0e538f1a1edd93456b.zip
It's alive.
Diffstat (limited to 'bismuth.asm')
-rw-r--r--bismuth.asm175
1 files changed, 175 insertions, 0 deletions
diff --git a/bismuth.asm b/bismuth.asm
new file mode 100644
index 0000000..b5f6182
--- /dev/null
+++ b/bismuth.asm
@@ -0,0 +1,175 @@
+section .data
+; This is stack of 4KB:
+ db 4096 dup 0
+stackbottom:
+; Place to copy msg content into:
+msg:
+ db 1024 dup 0
+; And finally our program:
+program:
+ dd bismuth ; We want to use our main interpreter, bismuth.
+ dd data
+ dd prog
+ dd data
+ dd 0x0a20202e
+ dd 0x2e2e6948
+ dd quote, eval, 0, pop
+ dd quote, eval, 0
+ dd 0, quote, msg, copywords
+ dd data, msg, eval, msg, eval, 0, output
+ dd 0
+
+
+; The input is in esi, pop dword from it:
+%macro bisnext 1
+ mov %1, dword [esi]
+ add esi, 4
+%endmacro
+
+; Top of the stack is in edi, pop dword from it:
+%macro bispop 1
+ mov %1, dword [edi]
+ add edi, 4
+%endmacro
+
+; Top of the stack is in edi, pop byte from it:
+%macro bispopbyte 1
+ mov %1, byte [edi]
+ inc edi
+%endmacro
+
+; Top of the stack is in edi, push dword onto it:
+%macro bispush 1
+ sub edi, 4
+ mov dword [edi], %1
+%endmacro
+
+; Top of the stack is in edi, push byte onto it:
+%macro bispushbyte 1
+ dec edi
+ mov byte [edi], %1
+%endmacro
+
+; Calling conventions for interpreters:
+%macro bisinterpret 1
+ push esi
+ mov esi, %1
+ bisnext eax
+ add eax, 4
+ push ebp
+ mov ebp, esp
+ call eax
+ mov esp, ebp
+ pop ebp
+ pop esi
+%endmacro
+
+
+section .text
+global _start
+_start:
+ mov esi, program ; We will read and execute program
+ mov edi, stackbottom ; and write results onto stack.
+ bisnext eax ; Read interpreter
+ bisinterpret eax ; and start interpretation.
+ ; After execution of program we will exit properly:
+ mov ebx, 0 ; We have no error (error code = 0)
+ mov eax, 1 ; and we want to exit.
+ int 0x80 ; Send this to kernel.
+ ; That's all! =)
+
+bismuth:
+ dd bismuth
+ mov esi, [ebp+4]
+bismuthloop:
+ bisnext eax
+ cmp eax, 0
+ je bismuthend
+ bisinterpret eax
+ jmp bismuthloop
+bismuthend:
+ mov [ebp+4], esi
+ ret
+
+prog:
+ dd prog
+progloop:
+ bisnext eax
+ cmp eax, 0
+ je progend
+ bisinterpret eax
+ jmp progloop
+progend:
+ ret
+
+pop:
+ dd pop
+ add edi, 4
+ ret
+
+copy:
+ dd copy
+ mov eax, dword [edi]
+ sub edi, 4
+ mov dword [edi], eax
+ ret
+
+quote:
+ dd quote
+ mov esi, [ebp+4]
+ bisnext eax
+ bispush eax
+ mov [ebp+4], esi
+ ret
+
+eval:
+ dd eval
+ mov esi, [ebp+4]
+ bispop eax
+ bisinterpret eax
+ mov [ebp+4], esi
+ ret
+
+data:
+ dd data
+ mov esi, [ebp+4]
+ push edi
+dataloop:
+ bisnext eax
+ cmp eax, eval
+ je dataeval
+ cmp eax, 0
+ je dataend
+ bispush eax
+ jmp dataloop
+dataeval:
+ bisinterpret eax
+ jmp dataloop
+dataend:
+ pop eax
+ sub eax, edi
+ bispush eax
+ mov [ebp+4], esi
+ ret
+
+copywords:
+ dd copywords
+ bispop ebx
+ bispop ecx
+ sub ebx, 4
+copywordsloop:
+ bispop eax
+ mov dword [ebx+ecx], eax
+ sub ecx, 4
+ jnz copywordsloop
+ ret
+
+output:
+ dd output
+ bispop edx
+ mov ecx, edi
+ mov ebx, 1
+ mov eax, 4
+ int 0x80
+ add edi, edx
+ ret