--- /dev/null
+\ vim: filetype=forth
+
+: mmap 222 sys6 ;
+: munmap 215 sys2 ;
+
+: PROT_READ 1 ;
+: PROT_WRITE 2 ;
+: MAP_PRIVATE 2 ;
+: MAP_ANONYMOUS 32 ;
+
+: ALLOC_PROT PROT_READ PROT_WRITE | ;
+: ALLOC_MAP MAP_PRIVATE MAP_ANONYMOUS | ;
+
+\ This is a raw way to allocate memory. Callers to this will need to know
+\ how much memory was allocated, to call dealloc later.
+: alloc_raw ( byte-count -- addr )
+ 0 swap ALLOC_PROT ALLOC_MAP -1:i32 0 mmap
+;
+
+: dealloc ( addr byte-count -- )
+ munmap
+;
+
+export alloc
+: alloc ( byte-count -- addr )
+ dup \ we'll need the length again later
+ 8 + \ add 64 bits to the front where we'll store the length
+ alloc_raw \ ( byte-count addr )
+ dup \ ( byte-count addr addr)
+ rot \ ( addr addr byte-count )
+ rot \ ( addr byte-count addr )
+ ! \ write the length to the addr, now ( addr )
+ 8 + \ here's the address we'll return, 8 bytes forward to account for the length
+;
+
+export free
+: free ( addr -- )
+ 8 - \ the real memory start is 8 bytes before
+ dup \ ( addr addr )
+ @ \ ( addr byte-length )
+ 8 + \ add 8 to the byte length to refer to the whole region from alloc.
+ dealloc
+;
+
+1024 alloc
+free
--- /dev/null
+\ vim: filetype=forth
+
+: write ( fd ptr len -- bytes-written-or-err )
+ 64
+ sys3
+;
+
+: strlen ( addr -- len )
+ dup dup \ ( addr addr addr )
+ @:8 \ ( addr addr byte )
+ loop \ ( addr addr )
+ 1 + \ ( addr addr+1 )
+ dup \ ( addr addr+1 addr+1)
+ @:8 \ ( addr addr+1 byte )
+ endloop
+ drop \ ( addr addr+len )
+ swap \ ( addr+len addr )
+ - \ ( len )
+;
+
+"this is a string" strlen
--- /dev/null
+#include <stdio.h>
+
+extern unsigned long data_stack_end;
+register unsigned long * stack_pointer asm("s2");
+
+void putn() {
+ unsigned long * stack_index = &data_stack_end;
+ printf("stack: ");
+ while (stack_index != stack_pointer) {
+ printf("%ld ", *stack_index);
+ stack_index -= 1;
+ }
+ printf("%ld\n", *stack_pointer);
+}
+
+
--- /dev/null
+# ../target/debug/relc mem.rel
+# riscv64-unknown-linux-gnu-as -o mem.o mem.asm
+# riscv64-unknown-linux-gnu-cc -O1 -no-pie -o test-mem.out putn.c mem.o -nostartfiles
+# ./test-mem.out
+
+../target/debug/relc out.rel
+riscv64-unknown-linux-gnu-as -o out.o out.asm
+riscv64-unknown-linux-gnu-cc -O1 -no-pie -o test-out.out putn.c out.o -nostartfiles
+./test-out.out