源代码
#define MY_MUL 0
u16 test_mul10(u16 x)
{
#if(0==MY_MUL)//移位方式
u16 y;
u16 tmp1,tmp2;
y=0;
tmp1=0;
tmp2=0;
tmp1=x<<3;
tmp2=x<<1;
y=tmp1+tmp2;
return y;
#elif(1==MY_MUL) //直接乘法
return (x*10);
#endif
}
因为10的十进制是1010,所以n乘以10就是理解为(n移位2^3+n移位2^1),发现移位方式之后,总的程序code为9204,而直接乘法,code为9192。也就是说,两种方式code代码量差不多。
再看生成的汇编:
方式1
0x08001D4E 2000 MOVS r0,#0x00
185: tmp1=0;
0x08001D50 2300 MOVS r3,#0x00
186: tmp2=0;
0x08001D52 2200 MOVS r2,#0x00
187: tmp1=x<<3;
0x08001D54 F64F74FF MOVW r4,#0xFFFF
0x08001D58 EA0403C1 AND r3,r4,r1,LSL #3
188: tmp2=x<<1;
0x08001D5C EA040241 AND r2,r4,r1,LSL #1
189: y=tmp1+tmp2;
190: return y;
191: #elif(1==MY_MUL)
192: return (x*10);
193: #endif
0x08001D60 189C ADDS r4,r3,r2
0x08001D62 B2A0 UXTH r0,r4
194: }
0x08001D64 BD10 POP {r4,pc}
方式2
0x08001D4A 4601 MOV r1,r0
192: return (x*10);
193: #endif
0x08001D4C EB010081 ADD r0,r1,r1,LSL #2
0x08001D50 F64F72FF MOVW r2,#0xFFFF
0x08001D54 EA020040 AND r0,r2,r0,LSL #1
194: }
0x08001D58 4770 BX lr
发现,实际上直接乘法,编译器已经按照移位方式(LSL)去处理了。
所以在乘法时候,我们可以直接去乘,不必自己亲自去计算移位了。
|