Linux内核源码分析—Linux内核中的嵌入式汇编

来源:互联网 发布:淘宝不交保证金 编辑:程序博客网 时间:2024/06/05 00:16

转载请注明出处:

http://blog.csdn.net/weifenghai/article/details/52794872

 

概述:

内核中分配文件描述符时找第一个0的位置的一个底层函数,了解Linux内核嵌入式汇编知识参见《LINUX内核源代码情景分析(上)》中的1.5节《1.5Linux内核源代码中的汇编语言代码》,内核汇编指令参见《汇编语言程序设计(美)布鲁姆_着,马朝晖_等译》,代码摘自2.6.11.1内核。

函数代码:

/**

 *find_first_zero_bit - find the first zero bit in a memory region

 *@addr: The address to start the search at

 *@size: The maximum size to search

 *

 *Returns the bit-number of the first zero bit, not the number of the byte

 *containing a bit.

 */

static inline int find_first_zero_bit(constunsigned long *addr, unsigned size)

{

         intd0, d1, d2;

         intres;

 

         if(!size)

                   return0;

         /*This looks at memory. Mark it volatile to tell gcc not to move it around */

         __asm__ __volatile__(

                   "movl$-1,%%eax\n\t"

                   "xorl%%edx,%%edx\n\t"

                   "repe;scasl\n\t"

                   "je1f\n\t"

                   "xorl-4(%%edi),%%eax\n\t"

                   "subl$4,%%edi\n\t"

                   "bsfl%%eax,%%edx\n"

                   "1:\tsubl%%ebx,%%edi\n\t"

                   "shll$3,%%edi\n\t"

                   "addl%%edi,%%edx"

                   :"=d"(res), "=&c" (d0), "=&D" (d1), "=&a"(d2)

                   :"1"((size + 31) >> 5), "2" (addr), "b" (addr) :"memory");

         returnres;

}

代码分析:

输出部:

代码::"=d" (res), "=&c" (d0), "=&D"(d1), "=&a" (d2)

解释:

%0: res放入edx

%1: d0放入ecx

%2:d1放入edi

%3:d2放入eax

输入部:

代码::"1" ((size + 31) >> 5), "2" (addr),"b" (addr)

    %4:与$1相同,(size + 31) >>5放入ecx

    %5:与$2相同,addr放入edi

    %6:addr 放入ebx

损坏部:: "memory"

指令部:

                   "movl$-1,%%eax\n\t":把eax的所有位都置成1

                   "xorl%%edx,%%edx\n\t":把edx置0

                   "repe;scasl\n\t":在edi(即addr)中搜索与eax不匹配的(即不全为1的)

                   "je1f\n\t" 没有找到

                   "xorl-4(%%edi),%%eax\n\t"  把eax中edi为0的位置1,其它位置0

                   "subl$4,%%edi\n\t"  edi存当前找到的位置

                   "bsfl%%eax,%%edx\n" edx存放eax中从右边第一个为1的位的索引,从0开始,edx存放目标字节内的偏移

                   "1:\tsubl%%ebx,%%edi\n\t"   现在edi中存放字节偏移位置

                   "shll$3,%%edi\n\t"    edi左移3位,存偏整体移位数

                   "addl%%edi,%%edx"   计算偏移位数

 

转载请注明出处:

http://blog.csdn.net/weifenghai/article/details/52794872
0 0
原创粉丝点击