购物车0种商品
IC邮购网-IC电子元件采购商城
还真是ADS1.2的BUG![build 805]的BUG,还在使ADS1.2的兄弟注意升级
(2011/10/16 9:09:00)
编译环境:ADS1.2
调试环境:AXDArmulate

发现问题:同一条语句,不同的编译选项编译,执行结果不同。

语句:
if((d&0x0fffffff)==0x05555550)

选用-O1选项编译时生成代码:(armcc–O1–g+-S–fs–cpuARM7TDMI–ooutO1.stest.c)
000004e1a00200MOVr0,r0,LSL#4
000008e1500221CMPr0,r1,LSR#4
00000c1a000001BNE|L1.24|
其中
r0为0xA5555550
r1为0x05555550

执行结果为假:
;r0中为0xA5555550
MOVr0,r0,LSL#4
;r0中为0x55555500,r1中为0x05555550,r1,LSR#4为0x00555555
CMPr0,r1,LSR#4;不相等,为假
BNE|L1.24|

选用-O0选项编译时生成代码:(armcc–O0–g+-S–fs–cpuARM7TDMI–ooutO0.stest.c)
000000e1a01000MOVr1,r0
000004e1a00201MOVr0,r1,LSL#4
000008e59f202cLDRr2,|L1.60|
00000ce1520220CMPr2,r0,LSR#4
其中
r0为0xA5555550

执行结果为真:
;r0中为0xA5555550
MOVr1,r0
;r0和r1中都为0xA5555550
MOVr0,r1,LSL#4
;r0中为0x55555500
LDRr2,|L1.60|
;r2中为0x05555550
CMPr2,r0,LSR#4;r0,LSR#4为0x05555550,与r2相等,为真

源程序:
inttest(unsignedintd)
{
if((d&0x0fffffff)==0x05555550)
return1;
else
return0;
}

intmain(void)
{
intd;

d=test(0xA5555550);

returnd;
}
使用-O1选项生成的汇编代码:
(armcc–O1–g+-S–fs–cpuARM7TDMI–ooutO1.stest.c)
;generatedbyARMCCompiler,ADS1.2[Build805]

;commandline[-O1-S-g+-fs"-IC:ProgramFilesARMADSv1_2INCLUDE"]
CODE32

AREA||.text||,CODE,READONLY

testPROC
;;;1inttest(unsignedintd)
;;;2{
000000e59f1020LDRr1,|L1.40|
;;;3//unsignedintbak;
;;;4
;;;5if((d&0x0fffffff)==0x05555550)
000004e1a00200MOVr0,r0,LSL#4
000008e1500221CMPr0,r1,LSR#4
00000c1a000001BNE|L1.24|
;;;6return1;
000010e3a00001MOVr0,#1
;;;7else
;;;8return0;
;;;9}
|L1.20|
000014e1a0f00eMOVpc,lr
|L1.24|
000018e3a00000MOVr0,#0;8
00001ceafffffcB|L1.20|;8
ENDP

mainPROC
;;;11intmain(void)
;;;12{
000020e59f0004LDRr0,|L1.44|
;;;13unsignedintd;
;;;14
;;;15d=test(0xA5555550);
000024eafffffeBtest
|L1.40|
00002805555550DCD0x05555550
|L1.44|
00002ca5555550DCD0xa5555550
;;;16
;;;17returnd;
;;;18}ENDP



END

使用-O0选项生成的汇编代码:
(armcc–O0–g+-S–fs–cpuARM7TDMI–ooutO0.stest.c)
;generatedbyARMCCompiler,ADS1.2[Build805]

;commandline[-O0-S-g+-fs"-IC:ProgramFilesARMADSv1_2INCLUDE"]
CODE32

AREA||.text||,CODE,READONLY

testPROC
;;;1inttest(unsignedintd)
;;;2{
000000e1a01000MOVr1,r0
;;;3//unsignedintbak;
;;;4
;;;5if((d&0x0fffffff)==0x05555550)
000004e1a00201MOVr0,r1,LSL#4
000008e59f202cLDRr2,|L1.60|
00000ce1520220CMPr2,r0,LSR#4
0000101a000001BNE|L1.28|
;;;6return1;
000014e3a00001MOVr0,#1
;;;7else
;;;8return0;
;;;9}
|L1.24|
000018e1a0f00eMOVpc,lr
|L1.28|
00001ce3a00000MOVr0,#0;8
000020eafffffcB|L1.24|;8
ENDP

mainPROC
;;;11intmain(void)
;;;12{
000024e52de004STRlr,[sp,#-4]!
;;;13unsignedintd;
;;;14
;;;15d=test(0xA5555550);
000028e59f0010LDRr0,|L1.64|
00002cebfffffeBLtest
000030e1a03000MOVr3,r0
;;;16
;;;17returnd;
000034e1a00003MOVr0,r3
;;;18}000038e49df004LDRpc,[sp],#4
|L1.60|
00003c05555550DCD0x05555550
|L1.64|
000040a5555550DCD0xa5555550
ENDP



END


网友评论:将上述程序用-O1选项编译,运行结果正确:
Inputanewvalue:2773833040

Yourinput:2773833040
intest():d=2773833040
Result:d=1c=2

产生的代码也可以理解:

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

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

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

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

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

把代码改为:
unsignedinttest(unsignedintd)
{

if((d&0x0fffffff)==0x05555550)
{
printf("return1,intest():d=%u ",d);
return1;
}
else
{
printf("return0,intest():d=%u ",d);
return0;
}
}
也没问题,用-O1选项生成代码为:
[0xe59f2030]ldrr2,0x00008118;=#0x05555550
[0xe1a01200]movr1,r0,lsl#4
[0xe1520221]cmpr2,r1,lsr#4

把代码改为
unsignedinttest(unsignedintd)
{
unsignedintret;

if((d&0x0fffffff)==0x05555550)
ret=1;
else
ret=0;

printf("ret=%u",ret);

returnret;
}
也没问题,用-O1选项生成代码为:
[0xe59f1028]ldrr1,0x00008110;=#0x05555550
[0xe1a00200]movr0,r0,lsl#4
[0xe1510220]cmpr1,r0,lsr#4

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

将代码改为
unsignedinttest(unsignedintd)
{
unsignedintret;

if((d&0x0fffffff)==0x05555550)
ret=1;
else
ret=0;

returnret;
}
运行正确,-O1选项产生的代码为
[0xe59f105c]ldrr1,0x00008140;=#0x05555550
[0xe1a00200]movr0,r0,lsl#4
[0xe1510220]cmpr1,r0,lsr#4

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

Inputanewvalue:2773833040

Yourinput:2773833040
intest():d=2773833040
Result:d=0c=0

Inputanewvalue:3

的确是build805版编译器的bug了。


网友评论:用ADS1.2也试了一下,但没看到汇编代码,所有不好说。
不过个人相信ADS1.2不会如此的笨吧!

用RVCT3.0X怎样编译都没问题!

;generatedbyARM/ThumbC/C++Compilerwith,RVCT3.0[Build951]foruVision
;commandlineArmCC[--thumb--debug-c--asm--interleave-opro_entry.o--device=DARMP--apcs=interwork-O3-IC:KeilARMINCPhilipspro_entry.c]

THUMB

AREA||.text.7||,CODE,READONLY,ALIGN=2

testPROC
;;;38{
;;;39if((d&0x0fffffff)==0x05555550)
0000004907LDRr1,|L1.32|
0000020100LSLSr0,r0,#4
0000044288CMPr0,r1
000006d101BNE|L1.12|
;;;40return1;
0000082001MOVSr0,#1
;;;41else
;;;42return0;
;;;43}
00000a4770BXlr
|L1.12|
00000c2000MOVSr0,#0;42
00000e4770BXlr
ENDP

mainPROC
;;;8intmain(void)
;;;9{
000010b500PUSH{lr}
;;;10
;;;13staticlongtmp;
;;;14
;;;15intx,y;
;;;27x=test(0xA5555550);
0000124804LDRr0,|L1.36|
000014f7fffffeBLtest
;;;28
;;;29y=2*x;
;;;30tmp=y;
0000184903LDRr1,|L1.40|
00001a0040LSLSr0,r0,#1;29
00001c6008STRr0,[r1,#0];tmp@main_0
;;;31
;;;32while(1);
|L1.30|
00001ee7feB|L1.30|
|L1.32|
00002055555500DCD0x55555500
|L1.36|
000024a5555550DCD0xa5555550
|L1.40|
00002800000000DCD||.data||
;;;33
;;;34
;;;35}
ENDP



AREA||.data||,DATA,ALIGN=2

||tmp@main_0||
DCD0x00000000





网友评论:非常感谢27楼的回复!找3.0找了半天也没找到。

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

|L1.32|
00002055555500DCD0x55555500
可见优化时把0x05555550优化时改为0x55555500,直接忽略高4位。
在比较时,
0000004907LDRr1,|L1.32|
0000020100LSLSr0,r0,#4
0000044288CMPr0,r1
000006d101BNE|L1.12|
直接把d(0xA5555550)左移4位(也直接忽略高4位)相比较就可以了。


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

intmain(void)
{
volatileintd;

d=test(0xA5555550);

returnd;
}
在805版编译器下编译,生成test1b805.s:
(armcc-O1-S-fs-cpuARM7TDMI-otest1b805.stest1.c)

;generatedbyARMCCompiler,ADS1.2[Build805]

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

AREA||.text||,CODE,READONLY

testPROC
;;;1inttest(unsignedintd)
;;;2{
000000e59f1020LDRr1,|L1.40|
;;;3if((d&0x0fffffff)==0x05555550)
000004e1a00200MOVr0,r0,LSL#4
000008e1500221CMPr0,r1,LSR#4
00000c1a000001BNE|L1.24|
;;;4return1;
000010e3a00001MOVr0,#1
|L1.20|
000014e1a0f00eMOVpc,lr
;;;5else
;;;6return0;
|L1.24|
000018e3a00000MOVr0,#0
00001ceafffffcB|L1.20|
;;;7}
ENDP

mainPROC
;;;9intmain(void)
;;;10{
000020e59f0004LDRr0,|L1.44|
;;;11volatileintd;
;;;12
;;;13d=test(0xA5555550);
000024eafffffeBtest
|L1.40|
00002805555550DCD0x05555550
|L1.44|
00002ca5555550DCD0xa5555550
;;;14
;;;15returnd;
;;;16}
ENDP



END

在848版下编译生成test1b848.s
(armcc-O1-S-fs-cpuARM7TDMI-otest1b848.stest1.c)
;generatedbyARMCCompiler,ADS1.2[Build848]

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

AREA||.text||,CODE,READONLY

testPROC
;;;1inttest(unsignedintd)
;;;2{
000000e59f1020LDRr1,|L1.40|
;;;3if((d&0x0fffffff)==0x05555550)
000004e1a00200MOVr0,r0,LSL#4
000008e1510220CMPr1,r0,LSR#4
00000c1a000001BNE|L1.24|
;;;4return1;
000010e3a00001MOVr0,#1
|L1.20|
000014e1a0f00eMOVpc,lr
;;;5else
;;;6return0;
|L1.24|
000018e3a00000MOVr0,#0
00001ceafffffcB|L1.20|
;;;7}
ENDP

mainPROC
;;;9intmain(void)
;;;10{
000020e59f0004LDRr0,|L1.44|
;;;11volatileintd;
;;;12
;;;13d=test(0xA5555550);
000024eafffffeBtest
|L1.40|
00002805555550DCD0x05555550
|L1.44|
00002ca5555550DCD0xa5555550
;;;14
;;;15returnd;
;;;16}
ENDP



END

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

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

inttest(unsignedintd)
{
if((d&0x0fffffff)==0x05555550)
return1;
else
return0;
}

intmain(void)
{
volatileintd,c;

scanf("%d",&d);
d=test(d);

c=2*d;
printf(" d=%d c=%d ",d,c);

returnc;
}

在805版编译器下编译,生成test1b805.s:
(armcc-O1-S-fs-cpuARM7TDMI-otest2b805.stest2.c)
;generatedbyARMCCompiler,ADS1.2[Build805]

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

AREA||.text||,CODE,READONLY

testPROC
;;;3inttest(unsignedintd)
;;;4{
000000e59f1054LDRr1,|L1.92|
;;;5if((d&0x0fffffff)==0x05555550)
000004e1a00200MOVr0,r0,LSL#4
000008e1500221CMPr0,r1,LSR#4
00000c1a000001BNE|L1.24|
;;;6return1;
000010e3a00001MOVr0,#1
|L1.20|
000014e1a0f00eMOVpc,lr
;;;7else
;;;8return0;
|L1.24|
000018e3a00000MOVr0,#0
00001ceafffffcB|L1.20|
;;;9}
ENDP

mainPROC
;;;11intmain(void)
;;;12{
000020e92d401cSTMFDsp!,{r2-r4,lr}
;;;13volatileintd,c;
;;;14
;;;15scanf("%d",&d);
000024e28d1004ADDr1,sp,#4
000028e28f0030ADRr0,|L1.96|
00002cebfffffeBL_scanf
;;;16d=test(d);
000030e59d0004LDRr0,[sp,#4]
000034ebfffffeBLtest
000038e58d0004STRr0,[sp,#4]
;;;17
;;;18c=2*d;
00003ce59d0004LDRr0,[sp,#4]
000040e1a04080MOVr4,r0,LSL#1
;;;19printf(" d=%d c=%d ",d,c);
000044e1a02004MOVr2,r4
000048e59d1004LDRr1,[sp,#4]
00004ce28f0010ADRr0,|L1.100|
000050ebfffffeBL_printf
;;;20
;;;21returnc;
000054e1a00004MOVr0,r4
000058e8bd801cLDMFDsp!,{r2-r4,pc}
|L1.92|
00005c05555550DCD0x05555550
|L1.96|
00006000006425DCB"%d"
|L1.100|
000064253d640aDCB" d=%"
000068630a2064DCB"d c"
00006c0a64253dDCB"=%d "
00007000000000DCB""
;;;22}ENDP



END
在848版下编译生成test2b848.s
(armcc-O1-S-fs-cpuARM7TDMI-otest2b848.stest2.c)
;generatedbyARMCCompiler,ADS1.2[Build848]

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

AREA||.text||,CODE,READONLY

testPROC
;;;3inttest(unsignedintd)
;;;4{
000000e59f1054LDRr1,|L1.92|
;;;5if((d&0x0fffffff)==0x05555550)
000004e1a00200MOVr0,r0,LSL#4
000008e1510220CMPr1,r0,LSR#4
00000c1a000001BNE|L1.24|
;;;6return1;
000010e3a00001MOVr0,#1
|L1.20|
000014e1a0f00eMOVpc,lr
;;;7else
;;;8return0;
|L1.24|
000018e3a00000MOVr0,#0
00001ceafffffcB|L1.20|
;;;9}
ENDP

mainPROC
;;;11intmain(void)
;;;12{
000020e92d401cSTMFDsp!,{r2-r4,lr}
;;;13volatileintd,c;
;;;14
;;;15scanf("%d",&d);
000024e28d1004ADDr1,sp,#4
000028e28f0030ADRr0,|L1.96|
00002cebfffffeBL_scanf
;;;16d=test(d);
000030e59d0004LDRr0,[sp,#4]
000034ebfffffeBLtest
000038e58d0004STRr0,[sp,#4]
;;;17
;;;18c=2*d;
00003ce59d0004LDRr0,[sp,#4]
000040e1a04080MOVr4,r0,LSL#1
;;;19printf(" d=%d c=%d ",d,c);
000044e1a02004MOVr2,r4
000048e59d1004LDRr1,[sp,#4]
00004ce28f0010ADRr0,|L1.100|
000050ebfffffeBL_printf
;;;20
;;;21returnc;
000054e1a00004MOVr0,r4
000058e8bd801cLDMFDsp!,{r2-r4,pc}
|L1.92|
00005c05555550DCD0x05555550
|L1.96|
00006000006425DCB"%d"
|L1.100|
000064253d640aDCB" d=%"
000068630a2064DCB"d c"
00006c0a64253dDCB"=%d "
00007000000000DCB""
;;;22}ENDP



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

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

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

看版本号的方法:
在命令提示符下输入
armcc
输出
ARMCCompiler,ADS1.2[Build848]
...

网友评论:2.2的在RVDS2.2里有,
3.0的在keilforarm3.0x里有

浏览:(3101)| 评论( 0 )
博文评论

  • 昵 称:
  • 内 容:10~250个字符
  • 验证码: 验证码看不清楚?请点击刷新验证码
  •                      
  • 博文分类

    热点博文

    最新博文

    最新评论

    IC电子元件查询
    IC邮购网电子元件品质保障