`
ladymaidu
  • 浏览: 678622 次
文章分类
社区版块
存档分类
最新评论

c语言位操作在内核中应用

 
阅读更多

1. “按位与”运算符(&)

参加运算的两个数据,按二进位进行“与”运算。原则是全1为1,有0为0,即:0&0=0; 0&1=0; 1&0=0; 1&1=1; 如下例:

a=5&3; //a=(0b 0101) & (0b 0011) =0b 0001 =1

那么如果参加运算的两个数为负数,又该如何算呢?会以其补码形式表示的二进制数来进行与运算。

a=-5&-3; //a=(0b 1011) & (0b1101) =0b 1001 =-7

在实际的应用中与操作经常被用于实现特定的功能:

1)清零

“按位与”通常被用来使变量中的某一位清零。如下例:

a=0xfe; //a=0b 11111110

a=a&0x55; //使变量a的第1位、第3位、第5位、第7位清零 a= 0b 01010100

2)检测位

要知道一个变量中某一位是‘1’还是‘0’,可以使用与操作来实现。

a=0xf5; //a=0b 11110101

result=a&0x08; //检测a的第三位,result=0

3)保留变量的某一位

要屏蔽某一个变量的其它位,而保留某些位,也可以使用与操作来实现。

a=0x55; //a=0b 01010101

a=a&0x0f; //将高四位清零,而保留低四位 a=0x05

  2. “按位或”运算符(|)            

   参与或操作的两个位,只要有一个为‘1’,则结果为‘1’。即有‘1’为‘1’,全‘0’为‘0’。0|0=0; 0|1=1; 1|0=1; 1|1=1;例如:

   a=0x30|0x0f; //a=(0b00110000)|(0b00001111)=(0b00111111)=0x3f

“按位或”运算最普遍的应用就是对一个变量的某些位置‘1’。如下例:

a=0x00; //a=0b 00000000

a=a|0x7f; //将a的低7位置为1,a=0x7f

3. “异或”运算符(^)

异或运算符^又被称为XOR运算符。当参与运算的两个位相同(‘1’与‘1’或‘0’与‘0’)时结果为‘0’。不同时为‘1’。即相同为0,不同为1


。 0^0=0; 0^1=1; 1^0=1;1^1=0;例如:

   a=0x55^0x3f; //a=(0b01010101)^(0b00111111)=(0b01101010)=0x6a

异或运算主要有以下几种应用:

   1)翻转某一位:当一个位与‘1’作异或运算时结果就为此位翻转后的值。如下例:

a=0x35; //a=0b00110101

a=a^0x0f; //a=0b00111010 a的低四位翻转

    关于异或的这一作用,有一个典型的应用,即取浮点的相反数,具体的实现如下:

f=1.23; //f为浮点型变量 值为1.23

f=f*-1; //f乘以-1,实现取其相反数,要进行一次乘运算

f=1.23;

((unsigned char *)&f)[0]^=0x80; //将浮点数f的符号位进行翻转实现取相反数       

   2)保留原值:当一个位与‘0’作异或运算时,结果就为此位的值。如下例:

a=0xff; //a=0b11111111

a=a^0x0f; //a=0b11110000 与0x0f作异或,高四位不变,低四位翻转

   3)交换两个变量的值,而不用临时变量,要交换两个变量的值,传统的方法都需要一个临时变量。实现如下:

void swap(unsigned char *pa,unsigned char *pb)

{

unsigned char temp=*pa;//定义临时变量,将pa指向的变量值赋给它

*pa=*pb;

*pb=temp; //变量值对调

}

而使用异或的方法来实现,就可以不用临时变量,如下:

void swap_xor(unsigned char *pa,unsigned char *pb)

{

*pa=*pa^*pb;

*pb=*pa^*pb;

*pa=*pa^*pb; //采用异或实现变量对调

}

几个经典的位运算函数

4.1求当前机器无符号整型最大长度

/*the max length of unsigned int*/

int int_size ()

{

unsigned int bits;

int size = 0;


bits = ~0;


while ( bits ) {

++size;

bits >>= 1;

}

return size;

}


4.2移位运算

/*a bit mover for unsigned int

if n > 0 move left for n bits,else move right*/

unsigned int bit_shift (unsigned int value,int n)

{

int intsize=int_size(); /*the length of unsigned int*/


if(n>0 && n< intsize) /*move left*/

value<<=n;

else if (n<0 && n> -intsize) /*move right*/

value>>=-n;

else

value=0;

return value;

}


4.3循环移位运算

/*a bit rotate mover for unsigned int

if n > 0 move left for n bits,else move right*/

unsigned int bit_rotate (unsigned int value, int n)

{

unsigned int result,bits,intsize;


intsize=int_size(); /*the length of unsigned int*/


if(n > 0)

n=n % intsize;

else

n=-(-n % intsize);


if(n==0)

result=value;

else if(n >0 ){ /*move left*/

bits=value >> (intsize-n);/*bits should be in the rightest*/

result=value << n|bits;

}else{ /*move right*/

n=-n;

bits=value << (intsize-n);/*bits should be in the leftest*/

result=value >> n|bits;

}

return result;

}


4.4返回无符号整型数value中从右起第p位的值

/* get bit No.p(from right) of value to see if it is on */

int bit_get (unsigned int value, int p)

{

int intsize=int_size(); /*the length of unsigned int*/


if ( p < 0 || p > intsize-1 )/*out of range*/

return 0;


if ( (value >> p) & 1 )

return 1;

else

return 0;

}


4.5将无符号整型数value中从右起的第p位置1

/* set bit No.p(from right) of value on */

unsigned int bit_set (unsigned int value, int p)

{

int intsize=int_size(); /*the length of unsigned int*/


if ( p < 0 || p > intsize-1 )/*out of range*/

return 0;


return value | (1 << p);

}


4.6返回无符号整型数value中从第p位(右起)向右n位的值

[1]~(~0 << n)表示最右边n位全为1;

[2]value >> (p+1-n)表示将目标位字段移至最右端;

/*get n bits of value at position p(from right) */

unsigned bits_get (unsigned int value, int p, int n)

{

int intsize=int_size(); /*the length of unsigned int*/


if ( n < 0 || p < 0 || p + n > intsize )

return 0;

return(value >> (p+1-n)) & ~(~0 << n);

}


4.7将无符号整型数value中从第p位(右起)向右n位设置为y最右边n位的值

[1]~(~0 << n)表示最右边n位全为1;

[2](~(~0 << n) << (p+1-n)表示将这n个1位左移至位置p;

[3]~(~(~0 << n) << (p+1-n))表示将从位置p开始的n位设置零,其余位设置一;

[4]unsigned tar=bits_get(y,n-1,n);取出y的低n位;

/*set n bits of value at position p(from right) with bits of y*/

unsigned bits_set (unsigned value, int p, int n, unsigned int y)

{

int intsize=int_size(); /*the length of unsigned int*/


if ( n < 0 || p < 0 || p + n > intsize )

return 0;

unsigned tar=bits_get(y,n-1,n);

return (value & ~(~(~0 << n) << (p+1-n))) | tar;

}

分享到:
评论

相关推荐

    C语言深层探索+ARM linux移植

    C语言嵌入式系统编程修炼之三:内存操作 31 C语言嵌入式系统编程修炼之四:屏幕操作 37 C语言嵌入式系统编程修炼之五:键盘操作 45 C语言嵌入式系统编程修炼之六:性能优化 49 C/C++语言void及void指针深层探索 52 C/C++...

    天书夜读:从汇编语言到Windows内核编程(完整版一)

    为了让前面练习的成果,在实际应用中产生价值,在这部分我们补充更多的理论知识并尝试用它们去做一点什么。这一部分包括指令分析、硬件基础知识、内核Hook的实际开发练习,以及将完成一个用到内核Hook的有趣的实例,...

    天书夜读:从汇编语言到Windows内核编程(完整版 二)

    为了让前面练习的成果,在实际应用中产生价值,在这部分我们补充更多的理论知识并尝试用它们去做一点什么。这一部分包括指令分析、硬件基础知识、内核Hook的实际开发练习,以及将完成一个用到内核Hook的有趣的实例,...

    嵌入式C语言精华+.pdf

    基于 ARM 的嵌入式 Linux 移植真实体验(5)――应用实例 ..........................................135 深入浅出 Linux 设备驱动编程 ..........................................................................

    天书夜谈:从汇编语言到Windows内核编程

    为了让前面练习的成果,在实际应用中产生价值,在这部分我们补充更多的理论知识并尝试用它们去做一点什么。这一部分包括指令分析、硬件基础知识、内核Hook的实际开发练习,以及将完成一个用到内核Hook的有趣的实例,...

    c语言编写单片机技巧

    在应用中,一般是将微处理器装配在专门设计的电路板上,在母板上只保留和嵌入式相关的功能即可,这样可以满足嵌入式系统体积小和功耗低的要求。目前的嵌入式处理器主要包括:PowerPC、Motorola 68000、ARM系列...

    Windows内核安全与驱动开发光盘源码

    5.2.2 在应用程序中打开与关闭设备 75 5.2.3 设备控制请求 75 5.2.4 内核中的对应处理 77 5.2.5 结合测试的效果 79 5.3 阻塞、等待与安全设计 80 5.3.1 驱动主动通知应用 80 5.3.2 通信接口的测试 81 5.3.3 ...

    Windows内核安全驱动开发(随书光盘)

    5.2.2 在应用程序中打开与关闭设备 75 5.2.3 设备控制请求 75 5.2.4 内核中的对应处理 77 5.2.5 结合测试的效果 79 5.3 阻塞、等待与安全设计 80 5.3.1 驱动主动通知应用 80 5.3.2 通信接口的测试 81 5.3.3 ...

    基于RISC-V 的开源微控制器系统_C语言_Objective-C_SystemVerilog_代码_相关文件_下载

    它实现了几个 ISA 扩展,例如:硬件循环、后递增加载和存储指令、位操作指令、MAC 操作、支持定点操作、打包 SIMD 指令和点积。它旨在提高超低功耗信号处理应用的能效。RISCY 实现了 1.9 特权规范的一个子集。 zero...

    宋劲彬的嵌入式C语言一站式编程

    5. 练习:在C语言中使用正则表达式 33. 信号 1. 信号的基本概念 2. 产生信号 2.1. 通过终端按键产生信号 2.2. 调用系统函数向进程发信号 2.3. 由软件条件产生信号 3. 阻塞信号 3.1. 信号在内核中的表示 3.2. 信号集...

    Windows驱动开发基础视频教程.txt

    第十四课 在驱动中使用c++中内存管理操作-newdelet 第十六课 驱动开发中宏与断言的使用 第5章应用程序与驱动程序通信 第二十六课 irp与派遣函数 第二十七课 缓冲区读写操作 第十五课 在驱动中使用结构化异常...

    嵌入式实时操作系统ucos-II 第二版 源代码

    μC/OSII是著名的、源码公开的实时内核,是专为嵌入式应用设计的,可用于各类8位、16位和32位单片机或DSP。从μC/OS算起,该内核已有10余年应用史,在诸多领域得到了广泛应用。  本书是MicroC/OSII The Real Time ...

    手把手教你学AVR单片机C程序设计(光盘)

    6.2 ATMEGAl6(L)中4组通用数字I/0端口的应用设置 6.3 ATMEGA16(L)的I/o端口使用注意事项 6.4 ATMEGAl6(L)PB口输出实验 6.5 8位数码管测试 6.6 独立式按键开关的使用 6.7 发光二极管的移动控制(跑马灯...

    嵌入式系统C语言精华

    基于ARM 的嵌入式Linux 移植真实体验(5)――应用实例..........................................135 深入浅出Linux 设备驱动编程.......................................................................144 1....

    边干边学Linux__第二版_doc格式

    6.4 命令行中使用操作符 6.5 Linux系统启动和进程层次结构 6.6 系统启动和关机 6.7 输入、输出重定向 6.8 使用文件描述符 6.9 输入和输出重定向的组合使用 6.10 管道(pipe) 第7章 C语言开发工具 7.1 编写程序的...

    c语言资料-c嵌入式C精华

    基于 ARM 的嵌入式 Linux 移植真实体验(5)――应用实例 ..........................................135 深入浅出 Linux 设备驱动编程 .........................................................................

    windows驱动开发技术详解-part2

     驱动程序被操作系统加载在内核模式下,它与Windows操作系统内核的其他组件进行密切交互。本章主 要介绍Windows操作系统内核的基本概念,同时还介绍应用程序和驱动程序之间的通信方法。  2.1 Windows操作系统概述...

    Windows驱动开发技术详解的光盘-part1

     驱动程序被操作系统加载在内核模式下,它与Windows操作系统内核的其他组件进行密切交互。本章主要介绍Windows操作系统内核的基本概念,同时还介绍应用程序和驱动程序之间的通信方法。  2.1 Windows操作系统概述 ...

    ucos源码

    至今,从8位到64位,uC/OSII已经在超过40种不同架构的微处理器上运行。 uC/OSII已经被应用到各个领域中,这些领域包括:照相机行业、航空业、高端音响、医疗器械、电子乐器、发动机控制、网络设备、高速公路电话...

Global site tag (gtag.js) - Google Analytics