像gcc这样的C编译器是否足够聪明,可以进行位移?

时间:2017-12-08 16:34:17

标签: c gcc compilation

与汇编代码不同,在C中,无法对值进行位移。要移位变量中的位,必须始终执行赋值:

bottomLayoutGuide

像gcc这样的编译器是否足够智能,可以意识到这是一个就地位移位并按如下方式编译:

x = x << 3;

或者编译器会将结果放在寄存器中,然后将其移回x(这需要两个额外的不必要的指令)。

2 个答案:

答案 0 :(得分:2)

任何打开优化的好编译器都会有效地处理位移。

编译器会在可行且有效的情况下将小对象保留在寄存器中,即使您编写赋值语句也不会将它们存储到内存中,直到它们被环境强制为止。

此外,在典型的现代处理器上,不希望尝试在存储器中移位值的位。通常,内存硬件没有任何操作存储值的功能。要更改内存中某些内容的值,必须将其移动到处理器(已加载),更改并移回(存储)。这是在一个指令还是几个指令中完成,通常不表示它的速度和效率,因为处理器仍然必须执行单独的加载,移位,存储操作,并且这些操作的性能高度依赖于处理器模型

除了特殊的编程情况外,你不应该担心这个级别的表现。

答案 1 :(得分:0)

你尝试的时候看到了什么?为什么不试试呢?

unsigned int fun(unsigned int x)     {         返回(x <&lt; 3);     }     部分的反汇编.text:

00000000 <fun>:
   0:   e1a00180    lsl r0, r0, #3
   4:   e12fff1e    bx  lr

Disassembly of section .text:

00000000 <_fun>:
   0:   1166            mov r5, -(sp)
   2:   1185            mov sp, r5
   4:   1d40 0004       mov 4(r5), r0
   8:   0cc0            asl r0
   a:   0cc0            asl r0
   c:   0cc0            asl r0
   e:   1585            mov (sp)+, r5
  10:   0087            rts pc

Disassembly of section .text:

0000000000000000 <fun>:
   0:   531d7000    lsl w0, w0, #3
   4:   d65f03c0    ret

Disassembly of section .text:

0000000000000000 <fun>:
   0:   8d 04 fd 00 00 00 00    lea    0x0(,%rdi,8),%eax
   7:   c3                      retq   

00000000 <fun>:
   0:   42 18 0c 5c     rpt #3 { rlax.w r12     ;
   4:   30 41           ret         

Disassembly of section .text:

00000000 <fun>:
   0:   050e                    slli    x10,x10,0x3
   2:   8082                    ret

unsigned int x;

void fun ( void )
{
    x=x<<3;
}
Disassembly of section .text:

00000000 <fun>:
   0:   e59f200c    ldr r2, [pc, #12]   ; 14 <fun+0x14>
   4:   e5923000    ldr r3, [r2]
   8:   e1a03183    lsl r3, r3, #3
   c:   e5823000    str r3, [r2]
  10:   e12fff1e    bx  lr
  14:   00000000    andeq   r0, r0, r0

等等