/** 0.11用了 unsigned char */
static unsigned short mem_map [ PAGING_PAGES ] = {0,};
/*
* Get physical address of first (actually last :-) free page, and mark it
* used. If no free pages left, return 0.
*/
/*
申请页,返回页面线性地址, 失败返回0
"std ; repne ; scasb
"
这行代码的作用是“置为方向,al(0) 与对应每个页面的di 做比较”
如果标志DF为0,则 inc EDI;如果DF为1,则 dec EDI。
默认edi是最后一页对应的下标
ecx总页数
//
将%edi+2 处的内容置为1, 表示该页已被分配,因为%edi 始终指向前一个字,所以要加2,才表示刚才对应 mem_map 的地址
*/
unsigned long get_free_page(void)
{
register unsigned long __res;
__asm__ __volatile__("std ; repne ; scasw
" /* AX - [ES:EDI] != 0 && ECX > 0继续查找 执行完scasb之后ecx - 1, edi -1 */
"jne 1f
" /* 没找到 */
"movw $1,2(%%edi)
" //如果找到了空闲页,那么执行这指令,然后把该页对应页面内存映像比特位置1.表示占用此页。注意edi寄存器的初始值是LOW_MEM 0x1000
"sall $12,%%ecx
"
"movl %%ecx,%%edx
"
"addl %2,%%edx
" //ecx 储存了页面号右移12位并且加上LOW_MEM,即可得到对应页面的地址
"movl $1024,%%ecx
"
"leal 4092(%%edx),%%edi
"
"rep ; stosl
" //内存页edi所指的内存反向清0
"movl %%edx,%%eax
"
"1:"
:"=a" (__res)
:"0" (0),"i" (LOW_MEM),"c" (PAGING_PAGES),
"D" (mem_map+PAGING_PAGES-1)
:"dx");
return __res;
}
http://www.tuicool.com/articles/UbeYZb
http://wenku.baidu.com/link?url=AApX6qSQB3cso2vjhFEhdeWj-g7q47SC9lyxv2uJtOJXmeW0bZaX8Xw4JyKGegdbvpCBXyL5GRw7uvNEWWBS9K7QyPXkDccF-DNaIGewoli