与汇编代码不同,在C中,无法对值进行位移。要移位变量中的位,必须始终执行赋值:
bottomLayoutGuide
像gcc这样的编译器是否足够智能,可以意识到这是一个就地位移位并按如下方式编译:
x = x << 3;
或者编译器会将结果放在寄存器中,然后将其移回x(这需要两个额外的不必要的指令)。
答案 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
等等