转自:https://www.cnblogs.com/fengeryi/p/3449720.html

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,linux内核中的宏ffs(x)相关推荐

  1. linux c语言内核函数手册,Linux C函数实例速查手册

    函数学习目录: 第1章 初级I/O函数 1.1 close函数:关闭已经打开的文件 1.2 creat函数:创建一个文件 1.3 dup函数:复制文件描述符 1.4 dup2函数:复制文件描述符到指定 ...

  2. linux应用调用内核函数,Hooking linux内核函数(一):寻找完美解决方案

    前言 我们最近参与了一个Linux系统安全相关项目,需要hooking几个重要的Linux内核函数调用,例如打开文件和启动进程,并利用它来启用系统活动监控并抢先阻止可疑进程. 最后,我们发明了一种有效 ...

  3. linux进程函数钩子,linux中钩子函数的理解

    看了一个回调函数,想再了解一下钩子函数,以下为在网络上查找的一些有用资料,记录一下: 钩子函数(回调函数)也是系统内核为驱动程序提供的一些特定的函数, 在驱动程序中某个变量的状态发生改变或将要改变或改 ...

  4. linux signal函数用法,linux信号机制之sigaction构造体浅析,signal 函数,信号捕捉.

    来自:http://hi.baidu.com/phenix_yw/blog/item/6eb4ca391d1479f23a87ce19.html 信号安装函数sigaction(int signum, ...

  5. linux c++ 函数效率,Linux C++程序进行性能分析工具gprof使用入门

    性能分析工具 软件的性能是软件质量的重要考察点,不论是在线服务程序还是离线程序,甚至是终端应用,性能都是用户体验的关键.这里说的性能重大的范畴来讲包括了性能和稳定性两个方面,我们在做软件测试的时候也是 ...

  6. linux打印函数名,linux kernel 打印函数指针对应的函数名方法

    linux kernel 打印函数指针对应的函数名方法 内核中函数指针用的很多,在debug 的时候能直接打印出一个函数指针对应的函数就会很方便. 打印裸指针(raw pointer)用 %p,%p除 ...

  7. linux内核函数 ffs,linux内核中的宏ffs(x)【转】

    linux内核中ffs(x)宏是平台相关的宏,在arm平台,该宏定义在 arch/arm/include/asm/bitops.h #define ffs(x) ({ unsigned long __ ...

  8. linux do_irq 报错 代码,linux - 内核函数asm_do_IRQ()中的irq与我在模块中请求的不同 - 堆栈内存溢出...

    我做了一些皮质-A9开发板的实验. 我使用gpio_to_irq()获取irq num并且我请求了irq并用它写了一个小驱动程序,它在syslog中是196. 我在asm_do_IRQ中添加了一些pr ...

  9. linux内核函数kmalloc,Linux内核内存分配函数之devm_kmalloc和devm_kzalloc

    本文介绍Linux内核内存分配函数devm_kmalloc()和devm_kzalloc(). 一.devm_kmalloc 文件:drivers/base/devres.c,定义如下: /** * ...

最新文章

  1. 运行从别处复制过来的linux可执行程序
  2. 基于nginx和uWSGI在Ubuntu系统上部署Django项目
  3. 计算机核心配件是什么,计算机的核心是什么
  4. 【PAT甲级 替换指定字符】1035 Password (20 分) Java版 4/4通过
  5. c++学习笔记之基础---类内声明线程函数的调用
  6. php获取url传参数乱码问题,php url地址栏传中文值乱码问题与解决方法
  7. Java NIO学习篇之直接缓冲区和非直接缓冲区
  8. 软件的艺术之美源于权衡(Trade-off)
  9. 【UWP通用应用开发】控件、应用栏
  10. struts2 拦截器_Struts2 execAndWait拦截器示例,用于长时间运行的动作
  11. HWUI(硬件加速绘制UI)简介
  12. sublime php code sniffer,mac下sublime text3的php错误提示插件php code sniffer安装后,无法显示php错误...
  13. html怎么读取2进制视频,IE 中如何读取二进制文件的内容?
  14. JavaFX Scene Builder支持JxBrowser
  15. 看完浪曦相关视频后的感受
  16. 密码行业标准委员会公布的国家行业标准
  17. 聊一聊数学中的基本定理(二)——算术基本定理的价值
  18. audio2mid:音频提取主旋律
  19. 计算机共享在哪里找,电脑共享文件在哪里找
  20. python分位数回归模型_分位数回归及其Python源码导读

热门文章

  1. 小米6MIUI稳定版安装谷歌相机
  2. 返回到上一个页面并刷新页面
  3. 在KubeSphere中部署微服务(阡陌)+ DevOps
  4. 哪位仁兄在狂顶精华贴?
  5. SSD固态硬盘和HDD机械硬盘的区别
  6. Git命令全解析-前端备忘录
  7. 2022基金从业考试如何备考
  8. 大三学生简历_不要再问那些没有的高级开发人员了。 开始指导大三学生。
  9. 水山蹇:自救者天救;雷水解:拯焚救溺
  10. fuchsia中virtio 后端实现