现在的位置: 首页 > 自动控制 > 工业·编程 > 正文

c++的位运算和逻辑运算

2012-08-06 06:30 工业·编程 ⁄ 共 1378字 ⁄ 字号 暂无评论

    因为很少使用位运算(与或非、移位以及对应的赋值操作),渐生一种神秘感,今天就把这层面纱揭去,看看他们的真面目。由于位运算和逻辑运算都有与或非操作,这里看看他们的区别。

引入这些运算的原因

    c++继承自c,c使用位运算自然是为了提高效率,使得c可以像低级语言那样实现bit-level的操作。使用逻辑运算是为了控制程序流程。

    现代编译器的优化功能不容小视,下面的汇编代码都是编译器优化后产生的。这些优化有些使我们吃惊,但却解释我们心中的疑惑。其中匿名局部变量处理、常量运算求值和内联函数展开和求值是常见的优化点。

     1. 位运算

      1.1 位的与或非

       参与运算的两个操作数必须为整形或其变体,操作数按位进行与或非操作。我们使用汇编代码给出真相。

void f(){
    0xfecb | 0xf03e0;
    int a1 = 0xfecb & 0xf03e0 | 0x3c83 & (~0x2db40f85)| ~0xfecb & 0xf03e0 | ~0x3c83 & (~0x2db40f85);
    char a2 = 0xf;
    int a3 = 0xf0;
    int a4 = a2 & a3;
}

对应的汇编代码为:

void f(){
00413C60  push        ebp 
00413C61  mov         ebp,esp
00413C63  sub         esp,0F0h
00413C69  push        ebx 
00413C6A  push        esi 
00413C6B  push        edi 
00413C6C  lea         edi,[ebp-0F0h]
00413C72  mov         ecx,3Ch
00413C77  mov         eax,0CCCCCCCCh
00413C7C  rep stos    dword ptr es:[edi]
    0xfecb | 0xf03e0;
    int a1 = 0xfecb & 0xf03e0 | 0x3c83 & (~0x2db40f85)| ~0xfecb & 0xf03e0 | ~0x3c83 & (~0x2db40f85);
00413C7E  mov         dword ptr [a1],0D24FF3FAh
    char a2 = 0xf;
00413C85  mov         byte ptr [a2],0Fh
    int a3 = 0xf0;
00413C89  mov         dword ptr [a3],0F0h
    int a4 = a2 & a3;
00413C90  movsx       eax,byte ptr [a2]
00413C94  and         eax,dword ptr [a3]
00413C97  mov         dword ptr [a4],eax
}

  这个例子说明,0.1 不使用的局部变量,编译器不会为它生成代码。 0.2 常量运算编译器直接求值。 0.3  变量的运算只能在运行时完成,编译器无法为其代劳。 1. 两个长度不同的变量做位运算时,需要符号扩展长度较小的变量,两操作数长度相同再运算。另外,c++所有的位运算都是算术的,这也体现在右移运算中。

      1.2 移位运算

       移位运算包括左移和右移运算,对操作数的要求同与或非。左移后空出的右边由若干个0填补,右移后空出的左边由若干个符号位填补。

给我留言

留言无头像?