打印

关于ADS的问题,请高手进来看下

[复制链接]
7488|10
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
ok2222991|  楼主 | 2010-1-27 14:55 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
最近使用ADS的时候发现一个问题:

下面的一个程序,两个变量的值居然不相等,请高手看下是什么原因。

#include <stdio.h>
unsigned int aa()
{
return 0x30313233;
}

int main()
{
int a;
int b;

a = (((unsigned int)0x30313233 & 0xFFFFFF) == 0x313233);
b = ((aa() & 0xFFFFFF) == 0x313233);
printf("a = %d, b = %d\n", a, b);

return 0;
}

在自己的板子上跑和用ADS的软件模拟结果都是a = 1, b =0。而相同的程序放到VC6.0上编译,结果确是a、b相等,实在没搞明白是怎么回事。

之前进汇编看了一下,最后第二段代码ADS将(aa() & 0xFFFFFF)处理成0x31323300,而后面的0x313233则没有进行相应的改变,就直接进行比对,所以为0,这个是ADS的BUG吗?

相关帖子

沙发
xinzha| | 2010-1-27 16:55 | 只看该作者
能把ADS的反汇编结果贴出来看看吗?
我非常怀疑跟ARM的优化有关,下面是不优化的结果

** Section #1 'i.aa' (SHT_PROGBITS) [SHF_ALLOC + SHF_EXECINSTR]
    Size   : 12 bytes (alignment 4)

    aa
    $a
    i.aa
        0x00000000:    e59f0000    ....    LDR      r0,[pc,#0]    ; [0x8] = 0x30313233
        0x00000004:    e12fff1e    ../.    BX       lr
    $d
        0x00000008:    30313233    3210    DCD    808530483

** Section #2 'i.main1' (SHT_PROGBITS) [SHF_ALLOC + SHF_EXECINSTR]
    Size   : 88 bytes (alignment 4)

    main1
    $a
    i.main1
        0x00000000:    e92d4070    p@-.    PUSH     {r4-r6,lr}
        0x00000004:    e3a04001    .@..    MOV      r4,#1
        0x00000008:    ebfffffe    ....    BL       aa  ; 0x0 Section #1
        0x0000000c:    e3c004ff    ....    BIC      r0,r0,#0xff000000
        0x00000010:    e59f102c    ,...    LDR      r1,[pc,#44]   ; [0x44] = 0x313233
        0x00000014:    e1500001    ..P.    CMP      r0,r1
        0x00000018:    1a000001    ....    BNE      {pc} + 0xc  ; 0x24
        0x0000001c:    e3a00001    ....    MOV      r0,#1
        0x00000020:    ea000000    ....    B        {pc} + 0x8  ; 0x28
        0x00000024:    e3a00000    ....    MOV      r0,#0
        0x00000028:    e1a05000    .P..    MOV      r5,r0
        0x0000002c:    e1a02005    . ..    MOV      r2,r5
        0x00000030:    e1a01004    ....    MOV      r1,r4
        0x00000034:    e28f000c    ....    ADR      r0,{pc}+0x14 ; 0x48
        0x00000038:    ebfffffe    ....    BL       __0printf  ;
        0x0000003c:    e3a00000    ....    MOV      r0,#0
        0x00000040:    e8bd8070    p...    POP      {r4-r6,pc}
    $d
        0x00000044:    00313233    321.    DCD    3224115
        0x00000048:    203d2061    a =     DCD    540876897
        0x0000004c:    202c6425    %d,     DCD    539780133
        0x00000050:    203d2062    b =     DCD    540876898
        0x00000054:    000a6425    %d..    DCD    680997

使用特权

评论回复
板凳
xinzha| | 2010-1-27 16:57 | 只看该作者
下面是开到最高优化的结果,貌似有点问题

** Section #1 'i.aa' (SHT_PROGBITS) [SHF_ALLOC + SHF_EXECINSTR]
    Size   : 12 bytes (alignment 4)

    aa
    $a
    i.aa
        0x00000000:    e59f0000    ....    LDR      r0,[pc,#0]    ; [0x8] = 0x30313233
        0x00000004:    e12fff1e    ../.    BX       lr
    $d
        0x00000008:    30313233    3210    DCD    808530483

** Section #2 'i.main1' (SHT_PROGBITS) [SHF_ALLOC + SHF_EXECINSTR]
    Size   : 32 bytes (alignment 4)

    main1
    $a
    i.main1
        0x00000000:    e3a01001    ....    MOV      r1,#1
        0x00000004:    e92d4010    .@-.    PUSH     {r4,lr}
        0x00000008:    e59f000c    ....    LDR      r0,[pc,#12]   ; [.constdata$1 = 0x1c] = 0
        0x0000000c:    e1a02001    . ..    MOV      r2,r1
        0x00000010:    ebfffffe    ....    BL       __0printf  ;
        0x00000014:    e3a00000    ....    MOV      r0,#0
        0x00000018:    e8bd8010    ....    POP      {r4,pc}
    $d
        0x0000001c:    00000000    ....    DCD    0 ; .constdata$1

使用特权

评论回复
地板
ok2222991|  楼主 | 2010-1-28 10:51 | 只看该作者
回二楼,下面是反汇编出来的代码

 
aa [0xe59f0038]   ldr      r0,0x000080e8 ; = #0x30313233
000080ac [0xe1a0f00e]   mov      pc,r14
main [0xe92d4008] * stmfd    r13!,{r3,r14}
000080b4 [0xe3a01001]   mov      r1,#1
000080b8 [0xebfffffa]   bl       aa
000080bc [0xe59f2028]   ldr      r2,0x000080ec ; = #0x00313233
000080c0 [0xe1a00400]   mov      r0,r0,lsl #8
000080c4 [0xe1500422]   cmp      r0,r2,lsr #8
000080c8 [0x1a000001]   bne      0x80d4  ; (main + 0x24)
000080cc [0xe3a02001]   mov      r2,#1
000080d0 [0xea000000]   b        0x80d8  ; (main + 0x28)
000080d4 [0xe3a02000]   mov      r2,#0
000080d8 [0xe28f0010]   add      r0,pc,#0x10 ; #0x80f0
000080dc [0xeb000009]   bl       _printf
000080e0 [0xe3a00000]   mov      r0,#0
000080e4 [0xe8bd8008]   ldmfd    r13!,{r3,pc}
000080e8 [0x30313233]   dcd      0x30313233  3210
000080ec [0x00313233]   dcd      0x00313233  321.
000080f0 [0x203d2061]   dcd      0x203d2061  a =
000080f4 [0x202c6425]   dcd      0x202c6425  %d,
000080f8 [0x203d2062]   dcd      0x203d2062  b =
000080fc [0x000a6425]   dcd      0x000a6425  %d..

使用特权

评论回复
5
ok2222991|  楼主 | 2010-1-28 11:22 | 只看该作者
主要在
000080c4 [0xe1500422]   cmp      r0,r2,lsr #8
这一句指令
执行前
r0 = 0x31323300,r2 = 0x313233
执行后
cpsr的z位为0,即比较结果为不相等。

顺便请教一下,ADS编译时的优化等级在哪里设置。

使用特权

评论回复
6
xinzha| | 2010-1-28 11:29 | 只看该作者
000080c0 [0xe1a00400]   mov      r0,r0,lsl #8

000080c4 [0xe1500422]   cmp      r0,r2,lsr #8
这两句的汇编似乎有点问题,我感觉应该是 mov r0,r0, lsl #8, cmp r2,r0,lsr #8才能正确地表达c语言的本意。而在rvds中直接是这个语句 BIC      r0,r0,#0xff000000,下面是thumb模式的反汇编,从lz贴出来的汇编来看,难道ads真的有bug???...

========================================================================

** Section #1 'i.aa' (SHT_PROGBITS) [SHF_ALLOC + SHF_EXECINSTR]
    Size   : 8 bytes (alignment 4)

    aa
    $t
    i.aa
        0x00000000:    4800        .H      LDR      r0,[pc,#0]    ; [0x4] = 0x30313233
        0x00000002:    4770        pG      BX       lr
    $d
        0x00000004:    30313233    3210    DCD    808530483

** Section #2 'i.main1' (SHT_PROGBITS) [SHF_ALLOC + SHF_EXECINSTR]
    Size   : 60 bytes (alignment 4)

    main1
    $t
    i.main1
        0x00000000:    b570        p.      PUSH     {r4-r6,lr}
        0x00000002:    2401        .$      MOVS     r4,#1
        0x00000004:    f7fffffe    ....    BL       aa  ; 0x0 Section #1
        0x00000008:    0200        ..      LSLS     r0,r0,#8
        0x0000000a:    0a00        ..      LSRS     r0,r0,#8
        0x0000000c:    4906        .I      LDR      r1,[pc,#24]   ; [0x28] = 0x313233
        0x0000000e:    4288        .B      CMP      r0,r1
        0x00000010:    d101        ..      BNE      {pc} + 0x6  ; 0x16
        0x00000012:    2001        .       MOVS     r0,#1
        0x00000014:    e000        ..      B        {pc} + 0x4  ; 0x18
        0x00000016:    2000        .       MOVS     r0,#0
        0x00000018:    0005        ..      MOVS     r5,r0
        0x0000001a:    002a        *.      MOVS     r2,r5
        0x0000001c:    0021        !.      MOVS     r1,r4
        0x0000001e:    a003        ..      ADR      r0,{pc}+0xe ; 0x2c
        0x00000020:    f7fffffe    ....    BL       __0printf  ;
        0x00000024:    2000        .       MOVS     r0,#0
        0x00000026:    bd70        p.      POP      {r4-r6,pc}
    $d
        0x00000028:    00313233    321.    DCD    3224115
        0x0000002c:    203d2061    a =     DCD    540876897
        0x00000030:    202c6425    %d,     DCD    539780133
        0x00000034:    203d2062    b =     DCD    540876898
        0x00000038:    000a6425    %d..    DCD    680997

使用特权

评论回复
7
ok2222991|  楼主 | 2010-1-29 10:14 | 只看该作者
感谢xinzha兄的关注,
请问
cmp      r2,r0,lsr #8
是指将r2左移8位后与r0比较吗?

使用特权

评论回复
8
xinzha| | 2010-1-29 11:28 | 只看该作者
按照arm汇编里面的解释,r2同 r0右移8位后的结果比较。

使用特权

评论回复
9
ok2222991|  楼主 | 2010-1-29 15:04 | 只看该作者
晕,是lsr,我一直都看成是lsl。
cmp r2,r0,lsr #8 的确才是正确的。
应该是ADS的BUG。以前一直用ADS,看来应该多接触下其他的编译器了。

使用特权

评论回复
10
ok2222991|  楼主 | 2010-1-29 15:15 | 只看该作者
再补充一下,这个问题跟ADS的优化确实有关,把优化级别改到最低,就正确了。


aa        [0xe59f0044]   ldr      r0,0x0000804c ; = #0x30313233
00008004        [0xe1a0f00e]   mov      pc,r14
main        [0xe92d4038] * stmfd    r13!,{r3-r5,r14}
0000800c        [0xe3a04001]   mov      r4,#1
00008010        [0xebfffffa]   bl       aa
00008014        [0xe1a00400]   mov      r0,r0,lsl #8
00008018        [0xe59f1030]   ldr      r1,0x00008050 ; = #0x00313233
0000801c        [0xe1510420]   cmp      r1,r0,lsr #8
00008020        [0x1a000001]   bne      0x802c  ; (main + 0x24)
00008024        [0xe3a00001]   mov      r0,#1
00008028        [0xea000000]   b        0x8030  ; (main + 0x28)
0000802c        [0xe3a00000]   mov      r0,#0
00008030        [0xe1a05000]   mov      r5,r0
00008034        [0xe1a02005]   mov      r2,r5
00008038        [0xe1a01004]   mov      r1,r4
0000803c        [0xe28f0010]   add      r0,pc,#0x10 ; #0x8054
00008040        [0xeb000033]   bl       _printf
00008044        [0xe3a00000]   mov      r0,#0
00008048        [0xe8bd8038]   ldmfd    r13!,{r3-r5,pc}
0000804c        [0x30313233]   dcd      0x30313233  3210
00008050        [0x00313233]   dcd      0x00313233  321.
00008054        [0x203d2061]   dcd      0x203d2061  a =
00008058        [0x202c6425]   dcd      0x202c6425  %d,
0000805c        [0x203d2062]   dcd      0x203d2062  b =
00008060        [0x000a6425]   dcd      0x000a6425  %d..

使用特权

评论回复
11
wowow| | 2010-1-30 08:15 | 只看该作者
ads里的编译器已经很老了,其后是rvds 2.2 => rvds 3.x => rvds 4.x,现在的keil for arm用的编译器基本与rvds 4.x同步。

使用特权

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

本版积分规则

4

主题

22

帖子

0

粉丝