发新帖我要提问
12
返回列表
打印

还真是ADS1.2的BUG![build 805]的BUG,还在使ADS1.2的兄弟注意升级

[复制链接]
楼主: bluesky_78
手机看帖
扫描二维码
随时随地手机跟帖
21
djyos| | 2007-5-29 08:32 | 只看该作者 回帖奖励 |倒序浏览

楼上

    RVCT 2.2中有关volatile的描叙的描述明显与ansi c标准不一致,说明realview编译器不是ansi兼容的编译器。
    ansi标准并没有说明全局和局部的区别,默认应该是指全部代码。局部变量也是可以用的,甚至参数也可以,例如在gcc下,定义一个delay函数:
void delay_us(volatile uint16_t time)
{
    volatile int i;
    for(; time > 0; time--)
        for(i = delaycounter; i >0 ; i--);
}
如果没有volatile,两个for循环都会被优化掉。
做产品,有标准可依的,应该严格按照标准文献。
仅就这一个方面而言,我对gcc十分满意。

使用特权

评论回复
22
djyos| | 2007-5-29 11:21 | 只看该作者

测了一下realview的优化能力

    使用realview自带的examples中的dhrystone2.1,在44b0x上,主频64M,选O3=time,执行速度是134Mips,ARM公司给出的ARM7速度的理论值是0.9Mips/Mhz,那么44b0x的速度极限应该不超过57.6Mips,为什么会这样,有谁知道。
是dhrystone代码错了?
还是ARM公司低估了ARM7的潜力?
或者ARM公司给出的不是dhrystone MIPS。
抑或其他原因?

同等条件下,gcc O2优化的结果是53.7MIPS,略低于理论值。

使用特权

评论回复
23
mohanwei| | 2007-5-29 18:12 | 只看该作者

我手头没有这个编译器,所以没办法做实验验证一下……

不过根据多年的调试经验,推翻了这么多次自己对编译器的怀疑以后,我现在一旦程序出问题就认真的找程序的BUG了……^_^

用过Turbo c,VC,Keil C。到目前为止,唯一发现的BUG就是Keil的著名的“0xFD”BUG了。

使用特权

评论回复
24
mohanwei| | 2007-5-29 21:47 | 只看该作者

改为如下代码再试试看(用Keil调怎么优化都没问题):

#include <stdio.h>

//int test(unsigned int d)
unsigned int test(unsigned int d)
{
    printf("in test(): d=%u ",d);
    if((d & 0x0fffffff) == 0x05555550)
        return 1;
    else
        return 0;
}

int main(void)
{
    //volatile int d, c; //存在潜在的溢出问题……
    unsigned int d, c;
//用C51调,此处要加串口初始化代码
//用C51调,怎么优化都没问题,但是需要将变量都改为“unsigned long”
    while(1)
       {
            printf(" Input a new value:");
                scanf("%u",&d);
                printf(" Your input:%u ",d);
                d = test(d);
             
                c = 2 * d;
                printf("Result:d=%u    c=%u ",d,c);
       }
    return 0;
}

使用特权

评论回复
25
bluesky_78|  楼主 | 2007-5-30 08:28 | 只看该作者

做了测试

将上述程序用-O1选项编译,运行结果正确:
Input a new value:2773833040

Your input:2773833040
in test(): d=2773833040
Result:d=1    c=2

产生的代码也可以理解:

其中 if((d & 0x0fffffff) == 0x05555550)产生的代码为:
[0xe59f102c]   ldr      r1,0x00008124 ; = #0x05555550
[0xe1a00204]   mov      r0,r4,lsl #4
[0xe1510220]   cmp      r1,r0,lsr #4     /****注意****/

与13楼中使用-O0产生的代码相似,即把0xA5555550左移4位,再右移4位与0x05555550比较。

而13楼中使用-O1选项产生的代码为
[0xe59f1050]   ldr      r1,0x00008100 ; = #0x05555550
[0xe1a00200]   mov      r0,r0,lsl #4
[0xe1500221]   cmp      r0,r1,lsr #4    /****注意****/
         /*改为cmp      r1, r0,lsr #4就对了*/

是将0xA5555550左移4位,与0x05555550右移4位比较,好象有问题。

做了一些测试,对于test函数稍作一点改动,其产生的代码就没有问题了。将代码改为:
unsigned int bak;
if((bak = d & 0x0fffffff) == 0x05555550)
用什么选项优化都不出问题了。

把代码改为:
unsigned int test(unsigned int d)
{
    
    if((d & 0x0fffffff) == 0x05555550)
    {
        printf("return 1,in test(): d=%u ",d);
        return 1;
    }
    else
    {
        printf("return 0,in test(): d=%u ",d);
        return 0;
    }
}
也没问题,用-O1选项生成代码为:
[0xe59f2030]   ldr      r2,0x00008118 ; = #0x05555550
[0xe1a01200]   mov      r1,r0,lsl #4
[0xe1520221]   cmp      r2,r1,lsr #4

把代码改为
 unsigned int test(unsigned int d)
{
    unsigned int ret;
    
    if((d & 0x0fffffff) == 0x05555550)
        ret = 1;
    else
        ret = 0;
        
       printf("ret=%u",ret);
       
      return ret;
}
也没问题,用-O1选项生成代码为:
[0xe59f1028]   ldr      r1,0x00008110 ; = #0x05555550
[0xe1a00200]   mov      r0,r0,lsl #4
[0xe1510220]   cmp      r1,r0,lsr #4

与代码
[0xe59f1050]   ldr      r1,0x00008100 ; = #0x05555550
[0xe1a00200]   mov      r0,r0,lsl #4
[0xe1500221]   cmp      r0,r1,lsr #4    /****注意****/
比较,仅有cmp一行不同(12楼test函数-O1选项生成的代码)

将代码改为
unsigned int test(unsigned int d)
{
    unsigned int ret;
    
    if((d & 0x0fffffff) == 0x05555550)
        ret = 1;
    else
        ret = 0;
               
      return ret;
}
运行正确,-O1选项产生的代码为
[0xe59f105c]   ldr      r1,0x00008140 ; = #0x05555550
[0xe1a00200]   mov      r0,r0,lsl #4
[0xe1510220]   cmp      r1,r0,lsr #4

/***************************************************/
补充说明:
上述测试在build 848版本上测试的。
刚才在build 805版本上又测了一下,输出为

Input a new value:2773833040

Your input:2773833040
in test(): d=2773833040
Result:d=0    c=0

Input a new value:3

的确是build 805 版编译器的bug了。

使用特权

评论回复
26
bluesky_78|  楼主 | 2007-5-30 16:19 | 只看该作者

感谢

非常感谢27楼的回复!找3.0找了半天也没找到。

上面生成的是THUMB代码,能再试一下生成ARM代码是什么样子吗?

                  |L1.32|
000020  55555500          DCD      0x55555500
可见优化时把0x05555550优化时改为0x55555500,直接忽略高4位。
在比较时,
000000  4907              LDR      r1,|L1.32|
000002  0100              LSLS     r0,r0,#4
000004  4288              CMP      r0,r1
000006  d101              BNE      |L1.12|
直接把d(0xA5555550)左移4位(也直接忽略高4位)相比较就可以了。

使用特权

评论回复
27
bluesky_78|  楼主 | 2007-5-30 17:39 | 只看该作者

这是ADS build 805版的一个BUG!

到ARM公司网站上下一个848版的补丁就好了!是805版编译器的一个BUG!
做了以下两程序的测试:
程序1
文件名test1.c
int test(unsigned int d)
{
    if((d & 0x0fffffff) == 0x05555550)
        return 1;
    else
        return 0;
}

int main(void)
{
    volatile int d;

    d = test(0xA5555550);

    return d;
}
在805版编译器下编译,生成test1b805.s:
(armcc -O1 -S -fs -cpu ARM7TDMI -o test1b805.s test1.c)

; generated by ARM C Compiler, ADS1.2 [Build 805]

; commandline [-O1 -S -fs "-IC:Program FilesARMADSv1_2INCLUDE"]
                          CODE32

                          AREA ||.text||, CODE, READONLY

                  test PROC
;;;1      int test(unsigned int d)
;;;2      {
000000  e59f1020          LDR      r1,|L1.40|
;;;3          if((d & 0x0fffffff) == 0x05555550)
000004  e1a00200          MOV      r0,r0,LSL #4
000008  e1500221          CMP      r0,r1,LSR #4
00000c  1a000001          BNE      |L1.24|
;;;4              return 1;
000010  e3a00001          MOV      r0,#1
                  |L1.20|
000014  e1a0f00e          MOV      pc,lr
;;;5          else
;;;6              return 0;
                  |L1.24|
000018  e3a00000          MOV      r0,#0
00001c  eafffffc          B        |L1.20|
;;;7      }
                          ENDP

                  main PROC
;;;9      int main(void)
;;;10     {
000020  e59f0004          LDR      r0,|L1.44|
;;;11         volatile int d;
;;;12     
;;;13         d = test(0xA5555550);
000024  eafffffe          B        test
                  |L1.40|
000028  05555550          DCD      0x05555550
                  |L1.44|
00002c  a5555550          DCD      0xa5555550
;;;14     
;;;15         return d;
;;;16     }
                          ENDP



        END

在848版下编译生成test1b848.s
(armcc -O1 -S -fs -cpu ARM7TDMI -o test1b848.s test1.c)
; generated by ARM C Compiler, ADS1.2 [Build 848]

; commandline [-O1 -S -fs "-IC:Program FilesARMADSv1_2INCLUDE"]
                          CODE32

                          AREA ||.text||, CODE, READONLY

                  test PROC
;;;1      int test(unsigned int d)
;;;2      {
000000  e59f1020          LDR      r1,|L1.40|
;;;3          if((d & 0x0fffffff) == 0x05555550)
000004  e1a00200          MOV      r0,r0,LSL #4
000008  e1510220          CMP      r1,r0,LSR #4
00000c  1a000001          BNE      |L1.24|
;;;4              return 1;
000010  e3a00001          MOV      r0,#1
                  |L1.20|
000014  e1a0f00e          MOV      pc,lr
;;;5          else
;;;6              return 0;
                  |L1.24|
000018  e3a00000          MOV      r0,#0
00001c  eafffffc          B        |L1.20|
;;;7      }
                          ENDP

                  main PROC
;;;9      int main(void)
;;;10     {
000020  e59f0004          LDR      r0,|L1.44|
;;;11         volatile int d;
;;;12     
;;;13         d = test(0xA5555550);
000024  eafffffe          B        test
                  |L1.40|
000028  05555550          DCD      0x05555550
                  |L1.44|
00002c  a5555550          DCD      0xa5555550
;;;14     
;;;15         return d;
;;;16     }
                          ENDP



        END

用UEDIT比较一下两个文件,生成的代码除一行不同外,其它的都一样(包括地址也一样),不同的一行是
000008  e1500221          CMP      r0,r1,LSR #4  ;805版
000008  e1510220          CMP      r1,r0,LSR #4  ;848版

第二个测试程序:
文件名:test2.c
#include "stdio.h"

int test(unsigned int d)
{
    if((d & 0x0fffffff) == 0x05555550)
        return 1;
    else
        return 0;
}

int main(void)
{
    volatile int d, c;
    
    scanf("%d",&d);
    d = test(d);
    
    c = 2 * d;
    printf(" d=%d  c=%d ",d,c);
    
    return c;
}

在805版编译器下编译,生成test1b805.s:
(armcc -O1 -S -fs -cpu ARM7TDMI -o test2b805.s test2.c)
; generated by ARM C Compiler, ADS1.2 [Build 805]

; commandline [-O1 -S -fs "-IC:Program FilesARMADSv1_2INCLUDE"]
                          CODE32

                          AREA ||.text||, CODE, READONLY

                  test PROC
;;;3      int test(unsigned int d)
;;;4      {
000000  e59f1054          LDR      r1,|L1.92|
;;;5          if((d & 0x0fffffff) == 0x05555550)
000004  e1a00200          MOV      r0,r0,LSL #4
000008  e1500221          CMP      r0,r1,LSR #4
00000c  1a000001          BNE      |L1.24|
;;;6              return 1;
000010  e3a00001          MOV      r0,#1
                  |L1.20|
000014  e1a0f00e          MOV      pc,lr
;;;7          else
;;;8              return 0;
                  |L1.24|
000018  e3a00000          MOV      r0,#0
00001c  eafffffc          B        |L1.20|
;;;9      }
                          ENDP

                  main PROC
;;;11     int main(void)
;;;12     {
000020  e92d401c          STMFD    sp!,{r2-r4,lr}
;;;13         volatile int d, c;
;;;14         
;;;15         scanf("%d",&d);
000024  e28d1004          ADD      r1,sp,#4
000028  e28f0030          ADR      r0,|L1.96|
00002c  ebfffffe          BL       _scanf
;;;16         d = test(d);
000030  e59d0004          LDR      r0,[sp,#4]
000034  ebfffffe          BL       test
000038  e58d0004          STR      r0,[sp,#4]
;;;17         
;;;18         c = 2 * d;
00003c  e59d0004          LDR      r0,[sp,#4]
000040  e1a04080          MOV      r4,r0,LSL #1
;;;19         printf(" d=%d  c=%d ",d,c);
000044  e1a02004          MOV      r2,r4
000048  e59d1004          LDR      r1,[sp,#4]
00004c  e28f0010          ADR      r0,|L1.100|
000050  ebfffffe          BL       _printf
;;;20         
;;;21         return c;
000054  e1a00004          MOV      r0,r4
000058  e8bd801c          LDMFD    sp!,{r2-r4,pc}
                  |L1.92|
00005c  05555550          DCD      0x05555550
                  |L1.96|
000060  00006425          DCB      "%d"
                  |L1.100|
000064  253d640a          DCB      " d=%"
000068  630a2064          DCB      "d  c"
00006c  0a64253d          DCB      "=%d "
000070  00000000          DCB      ""
;;;22     }                          ENDP



        END
在848版下编译生成test2b848.s
(armcc -O1 -S -fs -cpu ARM7TDMI -o test2b848.s test2.c)
; generated by ARM C Compiler, ADS1.2 [Build 848]

; commandline [-O1 -S -fs "-IC:Program FilesARMADSv1_2INCLUDE"]
                          CODE32

                          AREA ||.text||, CODE, READONLY

                  test PROC
;;;3      int test(unsigned int d)
;;;4      {
000000  e59f1054          LDR      r1,|L1.92|
;;;5          if((d & 0x0fffffff) == 0x05555550)
000004  e1a00200          MOV      r0,r0,LSL #4
000008  e1510220          CMP      r1,r0,LSR #4
00000c  1a000001          BNE      |L1.24|
;;;6              return 1;
000010  e3a00001          MOV      r0,#1
                  |L1.20|
000014  e1a0f00e          MOV      pc,lr
;;;7          else
;;;8              return 0;
                  |L1.24|
000018  e3a00000          MOV      r0,#0
00001c  eafffffc          B        |L1.20|
;;;9      }
                          ENDP

                  main PROC
;;;11     int main(void)
;;;12     {
000020  e92d401c          STMFD    sp!,{r2-r4,lr}
;;;13         volatile int d, c;
;;;14         
;;;15         scanf("%d",&d);
000024  e28d1004          ADD      r1,sp,#4
000028  e28f0030          ADR      r0,|L1.96|
00002c  ebfffffe          BL       _scanf
;;;16         d = test(d);
000030  e59d0004          LDR      r0,[sp,#4]
000034  ebfffffe          BL       test
000038  e58d0004          STR      r0,[sp,#4]
;;;17         
;;;18         c = 2 * d;
00003c  e59d0004          LDR      r0,[sp,#4]
000040  e1a04080          MOV      r4,r0,LSL #1
;;;19         printf(" d=%d  c=%d ",d,c);
000044  e1a02004          MOV      r2,r4
000048  e59d1004          LDR      r1,[sp,#4]
00004c  e28f0010          ADR      r0,|L1.100|
000050  ebfffffe          BL       _printf
;;;20         
;;;21         return c;
000054  e1a00004          MOV      r0,r4
000058  e8bd801c          LDMFD    sp!,{r2-r4,pc}
                  |L1.92|
00005c  05555550          DCD      0x05555550
                  |L1.96|
000060  00006425          DCB      "%d"
                  |L1.100|
000064  253d640a          DCB      " d=%"
000068  630a2064          DCB      "d  c"
00006c  0a64253d          DCB      "=%d "
000070  00000000          DCB      ""
;;;22     }                          ENDP



        END
用UEDIT比较一下两个文件,生成的代码除一行不同外,其它的都一样(包括地址也一样),不同的一行是
000008  e1500221          CMP      r0,r1,LSR #4  ;805版
000008  e1510220          CMP      r1,r0,LSR #4  ;848版

折腾了好几天,原来是版本太老了。
不过还好,学了不少东西,也感谢各位的指导!

还在使ADS1.2的要注意升级了!
补丁下载地址:
http://www.arm.com/support/downloads/info/4554.html

看版本号的方法:
在命令提示符下输入
armcc
输出
ARM C Compiler, ADS1.2[Build 848]
...

使用特权

评论回复
28
wowow| | 2007-5-30 19:43 | 只看该作者

为什么不直接用2.2或3.0

2.2的在RVDS 2.2里有,
3.0的在keil for arm 3.0x里有

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则