commit 401d08e3a475fed62e5ca51d45a1f3b2d16ff36b
parent c736051ea77058258104de32e4e2b3fa1dac2ea6
Author: Virgil Dupras <hsoft@hardcoded.net>
Date: Wed, 1 Jun 2022 13:51:41 -0400
Playing around with fork() waitpid() and execve()
Diffstat:
4 files changed, 49 insertions(+), 3 deletions(-)
diff --git a/.gitignore b/.gitignore
@@ -1,3 +1,4 @@
/dusk
+/cc
/xcomp.asm
*.o
diff --git a/Makefile b/Makefile
@@ -1,4 +1,4 @@
-TARGETS = dusk
+TARGETS = dusk cc
all: $(TARGETS)
xcomp.asm: dusk.asm xcomp.txt f2asm.py aliases.txt
@@ -9,7 +9,14 @@ xcomp.asm: dusk.asm xcomp.txt f2asm.py aliases.txt
dusk: xcomp.asm boot.fs
nasm -f elf32 xcomp.asm -o dusk.o
ld -m elf_i386 dusk.o -o $@
-
+
+cc: dummycc.c
+ cc dummycc.c -o $@
+
+.PHONY: run
+run: dusk cc
+ stty -icanon -echo; ./dusk ; stty icanon echo
+
.PHONY: clean
clean:
rm -f $(TARGETS) dusk.o xcomp.asm
diff --git a/dummycc.c b/dummycc.c
@@ -0,0 +1,3 @@
+int main() {
+ return 54;
+}
diff --git a/dusk.asm b/dusk.asm
@@ -4,8 +4,11 @@ BITS 32
%define RS_SZ 0x1000
%define MEMSIZE 0x40000
%define SYSCALL_EXIT 1
+%define SYSCALL_FORK 2
%define SYSCALL_READ 3
%define SYSCALL_WRITE 4
+%define SYSCALL_WAITPID 7
+%define SYSCALL_EXECVE 11
%macro pspush 1 ; src
sub ebp, 4
@@ -104,6 +107,7 @@ inptr: resd 1
inrd: resd 1
inrdc: resd 1
wnf: resd 1
+scratchpad: resd 0x100
psufl: resd 1
resd RS_SZ
rs_top:
@@ -113,6 +117,7 @@ herestart: resb MEMSIZE
SECTION .data
bootsrc: incbin "boot.fs"
+ccpath: db './cc', 0
SECTION .text
GLOBAL _start
@@ -462,8 +467,38 @@ defword 'call,', 5, word_callwrite, word_litn
ret
defword 'exit,', 5, word_exitwrite, word_callwrite
-word_asmlast:
pspush 0xc3 ; ret opcode
call word_cwrite
ret
+; ( sa sl -- status )
+; Alright, this is where things get really really interesting. Let's compile C
+; code! This takes a string as input and writes the binary result to "here".
+; status is the status code of the child process that ran.
+defword 'cc,', 3, word_ccwrite, word_exitwrite
+word_asmlast:
+ mov eax, SYSCALL_FORK
+ int 0x80
+ test eax, eax
+ jz _cc_is_child
+ ; is parent
+ mov ebx, eax ; child pid
+ mov eax, SYSCALL_WAITPID
+ mov ecx, scratchpad ; wstatus
+ xor edx, edx ; options
+ int 0x80
+ xor eax, eax
+ mov al, [scratchpad+1] ; status code
+ pspush eax
+ pspush 0x70 ; p
+ jmp word_emit
+_cc_is_child:
+ pspush 0x63 ; c
+ call word_emit
+ mov eax, SYSCALL_EXECVE
+ mov ebx, ccpath
+ mov ecx, scratchpad ; argv
+ mov dword [scratchpad], ccpath ; arg 0
+ mov dword [scratchpad+4], 0 ; end of arg
+ xor edx, edx ; no envp
+ int 0x80