|
我写的是一段由flag控制流水灯左流右流的语句,同样的语句只是位移符号不同,编译结果总是不同
if(flag == LEFT){
//_delay_ms(500);
if (PORTB == 0x7f) PORTB = 0b11111110;
else PORTB = ~(~PORTB << 1);
}else{
//_delay_ms(500);
if (PORTB == 0xfe) PORTB = 0b01111111;
else PORTB = ~(~PORTB >> 1);
}
其中关键的两句
else PORTB = ~(~PORTB << 1);
else PORTB = ~(~PORTB >> 1);
只是一个位移符号差异,但是汇编出来的语句完全不同
如下
第一句是这样的
28: else PORTB = ~(~PORTB << 1);
+0000005D: 8180 LDD R24,Z+0 Load indirect with displacement
+0000005E: E090 LDI R25,0x00 Load immediate
+0000005F: 9580 COM R24 One's complement
+00000060: 9590 COM R25 One's complement
+00000061: 0F88 LSL R24 Logical Shift Left
+00000062: 1F99 ROL R25 Rotate Left Through Carry
+00000063: 9580 COM R24 One's complement
+00000064: 8380 STD Z+0,R24 Store indirect with displacement
+00000065: CFEE RJMP PC-0x0011 Relative jump
而第二句却变成这样,明显它忽略了我的取反的运算,即使我把优化等级改到O0也没用
32: else PORTB = ~(~PORTB >> 1);
+0000006B: 8180 LDD R24,Z+0 Load indirect with displacement
+0000006C: 9586 LSR R24 Logical shift right
+0000006D: 8380 STD Z+0,R24 Store indirect with displacement
+0000006E: CFE5 RJMP PC-0x001A Relative jump
第一次使用GCC,请指教
我有考虑到优先级问题,加了括号结果还是一样,我用0s级别再优化一次,得到的结果是这样的
28: else PORTB = ~((~PORTB) << 1);
+00000057: B388 IN R24,0x18 In from I/O location
+00000058: E090 LDI R25,0x00 Load immediate
+00000059: 9580 COM R24 One's complement
+0000005A: 9590 COM R25 One's complement
+0000005B: 0F88 LSL R24 Logical Shift Left
+0000005C: 1F99 ROL R25 Rotate Left Through Carry
+0000005D: 9580 COM R24 One's complement
+0000005E: C007 RJMP PC+0x0008 Relative jump
32: else PORTB = ~((~PORTB) >> 1);
+00000064: B388 IN R24,0x18 In from I/O location
+00000065: 9586 LSR R24 Logical shift right
+00000066: BB88 OUT 0x18,R24 Out to I/O location
+00000067: CFE6 RJMP PC-0x0019 Relative jump
很明显,第一句汇编后的结果是正确的,真正做到取反-移位-再取反
而第二句加括号后,汇编结果总是直接将数值移位-输出
两句唯一的区别仅仅在于 左移位和右移位
按我一般的想法就是两者汇编出来的结果应该仅仅是在LSL,LSR的区别,其它应该一样才对啊,真是奇怪
我在草稿上演算了一遍又一遍,算法肯定是没问题的
个人估计,导致 《 》两种不同的结果可能是这样的原因,<<其实相当于原来的数值翻一倍速,而>>等于数值除以二,编译器认为,在除法进行之前取反,进行除法后再取反,结果是等同于直接进行除法,所以两个~被优化掉了,不过实在是很怪异,怎么也搞不行 |
阿莫论坛20周年了!感谢大家的支持与爱护!!
如果天空是黑暗的,那就摸黑生存;
如果发出声音是危险的,那就保持沉默;
如果自觉无力发光,那就蜷伏于牆角。
但是,不要习惯了黑暗就为黑暗辩护;
也不要为自己的苟且而得意;
不要嘲讽那些比自己更勇敢的人。
我们可以卑微如尘土,但不可扭曲如蛆虫。
|