linux内核函数 ffs,linux内核中的宏ffs(x)
转自: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)相关推荐
- linux c语言内核函数手册,Linux C函数实例速查手册
函数学习目录: 第1章 初级I/O函数 1.1 close函数:关闭已经打开的文件 1.2 creat函数:创建一个文件 1.3 dup函数:复制文件描述符 1.4 dup2函数:复制文件描述符到指定 ...
- linux应用调用内核函数,Hooking linux内核函数(一):寻找完美解决方案
前言 我们最近参与了一个Linux系统安全相关项目,需要hooking几个重要的Linux内核函数调用,例如打开文件和启动进程,并利用它来启用系统活动监控并抢先阻止可疑进程. 最后,我们发明了一种有效 ...
- linux进程函数钩子,linux中钩子函数的理解
看了一个回调函数,想再了解一下钩子函数,以下为在网络上查找的一些有用资料,记录一下: 钩子函数(回调函数)也是系统内核为驱动程序提供的一些特定的函数, 在驱动程序中某个变量的状态发生改变或将要改变或改 ...
- linux signal函数用法,linux信号机制之sigaction构造体浅析,signal 函数,信号捕捉.
来自:http://hi.baidu.com/phenix_yw/blog/item/6eb4ca391d1479f23a87ce19.html 信号安装函数sigaction(int signum, ...
- linux c++ 函数效率,Linux C++程序进行性能分析工具gprof使用入门
性能分析工具 软件的性能是软件质量的重要考察点,不论是在线服务程序还是离线程序,甚至是终端应用,性能都是用户体验的关键.这里说的性能重大的范畴来讲包括了性能和稳定性两个方面,我们在做软件测试的时候也是 ...
- linux打印函数名,linux kernel 打印函数指针对应的函数名方法
linux kernel 打印函数指针对应的函数名方法 内核中函数指针用的很多,在debug 的时候能直接打印出一个函数指针对应的函数就会很方便. 打印裸指针(raw pointer)用 %p,%p除 ...
- linux内核函数 ffs,linux内核中的宏ffs(x)【转】
linux内核中ffs(x)宏是平台相关的宏,在arm平台,该宏定义在 arch/arm/include/asm/bitops.h #define ffs(x) ({ unsigned long __ ...
- linux do_irq 报错 代码,linux - 内核函数asm_do_IRQ()中的irq与我在模块中请求的不同 - 堆栈内存溢出...
我做了一些皮质-A9开发板的实验. 我使用gpio_to_irq()获取irq num并且我请求了irq并用它写了一个小驱动程序,它在syslog中是196. 我在asm_do_IRQ中添加了一些pr ...
- linux内核函数kmalloc,Linux内核内存分配函数之devm_kmalloc和devm_kzalloc
本文介绍Linux内核内存分配函数devm_kmalloc()和devm_kzalloc(). 一.devm_kmalloc 文件:drivers/base/devres.c,定义如下: /** * ...
最新文章
- 运行从别处复制过来的linux可执行程序
- 基于nginx和uWSGI在Ubuntu系统上部署Django项目
- 计算机核心配件是什么,计算机的核心是什么
- 【PAT甲级 替换指定字符】1035 Password (20 分) Java版 4/4通过
- c++学习笔记之基础---类内声明线程函数的调用
- php获取url传参数乱码问题,php url地址栏传中文值乱码问题与解决方法
- Java NIO学习篇之直接缓冲区和非直接缓冲区
- 软件的艺术之美源于权衡(Trade-off)
- 【UWP通用应用开发】控件、应用栏
- struts2 拦截器_Struts2 execAndWait拦截器示例,用于长时间运行的动作
- HWUI(硬件加速绘制UI)简介
- sublime php code sniffer,mac下sublime text3的php错误提示插件php code sniffer安装后,无法显示php错误...
- html怎么读取2进制视频,IE 中如何读取二进制文件的内容?
- JavaFX Scene Builder支持JxBrowser
- 看完浪曦相关视频后的感受
- 密码行业标准委员会公布的国家行业标准
- 聊一聊数学中的基本定理(二)——算术基本定理的价值
- audio2mid:音频提取主旋律
- 计算机共享在哪里找,电脑共享文件在哪里找
- python分位数回归模型_分位数回归及其Python源码导读