diff options
-rw-r--r-- | crenshaw/README | 4 | ||||
-rw-r--r-- | ecomp-c/README | 21 | ||||
-rw-r--r-- | ecomp-c/ec.c | 112 |
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( ); |