84 lines
2.1 KiB
NASM
84 lines
2.1 KiB
NASM
global alloc, free
|
|
|
|
section .bss
|
|
free_list_head: resq 1 ; head of free list
|
|
alloc_list_head: resq 1 ; head of allocation list
|
|
|
|
section .text
|
|
alloc:
|
|
add rdi, 16 ; add space for metadata
|
|
mov rax, [free_list_head] ; 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_head], 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_head] ; load head of allocated blocks
|
|
mov [rax + 8], rsi ; move head to be next item after this block
|
|
mov [alloc_list_head], 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_head]
|
|
mov qword [rax + 8], rsi ; move head to be the next item after this block
|
|
mov [free_list_head], 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
|