该文件用于分配和释放系统、用户页。
系统和用户页分开管理,并通过bit来记录每一页的分配状态,0为未分配,1为一分配。
其中,系统可用内存从132K到640K之中分配(虚拟地址);用户可分页内存硬件地址,从1M开始(硬件地址)。
Alloc_sys_page:分配一页系统内存;
Alloc_usr_page:分配一页用户内存;
find_a_null_page:从系统或用户内存堆中找到一页空闲页;
Free_sys_page:释放一页系统页;
Free_usr_page:释放一页用户页;
free_a_used_page:释放系统或用户页;
代码中的sys_page_heap为系统内存页的状态组,每一个bit代表一个系统页的当前状态;
代码中的usr_page_heap为用户内存页的状态组,每一个bit代表一个用户页的当前状态;
;===============================================================================
;=== 本程序为内容管理,其主要功能有: ===
;=== 1.系统内存的管理和释放 ===
;=== 2.用户内容的管理和释放 ===
;===============================================================================
;-------------------------------------------------------------------------------
Alloc_sys_page: ;分配一页系统内存(从128K-640K处,都是可分配系统页)
;输出参数: eax—-系统页的线性地址(返回0表示没有系统内存了)
push ebx
push ecx
push edx
mov eax, sys_page_heap ;系统堆对应的地址
mov ebx, 15 ;系统堆大小(字节数)
call find_a_null_page
mov eax, sys_page_addr ;系统页起始线性地址
shl ecx, 12 ;ecx对应第几页,左移12位=*4K,得到空闲页的偏移地址
add eax, ecx ;系统可分配内存起始地址加上页的偏移地址,得到空闲页的线性地址
pop edx
pop ecx
pop ebx
ret
;-------------------------------------------------------------------------------
Alloc_usr_page: ;分配一页用户内存(1M-2M,都是可分配用户页)
;输入参数: 无
;输出参数: eax—-用户页的硬件地址(返回0表示没有用户内存了)
push ebx
push ecx
push edx
mov eax, usr_page_heap ;用户堆对应的地址
mov ebx, 31 ;用户堆大小(字节数)
call find_a_null_page
mov eax, usr_page_addr ;用户页起始硬件地址
shl ecx, 12 ;ecx对应第几页,左移12位=*4K,得到空闲页的偏移地址
add eax, ecx ;用户可分配内存硬件地址加上页的偏移地址,得到空闲页的硬件地址
pop edx
pop ecx
pop ebx
ret
;-------------------------------------------------------------------------------
find_a_null_page: ;从系统或用户内存堆中找到一页空闲页
;输入:eax - 内存堆地址
;输入:ebx - 内存堆的大小(字节)
;输出:ecx - 第几页为空闲页; 0xffffffff为无空闲页
push ebp
push ebx ;[ebp]-记录内存堆大小
mov ebp, esp
xor ebx, ebx ;ebx用于记录空闲页对应的字节
xor ecx, ecx
xor edx, edx
_find_char: ;找到一个非全0的字节
mov dl, [eax + ebx]
cmp dl, 0xff ;如果字节位全1,找下一个字节
jz _get_next_data
xor cx, cx
mov dh, 0x1
_find_bit:
test dl, dh ;从低位到高位,测试第几位是0
jz _get_the_bit
inc cl ;加一
shl dh, 1 ;左移1位
jmp _find_bit
_get_next_data:
inc ebx ;下一个字节
cmp ebx, [ebp] ;是否到了末尾
jae _no_more_page ;到了末尾,说明空闲页寻找失败
jmp _find_char
_get_the_bit: ;找到空闲页
bts dx, cx ;页对应的bit位置1
mov [eax + ebx], dl ;写回内存堆
shl ebx, 3 ;ebx对应位第几字节,左移3 = *8
add ecx, ebx ;ecx中位找到的空闲页为第几页
pop ebx
pop ebp
ret
_no_more_page: ;所有空闲页已经用完
mov ecx, 0xffffffff ;ecx返回全1
pop ebx
pop ebp
ret
;-------------------------------------------------------------------------------
Free_sys_page: ;释放一页系统页
;输入:eax - 系统页的线性地址
;输出:无
sub eax, sys_page_addr
shr eax, 12 ;右移12位 = 除以4096,得到页的编号
mov ebx, sys_page_heap
call free_a_used_page
ret
;-------------------------------------------------------------------------------
Free_usr_page: ;释放一页用户页
;输入:eax - 用户页的硬件地址
;输出:无
sub eax, usr_page_addr
shr eax, 12 ;右移12位 = 除以4096,得到页的编号
mov ebx, usr_page_heap
call free_a_used_page
ret
;-------------------------------------------------------------------------------
free_a_used_page: ;释放系统或用户页
;输入:ebx - 内存堆地址
;输入:eax - 内存页号码
;输出:无
xor edx, edx
xor ecx, ecx
mov cl, 8 ;ax除以cl
div cl ;al - 商;ah - 余数
mov cl, ah ;保存余数
xor ah, ah
mov dl, [ebx + eax] ;获取对应字节
mov ch, 0x01
shl ch, cl ;字节对应位置1
not ch ;取反
and dl, ch ;“与”操作
mov [ebx + eax], dl ;写回内存堆
ret
;--------------------------------全局变量---------------------------------------
align 4
;设备一共2M内存,其中前1M为系统内存,系统可用内存从132K到640K之中分配
;系统内存分配起始地址: 132K
sys_page_addr equ 0xc0022000
;系统内存堆,16字节,128位,每一位对应一页, 0-未用,1-已用,最后一页不用
sys_page_heap db 0,0,0,0,0,0,0,0,
db 0,0,0,0,0,0,0,0xc0
;设备一共2M内存,后1M-2M为用户可用内存
;用户可分页内存硬件地址,从1M开始
usr_page_addr equ 0x00100000
;用户内存堆,32字节,256位,每一位对应一页, 0-未用,1-已用
usr_page_heap db 0,0,0,0,0,0,0,0,
db 0,0,0,0,0,0,0,0,
db 0,0,0,0,0,0,0,0,
db 0,0,0,0,0,0,0,0
align 4