/*
34 * Get physical address of first (actually last :-) free page, and mark it
35 * used. If no free pages left, return 0.
36 */
unsigned long get_free_page(void)
{
register unsigned long __res asm("ax"); __asm__("std ; repne ; scasw\n\t"
"jne 1f\n\t"
"movw $1,2(%%edi)\n\t" //将对应页面的内存映像置1(使用)
"sall $12,%%ecx\n\t"   //页面数*4kb=相对LOW_MEMORY的页面起始地址
"movl %%ecx,%%edx\n\t"    //加上LOW_MEMORY形成物理起始地址
"addl %2,%%edx\n\t"       //页面实际地址给edx
"movl $1024,%%ecx\n\t"
"leal 4092(%%edx),%%edi\n\t" //将该页面的末端地址给edi
"rep ; stosl\n\t" //将edi所指内存请0
"movl %%edx,%%eax\n"
"1:"
:"=a" (__res)
:"" (),"i" (LOW_MEM),"c" (PAGING_PAGES),
"D" (mem_map+PAGING_PAGES-)
:"di","cx","dx");
return __res;
}

这段代码的作用是获取一个空闲的内存页,并且返回它的地址。

首先分析,std ; repne ;scasw 这三句的作用。首先,我们参考一下下面这这篇文章:http://blog.163.com/b____d/blog/static/7491166020099115207391/

那么,我们来分析一下这个函数里含义。首先,在这三句代码执行以前,asm已经将参数装入寄存器。即:

%1(ax=0) %2(LOW_MEM)  %3(cx=PAGING_PAGES)  %4(edi=mem_map+PAGING_PAGES-1) 。这里注意的是,参数%1 "0" (0),”0“表示使用和输出相同的寄存器。即eax。

这样,这三句话的含义就很清楚了,它的作用是从edi指代的地址搜索,如果找到0位,则返回。直到检索了PAGING_PAGES长度。

也就是说,这三句指令在mem_map[ ]数组中寻找0位,并且该0位的index存储在edx中。

疑问:系统页面长度为4096bit,为何将页面内容清0时,赋予计数器ecx的值是1024而不是4096?

答:关注这里的清零指令,rep;stosl

  STOSL指令相当于将EAX中的值保存到ES:EDI指向的地址中,若设置了EFLAGS中的方向位置位(即在STOSL指令前使用STD指令)则EDI自减4,否则(使用CLD指令)EDI自增4。

  由此可见,stosl每次将4个bit清零。因此计数器赋值1024。同理,这样是为什么edi的初始值被赋予4092而不是4095

linux源代码阅读笔记 get_free_page()代码分析的更多相关文章

  1. linux源代码阅读笔记 find_entry分析

    78 static struct buffer_head * find_entry(struct m_inode * dir, 79 const char * name, int namelen, s ...

  2. linux源代码阅读笔记 free_page_tables()分析

    /* 77 * This function frees a continuos block of page tables, as needed 78 * by 'exit()'. As does co ...

  3. linux源代码阅读笔记 linux文件系统(转)

    linux文件系统:   操作系统的文件数据除了文件实际内容外,还有非常多的属性,如文件权限(rwx)与文件属性(所有者.群组.时间参数等).   文件系统通常将这两部分数据存放在不同的块.权限属性放 ...

  4. linux源代码阅读笔记 高速缓冲区管理

    高速缓冲区是文件系统访问块设备中数据的必经要道,为了访问文件系统等块设备上的数据,内核可以每次都访问块设备,进行读写操作. 为了提高系统性能,内核在内存中开辟一个高速数据缓冲区.在Linux内核中,高 ...

  5. linux源代码阅读笔记 linux文件系统(二)

    上一篇文章说到linux文件系统中分为超级块,inode块,block块.inode块给出文件的权限,修改时间,大小等信息. 但是实际上,文件的数据是存储在block块中的.而inode块中给出了存储 ...

  6. linux源代码阅读笔记 fork和execve的区别

    1. man exec就可以知到: The exec() family of functions replaces the current process image with a new proce ...

  7. linux源代码阅读笔记 linux文件系统(三)

    当系统申请一个新的inode时.系统并不会对磁盘进行读写.它会在存储在内存的inode表(inode_table)中寻找一个空闲的位置. 如果找到了,直接返回该inode.否则要等待一个空闲的位置. ...

  8. linux源代码阅读笔记 八进制

    c语言中,众所周知,以0x开头的数是16进制数.例如 0x8FFF 然而较少使用的是八进制数.它以0开头.例如 01234

  9. CI框架源代码阅读笔记3 全局函数Common.php

    从本篇開始.将深入CI框架的内部.一步步去探索这个框架的实现.结构和设计. Common.php文件定义了一系列的全局函数(一般来说.全局函数具有最高的载入优先权.因此大多数的框架中BootStrap ...

随机推荐

  1. (转)Yale CAS + .net Client 实现 SSO(5)

    第一部分:安装配置 Tomcat 第二部分:安装配置 CAS 第三部分:实现 ASP.NET WebForm Client 第四部分:实现基于数据库的身份验证 第五部分:扩展基于数据库的身份验证 1. ...

  2. Myeclipse安装svn插件(link方式)

    Myeclipse安装svn插件(link方式) 优点:1.离线安装2.非侵入式 演示版本 myeclipse--myeclipse8.6 svn--subeclipse-site-1.6.5.zip ...

  3. POJ 2837 Til the Cows Come Home

    Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 45515   Accepted: 15434 Description Bes ...

  4. Linux platform设备简介

    Technorati 标签: Linux platform     Linux在2.6内核中,针对一系列设备驱动,提供新的管理框架,成为platform机制,推出的目的,在于隔离驱动的资源和实现,使得 ...

  5. 【风马一族_git_github】gitGui与github的SSH

    权限校验 首先,您的数据保存在远端服务器一份,服务器需要对您的身份识别.一段RSA加密字符串. 启动GUI,菜单-帮助,[Step1-创建密钥]Generate SSH KEY 步骤一: 步骤二: 步 ...

  6. zedboard OPENCV移植

    1:系统环境搭建 要准备好交叉编译环境 见http://blog.csdn.net/xiabodan/article/details/22717175 2:下载cmake CMake是一个跨平台的安装 ...

  7. linux命令行解析函数介绍

    函数原型:         int getopt(int argc,char * const argv[ ],const char * optstring);         给定了命令参数的数量 ( ...

  8. 将double类型的值保留几位小数

    1.第一个参数(3.1415926)是要处理的数值.第二个参数(1)为要保留的几位小数.第三个参数是按照“四舍五入”还是"直接取这一位的值"(MidpointRounding.To ...

  9. 七天学会NodeJS-学习笔记

    在网上发现一篇nodeJS教程,名为七天学会NodeJS,标题很有吸引力.我不指望七天能学会,只希望可以入门,下面是我的学习笔记和遇到的问题. 教程网址:http://nqdeng.github.io ...

  10. 数据库操作类util

    package util; import java.sql.Connection; import java.sql.Driver; import java.sql.DriverManager; imp ...