commit 1d5a0306dc96da7eb9d2bd2e5a53557671110da1 Author: NukeBird Date: Sun Nov 23 18:21:50 2025 +0300 First commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b883f1f --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +*.exe diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..0e76165 --- /dev/null +++ b/Makefile @@ -0,0 +1,16 @@ +CC = clang +CFLAGS = -Wall -Wextra -Werror -pedantic -std=c11 -nostdlib -static -Oz -ffreestanding +LDFLAGS = -Wl,/SUBSYSTEM:CONSOLE,/ENTRY:_start -fuse-ld=lld +LIBS = -lkernel32 -luser32 +SOURCES = main.c axl.c +TARGET = prog.exe + +all: $(TARGET) + +$(TARGET): $(SOURCES) + $(CC) $(CFLAGS) $(SOURCES) -o $(TARGET) $(LDFLAGS) $(LIBS) +clean: + rm -f $(TARGET) + +.PHONY: all clean + diff --git a/axl.c b/axl.c new file mode 100644 index 0000000..b8347d4 --- /dev/null +++ b/axl.c @@ -0,0 +1,112 @@ +#include "axl.h" + +static uint8_t memory[AXL_HEAP_SIZE]; + +struct mb_header +{ + uint32_t size; + bool is_free; + struct mb_header* next; +}; + +typedef struct mb_header mb_header; + +#define MB_HEADER_SIZE sizeof(mb_header) + +static mb_header* root = 0; + +void* axl_memset(void* ptr, int8_t c, int32_t n) +{ + if(ptr) + { + for(int32_t i = 0; i < n; i++) + { + ((int8_t*)ptr)[i] = c; + } + } + + return ptr; +} + +void axl_init(void) +{ + static bool axl_initialized = false; + + if(!axl_initialized) + { + axl_memset(memory, 0, AXL_HEAP_SIZE); + root = (mb_header*)memory; + root->is_free = true; + root->next = NULL; + root->size = AXL_HEAP_SIZE - MB_HEADER_SIZE; + axl_initialized = true; + } +} + +mb_header* axl_find_mb(uint32_t req_size) +{ + mb_header* block = root; + + while(block != NULL) + { + if(block->is_free && block->size >= req_size) + { + return block; + } + block = block->next; + } + + return NULL; +} + +void axl_split_mb(mb_header* block, uint32_t size) +{ + if(block->size > size + MB_HEADER_SIZE) + { + mb_header* new_block = (mb_header*)((uint8_t*)block + MB_HEADER_SIZE + size); + new_block->size = block->size - size - MB_HEADER_SIZE; + new_block->is_free = true; + new_block->next = block->next; + + block->size = size; + block->next = new_block; + } +} + +void* axl_malloc(uint32_t size) +{ + if(size > AXL_HEAP_SIZE - MB_HEADER_SIZE) + { + return NULL; + } + + mb_header* free_block = axl_find_mb(size); + + if(!free_block) + { + return NULL; + } + + axl_split_mb(free_block, size); + free_block->is_free = false; + + return (void*)((uint8_t*)free_block + MB_HEADER_SIZE); +} + +void axl_free(void* ptr) +{ + if(!ptr) + { + return; + } + + mb_header* block = (mb_header*)((uint8_t*)ptr - MB_HEADER_SIZE); + mb_header* next_block = block->next; + block->is_free = true; + + if(next_block != NULL && next_block->is_free) + { + block->size += next_block->size + MB_HEADER_SIZE; + block->next = next_block->next; + } +} diff --git a/axl.h b/axl.h new file mode 100644 index 0000000..2f2fdf5 --- /dev/null +++ b/axl.h @@ -0,0 +1,17 @@ +#ifndef AXL_H +#define AXL_H + +#ifndef AXL_HEAP_SIZE +#define AXL_HEAP_SIZE 1024 * 1024 * 16 +#endif + +#include +#include +#include + +void axl_init(void); +void* axl_malloc(uint32_t size); +void* axl_memset(void* ptr, int8_t c, int32_t n); +void axl_free(void* ptr); + +#endif diff --git a/main.c b/main.c new file mode 100644 index 0000000..6f9fd2a --- /dev/null +++ b/main.c @@ -0,0 +1,20 @@ +#include "axl.h" +#include + +int _start(void) // Entry point on Linux +{ + MessageBoxA(NULL, "wawa", "fffff", MB_OK | MB_ICONINFORMATION); + axl_init(); + + int* f = axl_malloc(sizeof(int)); + *f = 4; + axl_free(f); + + (void)f; + + Sleep(2); + + while(true){} + + return 0; +}