From 308e0310c4611986edec1518b73bb4dc61575f8b Mon Sep 17 00:00:00 2001 From: nub31 Date: Mon, 3 Feb 2025 18:37:25 +0100 Subject: [PATCH] basic alloc --- input/baseline/alloc.asm | 88 ++++++++++++++++++++++++++++++++++++++++ output/build.sh | 3 +- 2 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 input/baseline/alloc.asm diff --git a/input/baseline/alloc.asm b/input/baseline/alloc.asm new file mode 100644 index 0000000..ddbcba9 --- /dev/null +++ b/input/baseline/alloc.asm @@ -0,0 +1,88 @@ +global alloc, free + +; metadata +; +0: size +; +8: next +; +16 data + +section .bss + free_list: resq 1 ; head of free list + alloc_list: resq 1 ; head of allocation list + +section .text +alloc: + add rdi, 16 ; add space for metadata + mov rax, [free_list] ; load head of free list + xor r8, r8 ; last block +.loop: + test rax, rax ; end of list? + jz .new_block ; yes? allocate new block + cmp [rax], rdi ; does object fit in block and have space for metadata? + jge .found_block ; yes? use this block + mov r8, rax + mov rax, [rax + 8] ; load next free block + jb .loop ; no? go to next block +.found_block: + sub qword [rax], rdi ; reduce the available size of the block + cmp qword [rax], 0 ; no space left in block? + jg .done_remove_free_block ; no? do not remove block from free list + mov rsi, [rax + 8] ; yes? remove block from free list + test r8, r8 ; is current head of list? + jz .remove_free_head ; yes? remove head + mov [r8 + 8], rsi ; set prev.next to this.next + jmp .done_remove_free_block +.remove_free_head + mov [free_list], rsi +.done_remove_free_block: + mov rsi, [rax] ; load size of block excluding the newly allocated object + lea rax, [rax + rsi + 16] ; address of allocated block + sub rdi, 16 + mov [rax], rdi ; save size + mov rsi, [alloc_list] ; load head of allocated blocks + mov [rax + 8], rsi ; move head to be next item after this block + mov [alloc_list], rax ; set new head to this block + lea rax, [rax + 16] ; skip metadata for return value + ret +.new_block: + push rdi + push r8 + mov rdi, 4096 ; page size + call sys_mmap ; allocate a page + mov qword [rax], 4080 ; set size of block to block size - metadata + mov rsi, [free_list] + mov qword [rax + 8], rsi ; move head to be the next item after this block + mov [free_list], rax ; set new head to this block + pop r8 + pop rdi + jmp .found_block + +free: + ret + +sys_mmap: + mov rax, 9 + mov rsi, rdi + mov rdi, 0 + mov rdx, 3 + mov r10, 34 + mov r8, -1 + mov r9, 0 + syscall + cmp rax, -1 + je .error + ret +.error: + mov rax, 60 + mov rdi, 1 + syscall + +sys_munmap: + mov rax, 11 + syscall + cmp rax, -1 + je .error + ret +.error: + mov rax, 60 + mov rdi, 1 + syscall diff --git a/output/build.sh b/output/build.sh index 74ea336..2de7f52 100755 --- a/output/build.sh +++ b/output/build.sh @@ -2,6 +2,7 @@ # baseline nasm -g -felf64 ../input/baseline/gc.asm -o gc.o +nasm -g -felf64 ../input/baseline/alloc.asm -o alloc.o nasm -g -felf64 ../input/baseline/str_cmp.asm -o str_cmp.o # core @@ -12,4 +13,4 @@ nasm -g -felf64 ../input/core/itoa.asm -o itoa.o # program nasm -g -felf64 out.asm -o out.o -ld -o out str_len.o arr_size.o itoa.o gc.o str_cmp.o out.o +ld -o out str_len.o arr_size.o itoa.o alloc.o gc.o str_cmp.o out.o