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

[复制链接]
8629|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的优化有关,下面是不优化的结果

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

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

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

  12.     main1
  13.     $a
  14.     i.main1
  15.         0x00000000:    e92d4070    p@-.    PUSH     {r4-r6,lr}
  16.         0x00000004:    e3a04001    .@..    MOV      r4,#1
  17.         0x00000008:    ebfffffe    ....    BL       aa  ; 0x0 Section #1
  18.         0x0000000c:    e3c004ff    ....    BIC      r0,r0,#0xff000000
  19.         0x00000010:    e59f102c    ,...    LDR      r1,[pc,#44]   ; [0x44] = 0x313233
  20.         0x00000014:    e1500001    ..P.    CMP      r0,r1
  21.         0x00000018:    1a000001    ....    BNE      {pc} + 0xc  ; 0x24
  22.         0x0000001c:    e3a00001    ....    MOV      r0,#1
  23.         0x00000020:    ea000000    ....    B        {pc} + 0x8  ; 0x28
  24.         0x00000024:    e3a00000    ....    MOV      r0,#0
  25.         0x00000028:    e1a05000    .P..    MOV      r5,r0
  26.         0x0000002c:    e1a02005    . ..    MOV      r2,r5
  27.         0x00000030:    e1a01004    ....    MOV      r1,r4
  28.         0x00000034:    e28f000c    ....    ADR      r0,{pc}+0x14 ; 0x48
  29.         0x00000038:    ebfffffe    ....    BL       __0printf  ;
  30.         0x0000003c:    e3a00000    ....    MOV      r0,#0
  31.         0x00000040:    e8bd8070    p...    POP      {r4-r6,pc}
  32.     $d
  33.         0x00000044:    00313233    321.    DCD    3224115
  34.         0x00000048:    203d2061    a =     DCD    540876897
  35.         0x0000004c:    202c6425    %d,     DCD    539780133
  36.         0x00000050:    203d2062    b =     DCD    540876898
  37.         0x00000054:    000a6425    %d..    DCD    680997
xinzha 发表于 2010-1-27 16:57 | 显示全部楼层
下面是开到最高优化的结果,貌似有点问题

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

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

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

  12.     main1
  13.     $a
  14.     i.main1
  15.         0x00000000:    e3a01001    ....    MOV      r1,#1
  16.         0x00000004:    e92d4010    .@-.    PUSH     {r4,lr}
  17.         0x00000008:    e59f000c    ....    LDR      r0,[pc,#12]   ; [.constdata$1 = 0x1c] = 0
  18.         0x0000000c:    e1a02001    . ..    MOV      r2,r1
  19.         0x00000010:    ebfffffe    ....    BL       __0printf  ;
  20.         0x00000014:    e3a00000    ....    MOV      r0,#0
  21.         0x00000018:    e8bd8010    ....    POP      {r4,pc}
  22.     $d
  23.         0x0000001c:    00000000    ....    DCD    0 ; .constdata$1
 楼主| ok2222991 发表于 2010-1-28 10:51 | 显示全部楼层
回二楼,下面是反汇编出来的代码


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

 楼主| ok2222991 发表于 2010-1-28 11:22 | 显示全部楼层
主要在
000080c4 [0xe1500422]   cmp      r0,r2,lsr #8
这一句指令
执行前
r0 = 0x31323300,r2 = 0x313233
执行后
cpsr的z位为0,即比较结果为不相等。

顺便请教一下,ADS编译时的优化等级在哪里设置。
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???...

  1. ========================================================================

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

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

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

  13.     main1
  14.     $t
  15.     i.main1
  16.         0x00000000:    b570        p.      PUSH     {r4-r6,lr}
  17.         0x00000002:    2401        .$      MOVS     r4,#1
  18.         0x00000004:    f7fffffe    ....    BL       aa  ; 0x0 Section #1
  19.         0x00000008:    0200        ..      LSLS     r0,r0,#8
  20.         0x0000000a:    0a00        ..      LSRS     r0,r0,#8
  21.         0x0000000c:    4906        .I      LDR      r1,[pc,#24]   ; [0x28] = 0x313233
  22.         0x0000000e:    4288        .B      CMP      r0,r1
  23.         0x00000010:    d101        ..      BNE      {pc} + 0x6  ; 0x16
  24.         0x00000012:    2001        .       MOVS     r0,#1
  25.         0x00000014:    e000        ..      B        {pc} + 0x4  ; 0x18
  26.         0x00000016:    2000        .       MOVS     r0,#0
  27.         0x00000018:    0005        ..      MOVS     r5,r0
  28.         0x0000001a:    002a        *.      MOVS     r2,r5
  29.         0x0000001c:    0021        !.      MOVS     r1,r4
  30.         0x0000001e:    a003        ..      ADR      r0,{pc}+0xe ; 0x2c
  31.         0x00000020:    f7fffffe    ....    BL       __0printf  ;
  32.         0x00000024:    2000        .       MOVS     r0,#0
  33.         0x00000026:    bd70        p.      POP      {r4-r6,pc}
  34.     $d
  35.         0x00000028:    00313233    321.    DCD    3224115
  36.         0x0000002c:    203d2061    a =     DCD    540876897
  37.         0x00000030:    202c6425    %d,     DCD    539780133
  38.         0x00000034:    203d2062    b =     DCD    540876898
  39.         0x00000038:    000a6425    %d..    DCD    680997
 楼主| ok2222991 发表于 2010-1-29 10:14 | 显示全部楼层
感谢xinzha兄的关注,
请问
cmp      r2,r0,lsr #8
是指将r2左移8位后与r0比较吗?
xinzha 发表于 2010-1-29 11:28 | 显示全部楼层
按照arm汇编里面的解释,r2同 r0右移8位后的结果比较。
 楼主| ok2222991 发表于 2010-1-29 15:04 | 显示全部楼层
晕,是lsr,我一直都看成是lsl。
cmp r2,r0,lsr #8 的确才是正确的。
应该是ADS的BUG。以前一直用ADS,看来应该多接触下其他的编译器了。
 楼主| ok2222991 发表于 2010-1-29 15:15 | 显示全部楼层
再补充一下,这个问题跟ADS的优化确实有关,把优化级别改到最低,就正确了。


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

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

粉丝
快速回复 在线客服 返回列表 返回顶部