alloc/free working (not merging)
This commit is contained in:
@@ -6,52 +6,120 @@ section .bss
|
|||||||
|
|
||||||
section .text
|
section .text
|
||||||
alloc:
|
alloc:
|
||||||
add rdi, 16 ; add space for metadata
|
add rdi, 16 ; reserve 16 bytes for metadata
|
||||||
mov rax, [free_list_head] ; load head of free list
|
mov rsi, [free_list_head]
|
||||||
xor r8, r8 ; last block
|
xor r8, r8
|
||||||
.loop:
|
.loop:
|
||||||
test rax, rax ; end of list?
|
test rsi, rsi ; allocate new block if end of list is reached
|
||||||
jz .new_block ; yes? allocate new block
|
jz .new_block
|
||||||
cmp [rax], rdi ; does object fit in block and have space for metadata?
|
mov rdx, [rsi]
|
||||||
jge .found_block ; yes? use this block
|
cmp rdx, rdi ; is there enough space for allocation?
|
||||||
mov r8, rax
|
ja .use_block ; yes? allocate
|
||||||
mov rax, [rax + 8] ; load next free block
|
add rdx, 16
|
||||||
jb .loop ; no? go to next block
|
cmp rdx, rdi ; no? is there enough space if we include metadata
|
||||||
.found_block:
|
je .use_block ; if we include metadata, the sizes has to match exactly, or partial metadata will persist
|
||||||
sub qword [rax], rdi ; reduce the available size of the block
|
mov r8, rsi ; r8 contains the node from the last iteration
|
||||||
cmp qword [rax], 0 ; no space left in block?
|
mov rsi, [rsi + 8] ; next node
|
||||||
jg .done_remove_free_block ; no? do not remove block from free list
|
jmp .loop
|
||||||
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:
|
.new_block:
|
||||||
push rdi
|
push rdi
|
||||||
push r8
|
push r8
|
||||||
mov rdi, 4096 ; page size
|
add rdi, 16
|
||||||
call sys_mmap ; allocate a page
|
mov rsi, 4096
|
||||||
mov qword [rax], 4080 ; set size of block to block size - metadata
|
call max
|
||||||
mov rsi, [free_list_head]
|
push rax
|
||||||
mov qword [rax + 8], rsi ; move head to be the next item after this block
|
mov rdi, rax
|
||||||
mov [free_list_head], rax ; set new head to this block
|
call sys_mmap
|
||||||
|
pop rsi
|
||||||
|
sub rsi, 16
|
||||||
|
mov qword [rax], rsi ; update metadata to page size - metadata
|
||||||
|
push rax
|
||||||
|
mov rdi, rax
|
||||||
|
call insert_into_free
|
||||||
|
pop rsi
|
||||||
pop r8
|
pop r8
|
||||||
pop rdi
|
pop rdi
|
||||||
jmp .found_block
|
.use_block:
|
||||||
|
cmp [rsi], rdi ; check if the block will be empty after allocation
|
||||||
|
ja .unlink_done ; if not, do not unlink
|
||||||
|
test r8, r8 ; r8 is null if node is also head
|
||||||
|
jz .unlink_head
|
||||||
|
mov rdx, [rsi + 8] ; load next node
|
||||||
|
mov [r8 + 8], rdx ; link next node to last node's next
|
||||||
|
jmp .unlink_done
|
||||||
|
.unlink_head:
|
||||||
|
mov rdx, [free_list_head] ; load head
|
||||||
|
mov rdx, [rdx + 8] ; load head.next
|
||||||
|
mov [free_list_head], rdx ; mov head.next into head
|
||||||
|
.unlink_done:
|
||||||
|
sub [rsi], rdi ; reduce available space of block by the allocated space
|
||||||
|
mov rdx, [rsi] ; load the available space excluding the newly allocated space
|
||||||
|
lea rax, [rsi + rdx + 16] ; load the address of the newly allocated space
|
||||||
|
sub rdi, 16
|
||||||
|
mov [rax], rdi ; update metadata to allocation size - metadata
|
||||||
|
mov rdx, [alloc_list_head]
|
||||||
|
mov [rax + 8], rdx ; move head to nex item in this alloc
|
||||||
|
mov [alloc_list_head], rax ; update head to point to this node
|
||||||
|
lea rax, [rax + 16] ; skip past metadata for return value
|
||||||
|
ret
|
||||||
|
|
||||||
free:
|
free:
|
||||||
|
lea rdi, [rdi - 16] ; adjust for metadata
|
||||||
|
mov rsi, [alloc_list_head]
|
||||||
|
xor r8, r8
|
||||||
|
.loop:
|
||||||
|
test rsi, rsi
|
||||||
|
jz .not_found
|
||||||
|
cmp rdi, rsi
|
||||||
|
je .found
|
||||||
|
mov r8, rsi
|
||||||
|
mov rsi, [rsi + 8] ; next node
|
||||||
|
jmp .loop
|
||||||
|
.not_found:
|
||||||
|
mov rax, 60
|
||||||
|
mov rdi, 1
|
||||||
|
syscall
|
||||||
|
.found:
|
||||||
|
test r8, r8 ; r8 is null if node is also head
|
||||||
|
jz .unlink_head
|
||||||
|
mov rdx, [rsi + 8] ; load next node
|
||||||
|
mov [r8 + 8], rdx ; link next node to last node's next
|
||||||
|
jmp .unlink_done
|
||||||
|
.unlink_head:
|
||||||
|
mov rdx, [alloc_list_head] ; load head
|
||||||
|
mov rdx, [rdx + 8] ; load head.next
|
||||||
|
mov [alloc_list_head], rdx ; mov head.next into head
|
||||||
|
.unlink_done:
|
||||||
|
mov rdi, rsi
|
||||||
|
call insert_into_free
|
||||||
|
ret
|
||||||
|
|
||||||
|
insert_into_free:
|
||||||
|
mov rsi, [free_list_head] ; load head
|
||||||
|
test rsi, rsi ; is list empty
|
||||||
|
jz .insert_head ; if empty, insert at head
|
||||||
|
cmp rdi, rsi ; is input smaller then head
|
||||||
|
jl .insert_head ; if smaller, insert at head
|
||||||
|
xor r8, r8 ; r9 will track the previous node
|
||||||
|
.loop:
|
||||||
|
test rsi, rsi
|
||||||
|
jz .insert_end ; if at end of list, insert at end
|
||||||
|
cmp rdi, [rsi + 8] ; compare input to next node
|
||||||
|
jg .next ; if larger, skip to next node
|
||||||
|
mov [rsi + 8], rdi ; if smaller, insert at this position
|
||||||
|
mov [rdi + 8], rdx
|
||||||
|
ret
|
||||||
|
.next:
|
||||||
|
mov r8, rsi ; update r8 to current node
|
||||||
|
mov rsi, [rsi + 8] ; update rsi to next node
|
||||||
|
jmp .loop
|
||||||
|
.insert_head:
|
||||||
|
mov rdx, [free_list_head]
|
||||||
|
mov [rdi + 8], rdx
|
||||||
|
mov [free_list_head], rdi
|
||||||
|
ret
|
||||||
|
.insert_end:
|
||||||
|
mov [r8 + 8], rdi ; update last node's next to point at rdi
|
||||||
ret
|
ret
|
||||||
|
|
||||||
sys_mmap:
|
sys_mmap:
|
||||||
@@ -81,3 +149,12 @@ sys_munmap:
|
|||||||
mov rax, 60
|
mov rax, 60
|
||||||
mov rdi, 1
|
mov rdi, 1
|
||||||
syscall
|
syscall
|
||||||
|
|
||||||
|
max:
|
||||||
|
cmp rdi, rsi
|
||||||
|
jae .left
|
||||||
|
mov rax, rsi
|
||||||
|
ret
|
||||||
|
.left:
|
||||||
|
mov rax, rdi
|
||||||
|
ret
|
||||||
|
|||||||
Reference in New Issue
Block a user