【C2000的使用经验】使用重复指令,使用你的代码更简
[复制链接]
过去也曾讨论过CCS编译器的编译效率问题,作为TI CPU的专用编译器 ---- CCS,不能用到有特点的、效率高的指令,确实让人感到遗憾。
看一下常用的一个函数的编译结果:
void MemCopy(Uint16 *SourceAddr, Uint16* SourceEndAddr, Uint16* DestAddr) { while(SourceAddr < SourceEndAddr) { *DestAddr++ = *SourceAddr++; } return; } 不优化时: ADDB SP,#4 MOVL *-SP[4],XAR5 MOVL *-SP[2],XAR4 MOVL XAR6,*-SP[2] MOVL ACC,*-SP[4] CMPL ACC,XAR6 B $C$L2,LOS $C$L1: MOVL XAR4,*-SP[2] MOV AL,*XAR4++ MOVL *-SP[2],XAR4 MOVL XAR4,*-SP[8] MOVL XAR6,XAR4 ADDB XAR6,#1 MOVL *-SP[8],XAR6 MOV *+XAR4[0],AL MOVL XAR6,*-SP[2] MOVL ACC,*-SP[4] CMPL ACC,XAR6 B $C$L1,HI $C$L2: SUBB SP,#4 LRETR ; [CPU_] 最高优化级: MOVL XAR7,XAR4 MOVL ACC,XAR5 MOVL XAR5,*-SP[4] CMPL ACC,XAR7 BF $C$L2,LOS SUBL ACC,XAR7 SUBB ACC,#1 MOVL XAR4,ACC $C$L1: MOV AL,*XAR7 MOV *XAR5++,AL SUBB XAR4,#1 MOVB ACC,#0 ADDB XAR7,#1 SUBB ACC,#1 CMPL ACC,XAR4 BF $C$L1,NEQ $C$L2: LRETR 实际上,对于这个问题,都有相应的指令可用: XPREAD loc16, *(pma) XPWRITE *A,loc16 上两条指令是将程序区的内容拷贝至目标地址。指令的应用示例如下: ; Copy the contentsof Array1 to Array2: ; int16 Array1[N];// Located in high 64K of program space ; int16 Array2[N];// Located in data space ; for(i=0; i < N;i++) ; Array2 =Array1; MOVL XAR2,#Array2 ;XAR2 = pointer to Array2 RPT #(N−1) ; Repeatnext instruction N times ||XPREAD*XAR2++,*(Array1) ; Array2 = Array1, ; i++ 然而,使用CCS编译器时,并没有用到此指令------ 不管优化与否。 所以,在应用编程时,与此相当的过程,可以用嵌入汇编的方法,使程序达到最简、运行效率更高。 再看一个例子。将某一数组的值累加。 其C程序为: for ( i = 0; i < N; i++) { sum +=Array; } // 注:N为某一定值,为需要累加的长度。 经CCS编译后,生成如下汇编代码: MOV *-SP[3],#0 ;使用SP作数据运算 ---CCS惯用的办法。 MOV AL,*-SP[3] CMPB AL,#N BF $C$L2,HIS ;判断累加N次否? MOVL XAR4,#_Array ; 放首地址 $C$L1: MOVZ AR0,*-SP[3] MOV AL,*+XAR4[AR0] ADD *-SP[4],AL INC *-SP[3] MOV AL,*-SP[3] CMPB AL,#N BF $C$L1,LO 可见,CCS编译器并没有用到REP这条指令。
实际上,这个问题使用REP指令很容易解决: MOVL XAR1, #Array ;数据存储地址 RPT #(N-1) ||ADDU ACC,*XAR1++;累加32个数据
|