bit位快速查询asm实现(find

    技术2022-06-27  68

    最近在重翻些FS的代码,file open的时候首先要获取unused fd, 例如如下:

    /* * Find an empty file descriptor entry, and mark it busy. */int get_unused_fd(void){ struct files_struct * files = current->files; int fd, error;

       error = -EMFILE; write_lock(&files->file_lock);

    repeat:  fd = find_next_zero_bit(files->open_fds,     files->max_fdset,     files->next_fd);

    ........................

     

     这里重点研究下find_next_zero_bit,这里是从open_fds中找到空隙的fd,翻开这块内部代码:

    先温习下这里的几个重点asm命令(intel):

    bsfl:

          bsfl source, destination

         从右向左(0->15,31位)在source中找到非0的位置,并保存在destination

    scasl:

         扫描EDI(隐含源)和EAX的匹配度,和repe,repne结合

         比如 repe; scasl;

         含义:如果EDI和EAX等值,继续loop, until到不匹配

     

    static __inline__ int find_next_zero_bit (void * addr, int size, int offset){ unsigned long * p = ((unsigned long *) addr) + (offset >> 5); int set = 0, bit = offset & 31, res;  if (bit) {  /*   * Look for zero in first byte   */  __asm__(

       //从offset开始的INT查找bit 1,

       "bsfl %1,%0/n/t"   "jne 1f/n/t"   "movl $32, %0/n"   "1:"   : "=r" (set)

       // 注意取反,目标是look zero,   : "r" (~(*p >> bit)));  if (set < (32 - bit))   return set + offset;  set = 32 - bit;  p++; } /*  * No zero yet, search remaining full bytes for a zero  */ res = find_first_zero_bit (p, size - 32 * (p - (unsigned long *) addr)); return (offset + set + res);}

     

     

    /* * Find-bit routines.. */static __inline__ int find_first_zero_bit(void * addr, unsigned size){ int d0, d1, d2; int res;

     if (!size)  return 0; /* This looks at memory. Mark it volatile to tell gcc not to move it around */ __asm__ __volatile__(

     // EAX赋值0xFFFFFFFF  "movl $-1,%

    转载请注明原文地址: https://ibbs.8miu.com/read-2234446.html

    最新回复(0)