[讨论] 【C28汇编语言杂谈】一、C语言与汇编的比较

dontium   2013-10-11 17:48 楼主
【C28汇编语言杂谈】
大家都知道,C语言编程方便,可读性好,移植容易,有与硬件联系密切的特点,使用提供的头文件可以对CPU的内部寄存器及外围编程。通用性强。但编译器并非智能型的,对于C语言编译连接后所产生的机器码不尽相同,且一般很难达到最简,执行效率没有汇编高。
汇编语言,是用文字助记符来表示机器指令的符号语言,是最接近机器码的一种语言。其主要优点是占用资源少、程序执行效率高。但是不同的CPU,其汇编语言可能有所差异,所以不易移植。
现举个例子。在使用C28 CPU处理PID问题时,使用的PWM频率为50KHz,1200个时钟周期。程序中用了这样一句:
    return (pp->Proportion * Error // 比例项
           +pp->Integral * pp->SumError // 积分项
           +pp->Derivative * dError // 微分项
           );
使用CCS V5编译,在未使用优化时,编译后产生31行代码,并调用几个过程:
LCR       #L$$TOFS
LCR       #FS$$MPY
LCR       #FS$$ADD
LCR       #FS$$TOL
共9次。在调试时发现,仅此句就占用了数百个时钟,而处理整个PID过程在中断中占用1034个时钟,
在使用2级优化时,产生30行代码,上述的四个过程仍调用9次。
如果使用汇编语言编程,处理这个问题的时钟数也不会超过100个。
对一般C语句,CCS的处理效率还是很高的。如:
  GpioCtrlRegs.GPAMUX1.all = 0x0000; // GPIO functionality GPIO0-GPIO15
编译后的汇编语言为:
       MOVB     ACC,#0               
       MOVW     DP,#_GpioCtrlRegs+6
       MOVL     @_GpioCtrlRegs+6,ACC
如果接下去的C语句,是在同一个DP页,那么编译器将省掉MOVW DP, #xxx,效率将更高。 如:
  GpioCtrlRegs.GPAMUX1.all = 0x0000;
  GpioCtrlRegs.GPAMUX2.all = 0x0000;
  GpioCtrlRegs.GPBMUX1.all = 0x0000;
   GpioCtrlRegs.AIOMUX1.all = 0x0000;
  GpioCtrlRegs.GPADIR.all = 0x0000;
  GpioCtrlRegs.GPBDIR.all = 0x0000;
  GpioCtrlRegs.AIODIR.all = 0x0000;
因为GpioCtrlRegs的寄存器组在同一数据段内,所以省去DP的重新装载。就是以下这样:
       MOVB     ACC,#0
       MOVW     DP,#_GpioCtrlRegs+6
       MOVL     @_GpioCtrlRegs+6,ACC对应GPAMUX1
       MOVL     @_GpioCtrlRegs+8,ACC ;对应GPAMUX2
       MOVL     @_GpioCtrlRegs+22,ACC ; 对应GPBMUX1
       MOVL     @_GpioCtrlRegs+54,ACC ;对应AIOMUX1
       MOVL     @_GpioCtrlRegs+10,ACC ;对应GPADIR
        MOVL      @_GpioCtrlRegs+26,ACC ; 对应GPBDIR
       MOV      @_GpioCtrlRegs+58,#0  ;对应AIODIR
以上可见,后续的一条C语句,仅用一句汇编指令完成,执行周期一个时钟!从这里我们可以想到,如果有很需要对寄存器操作的语句,尽量把它们放在一起,且,同一数据页的放在一起!这样就不会频繁使用数据页指针寄存器DP。
C28的数据页分配如下:

a1.jpg

回复评论

暂无评论,赶紧抢沙发吧
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复