互联网网站建设挣钱吗,阳江房产网二手房林夏婷经纪人,哪些网站做任务好赚钱,域名备案查询站长之家linux内核中的宏ffs(x) linux内核中ffs(x)宏是平台相关的宏,在arm平台,该宏定义在 arch/arm/include/asm/bitops.h #define ffs(x) ({ unsigned long __t (x); fls(__t -__t); }) __t -__t 等于找到__t 第一个为1的位(从低位开始),并把该位保留为1其余位清0. 例…linux内核中的宏ffs(x) linux内核中ffs(x)宏是平台相关的宏,在arm平台,该宏定义在 arch/arm/include/asm/bitops.h #define ffs(x) ({ unsigned long __t (x); fls(__t -__t); }) __t -__t 等于找到__t 第一个为1的位(从低位开始),并把该位保留为1其余位清0. 例如 一32位整形数 6,用二进制表示它的低8位:00000110, 都知道负数为最高为1其余位取反加1.-6即 11111010 相与得 00000010,即6-6. 把该值传递给函数fls(). 再看fls函数. if (__builtin_constant_p(x))return constant_fls(x); __builtin_constant_p 是Gcc的内建函数 用于判断一个值是否为编译时常数如果参数的值是常数函数返回 1否则返回 0。 如果是常数就用下面函数计算00000010中1的位置 static inline int constant_fls(int x)
{int r 32;if (!x)return 0;if (!(x 0xffff0000u)) {x 16;r - 16;}if (!(x 0xff000000u)) {x 8;r - 8;}if (!(x 0xf0000000u)) {x 4;r - 4;}if (!(x 0xc0000000u)) {x 2;r - 2;}if (!(x 0x80000000u)) {x 1;r - 1;}return r;
} 算法就是折半法,这个函数计算的是从高位起第一个1位的位置.00000010, r2. 由于__t-__t只有一个1,所以就是找到该1的位置. 如果输入参数是00001010 那么 r4. 如果参数是变量,直接使用arm指令运算. 执行 asm(clz\t%0, %1 : r (ret) : r (x) : cc);ret 32 - ret; CLZ(Count Leading Zeros)指令对Rm中值的高位leading zeros个数进行计数结果放到Rd中。若源寄存器全为0则结果为32。若[31]为1则结果为0。 clz指令计算高位0的个数, 然后拿32-ret 算出1的位置. 所以,ffs(x)这个宏的值就是x的第一个1的位置(从低位开始,数值从1开始,0代表x全0). 另外,该文件中还有很多linux关于位操作的函数,可以作为自己写应用程序时的有用参考. 转载于:https://www.cnblogs.com/qiyuexin/p/9095161.html