А вот мой вариант со списком:
Код:
; Получение RCX страниц оперативной памяти (RAX - физический адрес)
align 8
alloc_phis_memory:
mov rax, [free_pages_count]
sub rax, rcx
cmp rax, [min_free_pages_count]
jl .error
mov [free_pages_count], rax
mov rax, [free_memory_pointer]
@@:
call temp_mount_page
cmp rcx, [temp_page + MEMORY_BLOCK.size]
je .equals
jb .below
mov rax, [temp_page + MEMORY_BLOCK.next]
cmp rax, [free_memory_pointer]
jne @b
.error:
mov rax, -1
ret
.equals:
push rax rdx
mov rax, [temp_page + MEMORY_BLOCK.next]
mov rdx, [temp_page + MEMORY_BLOCK.prev]
call temp_mount_page
mov [temp_page + MEMORY_BLOCK.prev], rdx
xchg rax, rdx
call temp_mount_page
pop rdx rax
.exit:
and rax, not 0xFFF
ret
.below:
sub [temp_page + MEMORY_BLOCK.size], rcx
push rcx
mov rcx, [temp_page + MEMORY_BLOCK.size]
shl rcx, 12
add rax, rcx
pop rcx
jmp .exit
; Освобожение RCX страниц оперативной памяти начиная с RAX
align 8
free_phis_memory:
add [free_pages_count], rcx
push rbx rcx rdx rdi
mov rbx, rax
mov rax, [free_memory_pointer]
@@:
push rax
call temp_mount_page
pop rax
mov rdx, [temp_page + MEMORY_BLOCK.size]
shl rdx, 12
add rdx, rax
cmp rdx, rbx
je .variant_2
mov rax, [qword temp_page + MEMORY_BLOCK.next]
cmp rax, [free_memory_pointer]
jne @b
mov rax, rcx
shl rax, 12
lea rdx, [rbx + rax]
mov rax, [free_memory_pointer]
@@:
push rax
call temp_mount_page
pop rax
cmp rax, rdx
je .variant_3
mov rax, [qword temp_page + MEMORY_BLOCK.next]
cmp rax, [free_memory_pointer]
jne @b
.variant_1: ; Наш блок не соседствует c другими
mov rax, [free_memory_pointer]
call temp_mount_page
mov rax, rbx
xchg [temp_page + MEMORY_BLOCK.prev], rax
mov rdi, rax
call temp_mount_page
mov rax, rbx
mov [temp_page + MEMORY_BLOCK.next], rax
call temp_mount_page
mov rdx, rcx
mov [temp_page + MEMORY_BLOCK.size], rdx
mov rdx, [free_memory_pointer]
mov [temp_page + MEMORY_BLOCK.next], rdx
mov [temp_page + MEMORY_BLOCK.prev], rdi
.exit:
pop rdi rdx rcx rbx
mov rax, TRUE
ret
.variant_2: ; Наш блок после другого
push rax
add [temp_page + MEMORY_BLOCK.size], rcx
mov rcx, [temp_page + MEMORY_BLOCK.size]
shl rcx, 12
add rax, rcx
mov rdx, rax
mov rax, [free_memory_pointer]
@@:
push rax
call temp_mount_page
pop rax
cmp rdx, rax
je .variant_4
mov rax, [temp_page + MEMORY_BLOCK.next]
cmp rax, [free_memory_pointer]
jne @b
pop rax
jmp .exit
.variant_3: ; Наш блок перед другим
mov rdi, [temp_page + MEMORY_BLOCK.size]
mov rdx, [temp_page + MEMORY_BLOCK.next]
mov rax, [temp_page + MEMORY_BLOCK.prev]
push rax
call temp_mount_page
pop rax
mov [temp_page + MEMORY_BLOCK.next], rdx
xchg rax, rdx
call temp_mount_page
mov [temp_page + MEMORY_BLOCK.prev], rdx
add rcx, rdi
jmp .variant_1
.variant_4: ; Наш блок между другими (с первым блоком объединение выполненно)
mov rdi, [temp_page + MEMORY_BLOCK.size]
mov rdx, [temp_page + MEMORY_BLOCK.next]
mov rax, [temp_page + MEMORY_BLOCK.prev]
push rax
call temp_mount_page
pop rax
mov [temp_page + MEMORY_BLOCK.next], rdx
xchg rax, rdx
call temp_mount_page
mov [temp_page + MEMORY_BLOCK.prev], rdx
pop rax
call temp_mount_page
add [temp_page + MEMORY_BLOCK.size], rdi
jmp .exit
Что можно улучшить? Какой алгоритм стоит использовать в своей системе?