linux内核中ffs(x)宏
来源:互联网 发布:好用的网络机顶盒 编辑:程序博客网 时间:2024/06/11 16:41
linux内核中ffs(x)宏是平台相关的宏,在arm平台,该宏定义在
arch/arm/include/asm/bitops.h
#define ffs(x) ({ unsigned long __t = (x); fls(__t & -__t); })
static inline int fls(int x){ int ret; if (__builtin_constant_p(x)) return constant_fls(x); asm("clz\t%0, %1" : "=r" (ret) : "r" (x) : "cc"); ret = 32 - ret; return ret;}
__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, r=2. 由于__t&-__t只有一个1,所以就是找到该1的位置.
如果输入参数是00001010 那么 r=4.
如果参数是变量,直接使用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关于位操作的函数,可以作为自己写应用程序时的有用参考.
- linux内核中ffs(x)宏
- Linux ffs 命令
- Linux ffs()函数
- True FFS内核编程(简单笔记)
- linux 内核驱动中__attribute__((alias(#x)))别名问题
- 在linux 4.x内核中增加系统调用
- linux 2.6x内核升级
- linux 内核宏定义:#define typecheck(type,x)
- ffs算法
- Linux 2.4.x内核中网络协议栈QoS模块(TC)的设计与实现
- linux内核源码中常见宏定义
- Linux内核中container_of宏的理解
- Linux内核中container_of宏的理解
- linux内核源码中常见宏定义
- Linux内核中container_of宏的理解
- linux内核中两个常见宏定义
- Linux内核源代码中常见的宏
- Linux内核中CONFIG_OF宏的解释
- python中time类型,datetime类型的关系与互相转换
- 千万别总跟孩子说我生气了
- C++ 友元与继承
- 深入理解Hadoop集群和网络
- 教你如何求多项式的系数
- linux内核中ffs(x)宏
- 网站统计中的数据收集原理及实现
- struts2上传文件
- do...while(0)的妙用
- Android Annotation注解的剖析和使用
- 子集生成
- VS2010 错误failure during conversion to COFF解决办法
- 开启守护进程daemon
- 推荐系统的常用算法概述