|
发表于 2009-7-10 21:05:54
|
显示全部楼层
编写了个程序,验证了一下。
int main( void )
{
INT8U i=0;
volatile INT8U x=0xFE;
volatile INT8S y=0xFE;
while( 1 )
{
if( i & 0x01 ) {
PORTB = ~((~PORTB)>>1);
x = ~((~x)>>1);
y = ~((~y)>>1);
}
else {
PORTB = ~((~PORTB)<<1);
x = ~((~x)<<1);
y = ~((~y)<<1);
}
i++;
}
}
反汇编后:
29: PORTB = ~((~PORTB)>>1);
+00000064: B185 IN R24,0x05 In from I/O location
+00000065: 9586 LSR R24 Logical shift right
+00000066: B985 OUT 0x05,R24 Out to I/O location
30: x = ~((~x)>>1);
+00000067: 8189 LDD R24,Y+1 Load indirect with displacement
+00000068: 9586 LSR R24 Logical shift right
+00000069: 8389 STD Y+1,R24 Store indirect with displacement
31: y = ~((~y)>>1);
+0000006A: 818A LDD R24,Y+2 Load indirect with displacement
+0000006B: 2799 CLR R25 Clear Register
+0000006C: FD87 SBRC R24,7 Skip if bit in register cleared
+0000006D: 9590 COM R25 One's complement
+0000006E: 9580 COM R24 One's complement
+0000006F: 9590 COM R25 One's complement
+00000070: 9595 ASR R25 Arithmetic shift right
+00000071: 9587 ROR R24 Rotate right through carry
+00000072: C018 RJMP PC+0x0019 Relative jump
34: PORTB = ~((~PORTB)<<1);
+00000073: B185 IN R24,0x05 In from I/O location
+00000074: E090 LDI R25,0x00 Load immediate
+00000075: 9580 COM R24 One's complement
+00000076: 9590 COM R25 One's complement
+00000077: 0F88 LSL R24 Logical Shift Left
+00000078: 1F99 ROL R25 Rotate Left Through Carry
+00000079: 9580 COM R24 One's complement
+0000007A: B985 OUT 0x05,R24 Out to I/O location
35: x = ~((~x)<<1);
+0000007B: 8189 LDD R24,Y+1 Load indirect with displacement
+0000007C: E090 LDI R25,0x00 Load immediate
+0000007D: 9580 COM R24 One's complement
+0000007E: 9590 COM R25 One's complement
+0000007F: 0F88 LSL R24 Logical Shift Left
+00000080: 1F99 ROL R25 Rotate Left Through Carry
+00000081: 9580 COM R24 One's complement
+00000082: 8389 STD Y+1,R24 Store indirect with displacement
36: y = ~((~y)<<1);
+00000083: 818A LDD R24,Y+2 Load indirect with displacement
+00000084: 2799 CLR R25 Clear Register
+00000085: FD87 SBRC R24,7 Skip if bit in register cleared
+00000086: 9590 COM R25 One's complement
+00000087: 9580 COM R24 One's complement
+00000088: 9590 COM R25 One's complement
+00000089: 0F88 LSL R24 Logical Shift Left
+0000008A: 1F99 ROL R25 Rotate Left Through Carry
+0000008B: 9580 COM R24 One's complement
+0000008C: 838A STD Y+2,R24 Store indirect with displacement
+0000008D: 5F2F SUBI R18,0xFF Subtract immediate
+0000008E: 4F3F SBCI R19,0xFF Subtract immediate with carry
+0000008F: CFD2 RJMP PC-0x002D Relative jump
+00000090: CFFF RJMP PC-0x0000 Relative jump
+00000091: 95FF9590 CALL 0x003F9590 Call subroutine
+00000093: 0F88 LSL R24 Logical Shift Left
+00000094: 1F99 ROL R25 Rotate Left Through Carry
+00000095: 9580 COM R24 One's complement
+00000096: 838A STD Y+2,R24 Store indirect with displacement
+00000097: 5F2F SUBI R18,0xFF Subtract immediate
+00000098: 4F3F SBCI R19,0xFF Subtract immediate with carry
+00000099: CFC9 RJMP PC-0x0036 Relative jump
+0000009A: CFFF RJMP PC-0x0000 Relative jump
查了一下资料。
关于c中的移位运算
1.移位运算的两个运算数必须是整形表达式,在运算数的两边完成整形提升,表达式整体的类型与提升后的左运算数相同。
2.左移位 exp1<<exp2的表达式使得exp1的位被按expr2指明的数目进行左移,并在低端移入0
3.右移位运算符>>与左移位运算符是不对称的。对左操作数进行移位取决于左操作数的类型:
(1)如果左操作数是无符号(或带符号的非负数),则左边移入0
(2)如果左操作数是带符号的负数,则实现者可以选择补0或者把左操作数最左边的位移入(常见的是填充符号位)。因此,左操作数为负的带符号数值,而右操作数为非0时,>>的应用是不可移植的。
4. 如果右操作数是负数,则移位运算(左移和右移)的结果是未定义的。
5.如果右操作数的值大于或等于左操作数的宽度(位数),则结果也是未定义的。如果右操作数为0,则结果等于左操作数。
-------------------------------
所以,还是改改程序吧,这个平时没注意,又学会一点。 |
|