关于linux bitops的使用
来源:互联网 发布:吴镇宇曹格 知乎 编辑:程序博客网 时间:2024/05/24 16:13
内核API没有通用的标准 即使在内核的文档和头文件也没详细给出
一个多平台开发中多处用到bitops 结果碰到许多问题
1
int find_first_zero_bit(void * addr, unsigned size);
int find_next_zero_bit(void * addr, int size, int offset);
找到0bit时,各平台都返回0~size-1
在x86下,没有找到0bit时,返回size
在arm下,没有找到0bit时,则返回size+1
所以通用的判断方法是,检查返回值是否>=size
2
test_bit
test_and_set_bit
test_and_clear_bit
0 bit 返回0是一定的
1 bit各个平台不一样 arm返回1 x86返回 ~0(全FF)
因此通用的检查方法是判断是0或者非0
3
2.6 引入了
find_first_bit
find_next_bit
用来查找1bit
内核头文件确实有了新的特性
但是在fc4的用户头文件中却没看到这个新特性,这个头文件在内核和用户空间不是应该一样么??
arm平台的uclinux中也没有,因此打算自己加上
它的实现在arch/armnommu/lib/findbits.S中
#include <linux/linkage.h>
#include <asm/assembler.h>
.text
/*
* Purpose : Find a 'zero' bit
* Prototype: int find_first_zero_bit(void *addr, int maxbit);
*/
ENTRY(find_first_zero_bit)
mov r2, #0
.bytelp: ldrb r3, [r0, r2, lsr #3]
eors r3, r3, #0xff @ invert bits
bne .found @ any now set - found zero bit
add r2, r2, #8 @ next bit pointer
cmp r2, r1 @ any more?
bcc .bytelp
add r0, r1, #1 @ no free bits
RETINSTR(mov,pc,lr)
/*
* Purpose : Find next 'zero' bit
* Prototype: int find_next_zero_bit(void *addr, int maxbit, int offset)
*/
ENTRY(find_next_zero_bit)
ands ip, r2, #7
beq .bytelp @ If new byte, goto old routine
ldrb r3, [r0, r2, lsr#3]
eor r3, r3, #0xff @ now looking for a 1 bit
movs r3, r3, lsr ip @ shift off unused bits
orreq r2, r2, #7 @ if zero, then no bits here
addeq r2, r2, #1 @ align bit pointer
beq .bytelp @ loop for next bit
/*
* One or more bits in the LSB of r3 are assumed to be set.
*/
.found: tst r3, #0x0f
addeq r2, r2, #4
movne r3, r3, lsl #4
tst r3, #0x30
addeq r2, r2, #2
movne r3, r3, lsl #2
tst r3, #0x40
addeq r2, r2, #1
mov r0, r2
RETINSTR(mov,pc,lr)
可以发现它的操作竟然是先将数字进行反转 即0->1 1->0后对1进行搜索
那简单的修改一下就应该能够搞定了
在代码后面加入下面代码
/*
* Purpose : Find a 'one' bit
* Prototype: int find_first_bit(void *addr, int maxbit);
*/
ENTRY(find_first_bit)
mov r2, #0
.bbytelp: ldrb r3, [r0, r2, lsr #3]
movs r3, r3 // 将xor改成movs 触发标志寄存器 保证下面的bne正确跳转
bne .bfound @ any now set - found zero bit
add r2, r2, #8 @ next bit pointer
cmp r2, r1 @ any more?
bcc .bbytelp
add r0, r1, #1 @ no free bits
RETINSTR(mov,pc,lr)
/*
* Purpose : Find next 'one' bit
* Prototype: int find_next_bit(void *addr, int maxbit, int offset)
*/
ENTRY(find_next_bit)
ands ip, r2, #7
beq .bbytelp @ If new byte, goto old routine
ldrb r3, [r0, r2, lsr#3]
movs r3, r3, lsr ip @ shift off unused bits
// 去掉了xor
orreq r2, r2, #7 @ if zero, then no bits here
addeq r2, r2, #1 @ align bit pointer
beq .bbytelp @ loop for next bit
/*
* One or more bits in the LSB of r3 are assumed to be set.
*/
.bfound: tst r3, #0x0f
addeq r2, r2, #4
movne r3, r3, lsl #4
tst r3, #0x30
addeq r2, r2, #2
movne r3, r3, lsl #2
tst r3, #0x40
addeq r2, r2, #1
mov r0, r2
RETINSTR(mov,pc,lr)
一个多平台开发中多处用到bitops 结果碰到许多问题
1
int find_first_zero_bit(void * addr, unsigned size);
int find_next_zero_bit(void * addr, int size, int offset);
找到0bit时,各平台都返回0~size-1
在x86下,没有找到0bit时,返回size
在arm下,没有找到0bit时,则返回size+1
所以通用的判断方法是,检查返回值是否>=size
2
test_bit
test_and_set_bit
test_and_clear_bit
0 bit 返回0是一定的
1 bit各个平台不一样 arm返回1 x86返回 ~0(全FF)
因此通用的检查方法是判断是0或者非0
3
2.6 引入了
find_first_bit
find_next_bit
用来查找1bit
内核头文件确实有了新的特性
但是在fc4的用户头文件中却没看到这个新特性,这个头文件在内核和用户空间不是应该一样么??
arm平台的uclinux中也没有,因此打算自己加上
它的实现在arch/armnommu/lib/findbits.S中
#include <linux/linkage.h>
#include <asm/assembler.h>
.text
/*
* Purpose : Find a 'zero' bit
* Prototype: int find_first_zero_bit(void *addr, int maxbit);
*/
ENTRY(find_first_zero_bit)
mov r2, #0
.bytelp: ldrb r3, [r0, r2, lsr #3]
eors r3, r3, #0xff @ invert bits
bne .found @ any now set - found zero bit
add r2, r2, #8 @ next bit pointer
cmp r2, r1 @ any more?
bcc .bytelp
add r0, r1, #1 @ no free bits
RETINSTR(mov,pc,lr)
/*
* Purpose : Find next 'zero' bit
* Prototype: int find_next_zero_bit(void *addr, int maxbit, int offset)
*/
ENTRY(find_next_zero_bit)
ands ip, r2, #7
beq .bytelp @ If new byte, goto old routine
ldrb r3, [r0, r2, lsr#3]
eor r3, r3, #0xff @ now looking for a 1 bit
movs r3, r3, lsr ip @ shift off unused bits
orreq r2, r2, #7 @ if zero, then no bits here
addeq r2, r2, #1 @ align bit pointer
beq .bytelp @ loop for next bit
/*
* One or more bits in the LSB of r3 are assumed to be set.
*/
.found: tst r3, #0x0f
addeq r2, r2, #4
movne r3, r3, lsl #4
tst r3, #0x30
addeq r2, r2, #2
movne r3, r3, lsl #2
tst r3, #0x40
addeq r2, r2, #1
mov r0, r2
RETINSTR(mov,pc,lr)
可以发现它的操作竟然是先将数字进行反转 即0->1 1->0后对1进行搜索
那简单的修改一下就应该能够搞定了
在代码后面加入下面代码
/*
* Purpose : Find a 'one' bit
* Prototype: int find_first_bit(void *addr, int maxbit);
*/
ENTRY(find_first_bit)
mov r2, #0
.bbytelp: ldrb r3, [r0, r2, lsr #3]
movs r3, r3 // 将xor改成movs 触发标志寄存器 保证下面的bne正确跳转
bne .bfound @ any now set - found zero bit
add r2, r2, #8 @ next bit pointer
cmp r2, r1 @ any more?
bcc .bbytelp
add r0, r1, #1 @ no free bits
RETINSTR(mov,pc,lr)
/*
* Purpose : Find next 'one' bit
* Prototype: int find_next_bit(void *addr, int maxbit, int offset)
*/
ENTRY(find_next_bit)
ands ip, r2, #7
beq .bbytelp @ If new byte, goto old routine
ldrb r3, [r0, r2, lsr#3]
movs r3, r3, lsr ip @ shift off unused bits
// 去掉了xor
orreq r2, r2, #7 @ if zero, then no bits here
addeq r2, r2, #1 @ align bit pointer
beq .bbytelp @ loop for next bit
/*
* One or more bits in the LSB of r3 are assumed to be set.
*/
.bfound: tst r3, #0x0f
addeq r2, r2, #4
movne r3, r3, lsl #4
tst r3, #0x30
addeq r2, r2, #2
movne r3, r3, lsl #2
tst r3, #0x40
addeq r2, r2, #1
mov r0, r2
RETINSTR(mov,pc,lr)
- 关于linux bitops的使用
- Linux内核源码(asm/bitops/atomic.h)学习
- set_bit() 等位函数分析! \linux-1.0\linux\include\asm\bitops.h
- 结合redis设计与实现的redis源码学习-24-二进制位数组(Bitops.c)
- 关于linux下面的file_get_contents的使用
- 关于linux下面的file_get_contents的使用
- 关于Linux下一些软件的使用
- 关于一些Linux SVN的安装使用
- 关于linux内核中使用的时钟
- 关于Linux使用的真实内存
- 关于Linux使用的真实内存
- 关于Linux STL使用的一点总结
- 关于linux grep 命令的使用
- 关于 linux 编译预处理 ifdef的使用
- 关于rlwrap的使用--Oracle Linux
- 关于linux下库的使用
- Linux关于GNUPLOT的使用技巧
- linux中关于fork函数的使用
- 现代企业(特别是商务公司)需具有的IT利器
- 读书笔记:Enterprise SOA中文版--面向服务架构的最佳实战(07-9/3更新)
- 身份证号码验证脚本函数
- Dying In The Sun
- ADO 资源
- 关于linux bitops的使用
- 写给李建忠老师的公开信...
- Windows Installer XML 概述 (2)
- 经典的C笔试,strcpy()有什么隐含的危险?
- 十句话
- 手动修改java配置
- SQL Server开发的二十一条军规(转贴)
- Ubuntu的双屏显示
- Java路径问题最终解决方案之一