find_next_zero_bit 是否是不可到达的代码? - 《Linux内核完全注释》《完全剖析》 - OldLinux - Powered by Discuz!

来源:互联网 发布:手机电路设计软件 编辑:程序博客网 时间:2024/05/22 03:32
导读:

内核版本2。4。0
/include/asm-i386/bitops.h
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__("bsfl %1,%0/n/t"
"jne 1f/n/t"
"movl $32, %0/n"
"1:"
: "=r" (set)
: "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);
}
如果bit不为0,则因为*p是unsigned long类型, *p >> bit必然不可能为全1(0xffffffff),(~(*p >> bit))自然不可能是0,那么"jne 1f/n/t"跳转条件必然成立,这样一来"movl $32, %0/n"岂不形同虚设?(can,t rearch?)
这个问题也是我在http://www.linuxforum.net/forum/showthreaded.php?Cat=&Board=linuxK&Number=489512&Search=true&Forum=linuxK&Words=%B2%BB%BF%C9%B5%BD%B4%EF&Match=Entire%20Phrase&Searchpage=0&Limit=25&Old=allposts&Main=489512这里问过的,不过也没能解决掉
据说这段代码还是LINUS本人写的
大家来看看吧

 

>>如果bit不为0,则因为*p是unsigned long类型, *p >> bit必然不可能为全1 >>(0xffffffff),(~(*p >> bit))自然不可能是0,那么"jne 1f/n/t"跳转条件必然 >>成立,这样一来"movl $32, %0/n"岂不形同虚设?(can,t rearch?) bit = offset & 31, 因此 bit 取值<31. *p >> bit 相当于把*p的32bit值整除bit^2 若*p = 0b0000,0000,0000,0000,0000,0000,0000,0010 = 0x00000002 bit = 0x08 则 *p >> bit 肯定为0

 



QUOTE:

下面引用由wizardwarren2004/07/16 05:26pm 发表的内容: 你好像没看清楚 (~(*p >> bit))自然不可能是0,那么"jne 1f/n/t"跳转条件必然成立是(~(*p >> bit))而不是*p >> bit


bit = offset & 31, 因此 bit 取值<=31.会在*p长字中寻找是zero的比特位。 *p >> bit 相当于把*p的32bit值整除bit^2 若*p = 0b1111,1111,1111,1111,1111,1111,1111,1111 = 0xffffffff bit = 0x04 则 (*p >> bit) 为0b0000,1111,1111,1111,1111,1111,1111,1011 = 0x0fffffff ~(*p >> bit) 为0xf0000000 于是bsfl指令会将ZF复位,并且set被置为28。若*p = 0b1111,1111,1111,1111,1111,1111,1111,1101 = 0xfffffffd bit = 0x04 则 *p >> bit 肯定为0b0000,1111,1111,1111,1111,1111,1111,1111 ~(*p >> bit) 为0xf0000000 于是bsfl指令会将ZF复位,set为28。若*p = 0b1111,1111,1111,1111,1111,1111,1011,1111 = 0xffffffbf bit = 0x04 则 (*p >> bit) 为0b0000,1111,1111,1111,1111,1111,1111,1011 = 0x0ffffffb ~(*p >> bit) 为0xf0000004 于是bsfl指令会将ZF复位,并且set被置为2。 在这里jne的确肯定满足。"movl $32, %0"无用。






本文转自
http://oldlinux.org/oldlinux/viewthread.php?tid=1982
原创粉丝点击