I hope that my code is commented good enough!
Code: Select all
;----------------------------
; Output:
; EAX = address of page -> 0 - error
alloc_4kb_page_bottom:
cmp dword[mem_free_4kb],0
je .end_not_engh
mov eax,[mem_bottom_4kb] ;get the first free 4kb page
mov ecx,eax ;save it in ecx
shr eax,5
shl eax,2 ;eax/32*4
mov esi,80000h ;start of memory bitmap
add esi,eax ;add 4byte position of the free page
mov edi,esi ;save it in edi
shl eax,3 ;eax*16
sub ecx,eax ;free page number minus the 4byte position
mov ebx,1 ;mark the first bit
shl ebx,cl ;get the bit from the free page
lodsd
or eax,ebx
stosd
dec dword[mem_free_4kb]
cmp dword[mem_free_4kb],0
jne .loop0
mov eax,[mem_bottom_4kb]
shl eax,12
mov dword[mem_bottom_4kb],0
mov dword[mem_top_4kb],0
jmp .end
.loop0
test eax,ebx ;test if it is an used or an unused page
je .found
shl ebx,1 ;shl ebx per 1 till the carry flag is set
jnc .loop0
mov eax,esi ;get the address
sub eax,80000h ;sub the start of the memory bitmap
and eax,7fh ;look if it can dividie by 80h -> which means that we reached a new 4mb page
jz .loop1
lodsd ;next 32bits of the memory bitmap
mov ebx,1
jmp .loop0 ;searches the new 32bit of the memory bitmap
.loop1
dec eax ;we need the 4mb page before the new page
shr eax,7 ;div eax by 128 to get the number of the 4mb page
mov ecx,eax
shr eax,5
shl eax,2 ;eax/32*4
mov esi,7fc00h ;start of 4mb page bitmaps
add esi,eax ;add 4byte position of the 4mb page
mov edi,esi
shl eax,3 ;eax*16
sub ecx,eax ;4mb page number minus the 4byte position
mov ebx,1 ;mark the first bit
shl ebx,cl ;get the bit from the 4mb page
lodsd
or eax,ebx ;mark the page as used -> there is no free 4kb page on this 4mb page
stosd
.loop2
test eax,ebx
je .end_loop2
shl ebx,1
jnc .loop2
lodsd
jmp .loop2 ;searches for a new 4mb page where are free 4kb pages
.end_loop2
mov eax,ebx
call bit_pos2number
mov ebx,eax
sub esi,7fc00h ;to get the 4byte position of the new 4mb page
mov eax,esi
sub eax,4 ;we need the old value
shl eax,3 ;eax*8
add eax,ebx ;get the number of the new 4mb page
shl eax,7 ;eax*128
mov esi,80000h
add esi,eax ;get the position of the new 4mb page in the 4kb bitmap
lodsd
mov ebx,1
jmp .loop0
.found
mov eax,[mem_bottom_4kb] ;get the old 4kb page
shl eax,12 ;eax*4096 to have the right byte address
push eax
mov eax,ebx
call bit_pos2number
mov ebx,eax
sub esi,80000h
mov eax,esi
sub eax,4 ;because we need the old esi address
shl eax,3 ;eax*8
add eax,ebx
mov [mem_bottom_4kb],eax ;save the new 4kb page
pop eax
push eax
and eax,3fffffh
jnz .end ;only jump when the address is no 4mb address
shr eax,22 ;eax*4194304
mov ecx,eax ;save eax
shr eax,5
shl eax,2 ;eax/32*4
mov esi,7fe00h ;address of 4mb page bitmap
add esi,eax ;add 4byte position
mov edi,esi ;save esi
shl eax,3 ;eax*8
sub ecx,eax ;4mb page number minus the 4byte position
mov ebx,1 ;mark the first bit
shl ebx,cl ;get the position of the page
lodsd
or eax,ebx ;mark the page used
stosd
.loop3
test eax,ebx
je .end_loop3
shl ebx,1
jnc .loop3
mov ebx,1
jmp .loop3 ;searches for a new free 4mb page
.end_loop3
mov eax,ebx
call bit_pos2number
mov ebx,eax
sub esi,7fe00h
mov eax,esi ;get the 4byte position of the new page
sub eax,4 ;because we need the old value
shl eax,3 ;eax*8
add eax,ebx
mov [mem_bottom_4mb],eax ;get the new position of the new 4mb page and save it
.end
pop eax
ret
.end_not_engh
xor eax,eax
ret
;----------------------------
;----------------------------
; converts a bit position to the number of the position
; Input:
; EAX - bit position
; Output:
; EAX - number
bit_pos2number:
mov ecx,0ffffffffh
.loop
inc ecx
shr eax,1
jnc .loop
mov eax,ecx
.end
ret
;----------------------------