basic alloc
This commit is contained in:
88
input/baseline/alloc.asm
Normal file
88
input/baseline/alloc.asm
Normal file
@@ -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
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
# baseline
|
# baseline
|
||||||
nasm -g -felf64 ../input/baseline/gc.asm -o gc.o
|
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
|
nasm -g -felf64 ../input/baseline/str_cmp.asm -o str_cmp.o
|
||||||
|
|
||||||
# core
|
# core
|
||||||
@@ -12,4 +13,4 @@ nasm -g -felf64 ../input/core/itoa.asm -o itoa.o
|
|||||||
# program
|
# program
|
||||||
nasm -g -felf64 out.asm -o out.o
|
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
|
||||||
|
|||||||
Reference in New Issue
Block a user