get_free_page

/**  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\n\t"

这行代码的作用是“置为方向,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\n\t" /* AX - [ES:EDI] != 0 && ECX > 0继续查找 执行完scasb之后ecx - 1, edi -1 */
    "jne 1f\n\t" /* 没找到 */
    "movw $1,2(%%edi)\n\t" //如果找到了空闲页,那么执行这指令,然后把该页对应页面内存映像比特位置1.表示占用此页。注意edi寄存器的初始值是LOW_MEM 0x1000
    "sall $12,%%ecx\n\t"   
    "movl %%ecx,%%edx\n\t"
    "addl %2,%%edx\n\t"        //ecx 储存了页面号右移12位并且加上LOW_MEM,即可得到对应页面的地址
    "movl $1024,%%ecx\n\t"    
    "leal 4092(%%edx),%%edi\n\t"
    "rep ; stosl\n\t" //内存页edi所指的内存反向清0
    "movl %%edx,%%eax\n"
    "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

posted @ 2015-05-07 20:01  mull  阅读(298)  评论(0编辑  收藏  举报