summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--crenshaw/README4
-rw-r--r--ecomp-c/README21
-rw-r--r--ecomp-c/ec.c112
3 files changed, 133 insertions, 4 deletions
diff --git a/crenshaw/README b/crenshaw/README
index 244c0be..9797e1b 100644
--- a/crenshaw/README
+++ b/crenshaw/README
@@ -22,7 +22,7 @@ fpc main.pas
nasm -o test.bin -f bin test.asm
./emul test.bin
-TODO: kapstone to actually assemble the code, currently
+TODO: capstone to actually assemble the code, currently
we use nasm to produce a binary and we use capstone to decode
it. What's better?
@@ -87,7 +87,7 @@ but we still have to calculate relative addresses. On the
other hand we loose a register as sort of an address base
register.
-PC-relative adressig is a good thing, as it makes
+PC-relative adressing is a good thing, as it makes
code relocatable for free.
Some survey on which CPUs have/had PC-relative adressing:
diff --git a/ecomp-c/README b/ecomp-c/README
index 850bc5e..ca3fc12 100644
--- a/ecomp-c/README
+++ b/ecomp-c/README
@@ -10,3 +10,24 @@ pcc -g -O0 -march=i386 -ffreestanding -nostdlib -Wl,-emain -Werror -Wall -std=c8
tcc -g -O0 -m32 -march=i386 -fno-builtin -std=c89 -Werror -Wall -o ec ec.c
./ec < test1.e > test1
+
+links
+-----
+
+29:00 video Hjalfi writes a compiler
+things I got from cowgol:
+inner-nested functions/procedures
+don't do automatic type promotion, maybe something like uint8, int8, etc.
+
+memory management
+-----------------
+
+https://www.informatik.htw-dresden.de/~beck/ASM/syscall_list.html
+sbrk and brk inspired from rt0 (git@github.com:lpsantil/rt0.git)
+
+http://dmitrysoshnikov.com/compilers/writing-a-memory-allocator/
+
+https://arjunsreedharan.org/post/148675821737/memory-allocators-101-write-a-simple-memory
+https://github.com/arjun024/memalloc.git
+
+
diff --git a/ecomp-c/ec.c b/ecomp-c/ec.c
index be8f785..7559d8f 100644
--- a/ecomp-c/ec.c
+++ b/ecomp-c/ec.c
@@ -4,7 +4,9 @@
/* string */
-void *NULL = (void *)0;
+enum {
+ NULL = 0
+};
int strcmp( const char *s1, const char *s2 )
{
@@ -75,6 +77,10 @@ int strlcat( char *d, const char *s, int n )
int errno;
+enum {
+ ENOMEM = 1
+};
+
/* stdlib */
enum {
@@ -85,7 +91,8 @@ enum {
enum {
SYSCALL_EXIT = 1,
SYSCALL_READ = 3,
- SYSCALL_WRITE = 4
+ SYSCALL_WRITE = 4,
+ SYSCALL_BRK = 45
};
enum {
@@ -179,6 +186,101 @@ char *itoa( int v, char *s, int base )
return s;
}
+static int system_brk( void *addr )
+{
+ return syscall1( SYSCALL_BRK, (int )addr );
+}
+
+void *current_brk = 0;
+
+int brk( void *addr )
+{
+ void *p;
+
+ p = (void *)system_brk( addr );
+ if( p == current_brk ) {
+ errno = ENOMEM;
+ return -1;
+ }
+
+ current_brk = p;
+
+ return 0;
+}
+
+void *sbrk( int inc )
+{
+ void *old_brk;
+ int res;
+
+ if( current_brk == 0 ) {
+ brk( 0 );
+ }
+
+ if( inc == 0 ) {
+ return current_brk;
+ }
+
+ old_brk = current_brk;
+
+ res = brk( ( char *)current_brk + inc );
+ if( res == -1 ) {
+ return (void *)-1;
+ }
+
+ return old_brk;
+}
+
+typedef struct mem_header {
+ int size;
+ int used;
+ struct mem_header *next;
+} mem_header;
+
+static mem_header *mem_head = NULL;
+static mem_header *mem_tail = NULL;
+
+int mem_align( int n )
+{
+ return ( n + sizeof( int ) - 1 ) & ~( sizeof( int ) - 1 );
+}
+
+void *malloc( int size )
+{
+ int total_size;
+ void *p;
+ mem_header *h;
+
+ total_size = mem_align( sizeof( mem_header ) + size );
+
+ /* TODO: get an unused block with size */
+
+ p = sbrk( total_size );
+ if( p == (void *)-1 ) {
+ return NULL;
+ }
+
+ h = p;
+ h->size = size;
+ h->used = 1;
+ h->next = NULL;
+
+ if( mem_head == NULL ) {
+ mem_head = h;
+ }
+ if( mem_tail != NULL ) {
+ mem_tail->next = h;
+ }
+ mem_tail = h;
+
+ return (void *)( h + 1 );
+}
+
+void free( void *ptr )
+{
+ /* TODO: insert in free list, mark block as unused */
+}
+
/* stdio */
static void print_string( int fd, const char *s )
@@ -871,6 +973,12 @@ static void epilogue( void )
int main( void )
{
+ const char *hello = "Hello World!";
+ char *s = malloc( strlen( hello ) + 1 );
+ strlcpy( s, hello, strlen( hello ) );
+ puts( s );
+ free( s );
+
init( );
prologue( );
parseModule( );