Friday, March 27, 2009

linux-0.11-mm-1

unsigned long get_free_page(void)
{
register unsigned long __res asm("ax");// AS(16bit) consists of AH(8bit) and AL (8bit)
// repne: %cx is decremented by 1 each cycle.
__asm__("std ; repne ; scasb\n\t" //"scasb"compare 0(%1) with %edi:end of mem_map(%4) repne: repeat if ZF=0.doesn't find empty page
"jne 1f\n\t" // JUMP IF ZF(zero flag in EFLAGS) =0. when reach here, ZF=1.(No more page ZF=0)
"movb $1,1(%%edi)\n\t"//Found empty page.Mark used.after executed "scasb",pointed to next position.so need to add 1 before set
"sall $12,%%ecx\n\t" // multiple %ecs 12 times. %edi is the destination of string operation.4MbX (target page)=relative ADD.
"addl %2,%%ecx\n\t" //%2 LOW_MEM. LOW_MEM + relative address = absolute address
"movl %%ecx,%%edx\n\t" // save to %edx
"movl $1024,%%ecx\n\t" // set counts
"leal 4092(%%edx),%%edi\n\t" // move to the end point of target page.
"rep ; stosl\n\t" // move %eax // copy AL = 0 to %edi and %edi decrement. initialize this page.
"movl %%edx,%%eax\n" // %edx the begining of this page. send to output.
"1:"
:"=a" (__res) // %eax
:"0" (0),"i" (LOW_MEM),"c" (PAGING_PAGES), // "c"--> %ecx "i"-->> a constant value
"D" (mem_map+PAGING_PAGES-1) // D -->>> %edi
:"di","cx","dx");
return __res;
}

No comments: