0,0 → 1,833 |
if ~defined memmanager_inc |
memmanager_inc_fix: |
memmanager_inc fix memmanager_inc_fix |
;for testing in applications |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; Memory allocator for MenuetOS kernel |
;; Andrey Halyavin, halyavin@land.ru 2005 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; heap block structure - |
;; you can handle several ranges of |
;; pages simultaneosly. |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
.heap_linear_address equ 0 |
.heap_block_size equ 4 |
.heap_physical_address equ 8 |
.heap_reserved equ 12 |
.heap_block_info equ 16 |
max_heaps equ 8 |
.range_info equ 36 |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;; memory manager data |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
uglobal |
MEM_heap_block rd .heap_block_info*max_heaps/4 |
MEM_heap_count rd 1 |
MEM_cli_count rd 1 |
MEM_cli_prev rd 1 |
MEM_FreeSpace rd 1 |
; MEM_AllSpace rd 1 |
endg |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;;MEM_Init |
;;Initialize memory manager structures. |
;;Must be called first. |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
MEM_Init: |
push eax |
xor eax,eax |
mov [MEM_cli_prev],eax ;init value = 0 |
dec eax |
mov [MEM_cli_count],eax ;init value = -1 |
pop eax |
ret |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;;MEM_Heap_Lock |
;;Wait until all operations with heap will be finished. |
;;Between MEM_Heap_Lock and MEM_Heap_UnLock operations |
;;with heap are forbidden. |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
MEM_Heap_Lock: |
pushfd |
cli |
inc dword [MEM_cli_count] |
jz MEM_Heap_First_Lock |
add esp,4 |
ret |
MEM_Heap_First_Lock: ;save interrupt flag |
shr dword [esp],9 |
and dword [esp],1 |
pop dword [MEM_cli_prev] |
ret |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;;MEM_Heap_UnLock |
;;After this routine operations with heap are allowed. |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
MEM_Heap_UnLock: |
dec dword [MEM_cli_count] |
js MEM_Heap_UnLock_last |
ret |
MEM_Heap_UnLock_last: |
cmp dword [MEM_cli_prev],0 ;restore saved interrupt flag |
jz MEM_Heap_UnLock_No_sti |
sti |
MEM_Heap_UnLock_No_sti: |
ret |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;;MEM_Add_Heap |
;;Add new range to memory manager. |
;;eax - linear address |
;;ebx - size in pages |
;;ecx - physical address |
;;Result: |
;; eax=1 - success |
;; eax=0 - failed |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
MEM_Add_Heap: |
push edx |
call MEM_Heap_Lock |
mov edx,[MEM_heap_count] |
cmp edx,max_heaps |
jz MEM_Add_Heap_Error |
inc dword [MEM_heap_count] |
shl edx,4 |
mov [MEM_heap_block+edx+.heap_linear_address],eax |
mov [MEM_heap_block+edx+.heap_block_size],ebx |
shl dword [MEM_heap_block+edx+.heap_block_size],12 |
mov [MEM_heap_block+edx+.heap_physical_address],ecx |
lea edx,[4*ebx+.range_info+4095] ;calculate space for page info table |
and edx,0xFFFFF000 |
|
push edi |
mov edi,edx |
shr edi,12 |
sub edi,ebx ;edi=-free space |
sub [MEM_FreeSpace],edi |
; sub [MEM_AllSpace],edi |
|
mov [eax],eax |
add [eax],edx ;first 4 bytes - pointer to first free page |
;clean page info area |
lea edi,[eax+4] |
mov ecx,edx |
shr ecx,2 |
push eax |
xor eax,eax |
rep stosd |
pop eax |
pop edi |
;create free pages list. |
mov ecx,[eax] |
shl ebx,12 |
add eax,ebx ;eax - address after block |
MEM_Add_Heap_loop: |
add ecx,4096 |
mov [ecx-4096],ecx ;set forward pointer |
cmp ecx,eax |
jnz MEM_Add_Heap_loop |
mov dword [ecx-4096],0 ;set end of list |
MEM_Add_Heap_ret: |
call MEM_Heap_UnLock |
pop edx |
ret |
MEM_Add_Heap_Error: |
xor eax,eax |
jmp MEM_Add_Heap_ret |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;;MEM_Get_Physical_Address |
;;Translate linear address to physical address |
;;Parameters: |
;; eax - linear address |
;;Result: |
;; eax - physical address |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
if used MEM_Get_Physical_Address |
MEM_Get_Physical_Address: |
push ecx |
call MEM_Heap_Lock |
mov ecx,[MEM_heap_count] |
dec ecx |
shl ecx,4 |
MEM_Get_Physical_Address_loop: |
sub eax,[MEM_heap_block+ecx+.heap_linear_address] |
jl MEM_Get_Physical_Address_next |
cmp eax,[MEM_heap_block+ecx+.heap_block_size] |
jge MEM_Get_Physical_Address_next |
add eax,[MEM_heap_block+ecx+.heap_physical_address] |
jmp MEM_Get_Physical_Address_loopend |
MEM_Get_Physical_Address_next: |
add eax,[MEM_heap_block+ecx+.heap_linear_address] |
sub ecx,16 |
jns MEM_Get_Physical_Address_loop |
xor eax,eax ;address not found |
MEM_Get_Physical_Address_loopend: |
call MEM_Heap_UnLock |
pop ecx |
ret |
end if |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;;MEM_Get_Linear_Address |
;;Translate physical address to linear address. |
;;Parameters: |
;; eax - physical address |
;;Result: |
;; eax - linear address |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
if used MEM_Get_Linear_Address |
MEM_Get_Linear_Address: |
push ecx |
call MEM_Heap_Lock |
mov ecx,[MEM_heap_count] |
dec ecx |
shl ecx,4 |
MEM_Get_Linear_Address_loop: |
sub eax,[MEM_heap_block+ecx+.heap_physical_address] |
jl MEM_Get_Linear_Address_Next |
cmp eax,[MEM_heap_block+ecx+.heap_block_size] |
jge MEM_Get_Linear_Address_Next |
add eax,[MEM_heap_block+ecx+.heap_linear_address] |
call MEM_Heap_UnLock |
pop ecx |
ret |
MEM_Get_Linear_Address_Next: |
add eax,[MEM_heap_block+ecx+.heap_physical_address] |
sub ecx,16 |
jns MEM_Get_Linear_Address_loop |
call MEM_Heap_UnLock |
pop ecx |
xor eax,eax ;address not found |
ret |
end if |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;;MEM_Alloc_Page |
;;Allocate and add reference to page |
;;Result: |
;; eax<>0 - physical address of page |
;; eax=0 - not enough memory |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
if used MEM_Alloc_Page |
MEM_Alloc_Page: |
push ecx |
call MEM_Heap_Lock |
mov ecx,[MEM_heap_count] |
dec ecx |
shl ecx,4 |
MEM_Alloc_Page_loop: |
push ecx |
mov ecx,[MEM_heap_block+ecx+.heap_linear_address] |
cmp dword [ecx],0 |
jz MEM_Alloc_Page_loopend |
mov eax,[ecx] |
push dword [eax] |
pop dword [ecx] |
sub eax,ecx |
push eax |
shr eax,10 |
mov word [ecx+.range_info+eax],1 |
pop eax |
pop ecx |
add eax,[MEM_heap_block+ecx+.heap_physical_address] |
dec [MEM_FreeSpace] |
jmp MEM_Alloc_Page_ret |
MEM_Alloc_Page_loopend: |
pop ecx |
sub ecx,16 |
jns MEM_Alloc_Page_loop |
xor eax,eax |
MEM_Alloc_Page_ret: |
call MEM_Heap_UnLock |
pop ecx |
ret |
end if |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;;MEM_Alloc_Page_Linear |
;;Allocate and add reference to page |
;;Result: |
;; eax<>0 - linear address of page |
;; eax=0 - not enough memory |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
if used MEM_Alloc_Page_Linear |
MEM_Alloc_Page_Linear: |
push ecx |
call MEM_Heap_Lock |
mov ecx,[MEM_heap_count] |
dec ecx |
shl ecx,4 |
MEM_Alloc_Page_Linear_loop: |
push ecx |
mov ecx,[MEM_heap_block+ecx+.heap_linear_address] |
cmp dword [ecx],0 |
jz MEM_Alloc_Page_Linear_loopend |
mov eax,[ecx] |
push dword [eax] |
pop dword [ecx] |
push eax |
sub eax,ecx |
shr eax,10 |
mov word [ecx+.range_info+eax],1 |
pop eax |
pop ecx |
dec [MEM_FreeSpace] |
jmp MEM_Alloc_Page_Linear_ret |
MEM_Alloc_Page_Linear_loopend: |
pop ecx |
sub ecx,16 |
jns MEM_Alloc_Page_Linear_loop |
xor eax,eax |
MEM_Alloc_Page_Linear_ret: |
call MEM_Heap_UnLock |
pop ecx |
ret |
end if |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;;MEM_Free_Page |
;;Remove reference and free page if number of |
;;references is equal to 0 |
;;Parameters: |
;; eax - physical address of page |
;;Result: |
;; eax - 1 success |
;; eax - 0 failed |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
if (used MEM_Free_Page) | (used MEM_Free_Page_Linear) |
MEM_Free_Page: |
test eax,eax |
jz MEM_Free_Page_Zero |
test eax,0xFFF |
jnz MEM_Free_Page_Not_Aligned |
push ebx |
push ecx |
push edx |
call MEM_Heap_Lock |
mov ecx,[MEM_heap_count] |
dec ecx |
shl ecx,4 |
MEM_Free_Page_Heap_loop: |
sub eax,[MEM_heap_block+ecx+.heap_physical_address] |
js MEM_Free_Page_Heap_loopnext |
cmp eax,[MEM_heap_block+ecx+.heap_block_size] |
jl MEM_Free_Page_Heap_loopend |
MEM_Free_Page_Heap_loopnext: |
add eax,[MEM_heap_block+ecx+.heap_physical_address] |
sub ecx,16 |
jns MEM_Free_Page_Heap_loop |
xor eax,eax |
inc eax |
jmp MEM_Free_Page_ret |
MEM_Free_Page_Heap_loopend: |
mov ecx,[MEM_heap_block+ecx+.heap_linear_address] |
mov ebx,eax |
add eax,ecx |
shr ebx,10 |
mov edx,[ecx+.range_info+ebx] |
test edx,0x80000000 |
jnz MEM_Free_Page_Bucket |
test dx,dx |
jz MEM_Free_Page_Error |
dec word [ecx+.range_info+ebx] |
jnz MEM_Free_Page_OK |
MEM_Free_Page_Bucket: |
push dword [ecx] |
mov [ecx],eax |
pop dword [eax] |
mov dword [ecx+.range_info+ebx],0 |
inc [MEM_FreeSpace] |
MEM_Free_Page_OK: |
mov eax,1 |
MEM_Free_Page_ret: |
call MEM_Heap_UnLock |
pop edx |
pop ecx |
pop ebx |
ret |
MEM_Free_Page_Error: |
xor eax,eax |
jmp MEM_Free_Page_ret |
MEM_Free_Page_Zero: |
inc eax |
ret |
MEM_Free_Page_Not_Aligned: |
xor eax,eax |
ret |
end if |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;;MEM_Free_Page_Linear |
;;Remove reference and free page if number of |
;;references is equal to 0 |
;;Parameters: |
;; eax - linear address of page |
;;Result: |
;; eax - 1 success |
;; eax - 0 failed |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
if used MEM_Free_Page_Linear |
MEM_Free_Page_Linear: |
test eax,eax |
jz MEM_Free_Page_Zero |
test eax,0xFFF |
jnz MEM_Free_Page_Not_Aligned |
push ebx |
push ecx |
push edx |
call MEM_Heap_Lock |
mov ecx,[MEM_heap_count] |
dec ecx |
shl ecx,4 |
|
MEM_Free_Page_Linear_Heap_loop: |
sub eax,[MEM_heap_block+ecx+.heap_linear_address] |
js MEM_Free_Page_Linear_Heap_loopnext |
cmp eax,[MEM_heap_block+ecx+.heap_block_size] |
jl MEM_Free_Page_Heap_loopend |
MEM_Free_Page_Linear_Heap_loopnext: |
add eax,[MEM_heap_block+ecx+.heap_linear_address] |
sub ecx,16 |
jns MEM_Free_Page_Linear_Heap_loop |
xor eax,eax |
inc eax |
jmp MEM_Free_Page_ret |
end if |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;;MEM_Alloc_Pages |
;;Allocates set of pages. |
;;Parameters: |
;; eax - number of pages |
;; ebx - buffer for physical addresses |
;;Result: |
;; eax - number of allocated pages |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
if used MEM_Alloc_Pages |
MEM_Alloc_Pages: |
push eax |
push ebx |
push ecx |
mov ecx,eax |
test ecx,ecx |
jz MEM_Alloc_Pages_ret |
MEM_Alloc_Pages_loop: |
call MEM_Alloc_Page |
test eax,eax |
jz MEM_Alloc_Pages_ret |
mov [ebx],eax |
add ebx,4 |
dec ecx |
jnz MEM_Alloc_Pages_loop |
MEM_Alloc_Pages_ret: |
sub [esp+8],ecx |
pop ecx |
pop ebx |
pop eax |
ret |
end if |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;;MEM_Alloc_Pages_Linear |
;;Allocates set of pages. |
;;Parameters: |
;; eax - number of pages |
;; ebx - buffer for linear addresses |
;;Result: |
;; eax - number of allocated pages |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
if used MEM_Alloc_Pages_Linear |
MEM_Alloc_Pages_Linear: |
push eax |
push ebx |
push ecx |
mov ecx,eax |
test ecx,ecx |
jz MEM_Alloc_Pages_Linear_ret |
MEM_Alloc_Pages_Linear_loop: |
call MEM_Alloc_Page_Linear |
test eax,eax |
jz MEM_Alloc_Pages_Linear_ret |
mov [ebx],eax |
add ebx,4 |
dec ecx |
jnz MEM_Alloc_Pages_Linear_loop |
MEM_Alloc_Pages_Linear_ret: |
sub [esp+8],ecx |
pop ecx |
pop ebx |
pop eax |
ret |
end if |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;;MEM_Free_Pages |
;;Parameters: |
;; eax - number of pages |
;; ebx - array of addresses |
;;Result: |
;; eax=1 - succcess |
;; eax=0 - failed |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
if used MEM_Free_Pages |
MEM_Free_Pages: |
push ebx |
push ecx |
mov ecx,eax |
test ecx,ecx |
jz MEM_Free_Pages_ret |
MEM_Free_Pages_loop: |
mov eax,[ebx] |
call MEM_Free_Page |
add ebx,4 |
test eax,eax |
jz MEM_Free_Pages_ret |
dec ecx |
jnz MEM_Free_Pages_loop |
MEM_Free_Pages_ret: |
pop ecx |
pop ebx |
ret |
end if |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;;MEM_Free_Pages_Linear |
;;Parameters: |
;; eax - number of pages |
;; ebx - array of addresses |
;;Result: |
;; eax=1 - succcess |
;; eax=0 - failed |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
if used MEM_Free_Pages_Linear |
MEM_Free_Pages_Linear: |
push ebx |
push ecx |
mov ecx,eax |
test ecx,ecx |
jz MEM_Free_Pages_Linear_ret |
MEM_Free_Pages_Linear_loop: |
mov eax,[ebx] |
call MEM_Free_Page_Linear |
add ebx,4 |
test eax,eax |
jz MEM_Free_Pages_Linear_ret |
dec ecx |
jnz MEM_Free_Pages_Linear_loop |
MEM_Free_Pages_Linear_ret: |
pop ecx |
pop ebx |
ret |
end if |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;;MEM_Get_Heap_Number |
;;Calculate number of heap which pointer belongs to. |
;;Parameter: |
;; eax - address |
;;Result: |
;; ecx - number of heap*16. |
;; eax=0 if address not found. |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
if used MEM_Get_Heap_Number |
MEM_Get_Heap_Number: |
call MEM_Heap_Lock |
mov ecx,[MEM_heap_count] |
dec ecx |
shl ecx,4 |
MEM_Get_Heap_loop: |
sub eax,[MEM_heap_block+ecx+.heap_physical_address] |
jl MEM_Get_Heap_loopnext |
cmp eax,[MEM_heap_block+ecx+.heap_block_size] |
jl MEM_Get_Heap_loopend |
MEM_Get_Heap_loopnext: |
add eax,[MEM_heap_block+ecx+.heap_physical_address] |
sub ecx,16 |
jns MEM_Get_Heap_loop |
call MEM_Heap_UnLock |
xor eax,eax |
ret |
MEM_Get_Heap_loopend: |
add eax,[MEM_heap_block+ecx+.heap_physical_address] |
call MEM_Heap_UnLock |
ret |
end if |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;;MEM_Get_Heap_Number_Linear |
;;Calculate number of heap which pointer belongs to. |
;;Parameter: |
;; eax - address |
;;Result: |
;; ecx - number of heap*16. |
;; eax=0 if address not found. |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
if used MEM_Get_Heap_Number_Linear |
MEM_Get_Heap_Number_Linear: |
call MEM_Heap_Lock |
mov ecx,[MEM_heap_count] |
dec ecx |
shl ecx,4 |
MEM_Get_Heap_Linear_loop: |
sub eax,[MEM_heap_block+ecx+.heap_linear_address] |
jl MEM_Get_Heap_Linear_loopnext |
cmp eax,[MEM_heap_block+ecx+.heap_block_size] |
jl MEM_Get_Heap_Linear_loopend |
MEM_Get_Heap_Linear_loopnext: |
add eax,[MEM_heap_block+ecx+.heap_linear_address] |
sub ecx,16 |
jns MEM_Get_Heap_Linear_loop |
call MEM_Heap_UnLock |
xor eax,eax |
ret |
MEM_Get_Heap_Linear_loopend: |
add eax,[MEM_heap_block+ecx+.heap_linear_address] |
call MEM_Heap_UnLock |
ret |
end if |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;;MEM_Alloc |
;;Allocate small region. |
;;Parameters: |
;; eax - size (0<eax<=4096) |
;;Result: |
;; eax - linear address |
;; eax=0 - not enough memory |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
if used MEM_Alloc |
MEM_Alloc: |
;find chain |
test eax,eax |
jng MEM_Alloc_Wrong_Size |
cmp eax,4096 |
jg MEM_Alloc_Wrong_Size |
push ebx |
push ecx |
push edx |
push esi |
dec eax |
shr eax,4 |
xor edx,edx |
MEM_Alloc_Find_Size: |
add edx,4 |
shr eax,1 |
jnz MEM_Alloc_Find_Size |
MEM_Alloc_Size_Found: |
mov ecx,edx |
shr ecx,2 |
add ecx,4 |
mov eax,1 |
shl eax,cl |
mov esi,eax |
;esi - block size |
;edx - offset |
call MEM_Heap_Lock |
mov ecx,[MEM_heap_count] |
dec ecx |
shl ecx,4 |
MEM_Alloc_Find_Heap: |
mov eax,[MEM_heap_block+ecx+.heap_linear_address] |
cmp dword [eax+edx],0 |
jnz MEM_Alloc_Use_Existing |
sub ecx,16 |
jns MEM_Alloc_Find_Heap |
;create new bucket page |
call MEM_Alloc_Page_Linear |
call MEM_Get_Heap_Number_Linear |
mov ecx,[MEM_heap_block+ecx+.heap_linear_address] |
mov [ecx+edx],eax |
lea ebx,[eax+4096] |
MEM_Alloc_List_loop: |
mov [eax],eax |
mov [eax+4],eax |
add [eax],esi |
sub [eax+4],esi |
add eax,esi |
cmp eax,ebx |
jnz MEM_Alloc_List_loop |
sub ebx,esi |
mov dword [ebx],0 |
sub eax,4096 |
mov dword [eax+4],0 |
mov eax,ecx |
|
MEM_Alloc_Use_Existing: |
mov ebx,eax |
mov eax,[eax+edx] |
mov ecx,[eax] |
mov [ebx+edx],ecx |
test ecx,ecx |
jz MEM_Alloc_Became_Empty |
mov dword [ecx+4],0 |
MEM_Alloc_Became_Empty: |
mov ecx,eax |
sub ecx,ebx |
shr ecx,10 |
and ecx,0xFFFFFFFC |
inc byte [ebx+.range_info+ecx+2] |
shr edx,2 |
add edx,128 |
dec edx |
mov [ebx+.range_info+ecx+3],dl |
|
MEM_Alloc_ret: |
call MEM_Heap_UnLock |
pop esi |
pop edx |
pop ecx |
pop ebx |
ret |
MEM_Alloc_Wrong_Size: |
xor eax,eax |
ret |
end if |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;;MEM_Free |
;;Parameters: |
;; eax - linear address |
;;Result: |
;; eax=1 - success |
;; eax=0 - failed |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
if used MEM_Free |
MEM_Free: |
test eax,eax |
jz MEM_Free_Zero |
push ebx |
push ecx |
push edx |
push esi |
push edi |
push ebp |
call MEM_Heap_Lock |
call MEM_Get_Heap_Number_Linear |
test eax,eax |
jz MEM_Free_ret |
mov edx,eax |
mov ecx,[MEM_heap_block+ecx+.heap_linear_address] |
sub edx,ecx |
shr edx,10 |
and edx,0xFFFFFFFC |
mov ebx,[ecx+.range_info+edx] |
mov esi,ebx |
shr esi,24 |
sub esi,128 |
mov edi,[ecx+4+4*esi] |
mov [eax],edi |
mov dword [eax+4],0 |
test edi,edi |
jz MEM_Free_Empty_List |
mov [edi+4],eax |
MEM_Free_Empty_List: |
mov [ecx+4+4*esi],eax |
sub ebx,0x10000 |
mov [ecx+.range_info+edx],ebx |
test ebx,0xFF0000 |
jnz MEM_Free_ret |
;delete empty blocks on the page |
lea edx,[esi+5] |
and eax,0xFFFFF000 |
mov edi,eax |
mov eax,1 |
xchg ecx,edx |
shl eax,cl |
mov ecx,edx |
mov edx,eax |
;edx - size of block |
;edi - start of page |
mov eax,edi |
lea ebx,[eax+4096] |
MEM_Free_Block_loop: |
cmp dword [eax+4],0 |
jnz MEM_Free_Block_Not_First |
mov ebp,dword [eax] |
mov [ecx+4+4*esi],ebp |
test ebp,ebp |
jz MEM_Free_Block_Last |
mov dword [ebp+4],0 |
MEM_Free_Block_Last: |
jmp MEM_Free_Block_loop_end |
MEM_Free_Block_Not_First: |
mov ebp,dword [eax] |
push ebp |
mov ebp,dword [eax+4] |
pop dword [ebp] |
mov ebp,dword [eax] |
test ebp,ebp |
jz MEM_Free_Block_loop_end |
push dword [eax+4] |
pop dword [ebp+4] |
; jmp MEM_Free_Block_loop_end |
MEM_Free_Block_loop_end: |
add eax,edx |
cmp eax,ebx |
jnz MEM_Free_Block_loop |
mov eax,edi |
call MEM_Free_Page_Linear |
MEM_Free_ret: |
call MEM_Heap_UnLock |
pop ebp |
pop edi |
pop esi |
pop edx |
pop ecx |
pop ebx |
ret |
MEM_Free_Zero: |
inc eax |
ret |
end if |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;;MEM_Add_Reference |
;; eax - physical address of page |
;;Result: |
;; eax=1 - success |
;; eax=0 - failed |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
if used MEM_Add_Reference |
MEM_Add_Reference: |
push ebx |
push ecx |
call MEM_Heap_Lock |
call MEM_Get_Heap_Number |
test eax,eax |
jz MEM_Add_Reference_ret |
sub eax,[MEM_heap_block+ecx+.heap_physical_address] |
mov ecx,[MEM_heap_block+ecx+.heap_linear_address] |
shr eax,10 |
and eax,0xFFFFFFFC |
test dword [ecx+eax+.range_info],0x80000000 |
jnz MEM_Add_Reference_failed |
inc dword [ecx+eax+.range_info] |
MEM_Add_Reference_ret: |
call MEM_Heap_UnLock |
pop ecx |
pop ebx |
ret |
MEM_Add_Reference_failed: |
xor eax,eax |
jmp MEM_Add_Reference_ret |
end if |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
;;MEM_Add_Reference_Linear |
;; eax - linear address of page |
;;Result: |
;; eax=1 - success |
;; eax=0 - failed |
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; |
if used MEM_Add_Reference_Linear |
MEM_Add_Reference_Linear: |
push ebx |
push ecx |
call MEM_Heap_Lock |
call MEM_Get_Heap_Number_Linear |
test eax,eax |
jz MEM_Add_Reference_Linear_ret |
mov ecx,[MEM_heap_block+ecx+.heap_linear_address] |
sub eax,ecx |
shr eax,10 |
and eax,0xFFFFFFFC |
test dword [ecx+eax+.range_info],0x80000000 |
jnz MEM_Add_Reference_Linear_failed |
inc dword [ecx+eax+.range_info] |
mov eax,1 |
MEM_Add_Reference_Linear_ret: |
call MEM_Heap_UnLock |
pop ecx |
pop ebx |
ret |
MEM_Add_Reference_Linear_failed: |
xor eax,eax |
jmp MEM_Add_Reference_Linear_ret |
end if |
end if ;memmanager.inc |