遇到了一个理解不了的问题,是Keil编译器的BUG吗?

2020-01-12 17:19发布

本帖最后由 renpeng009672 于 2019-10-6 22:13 编辑

我知道哪儿错了。。。。。。。。。拿无符号数和有符号数进行比较了。。。。。。。
编译器没错
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
简单描述如下:

代码用了一个小OS,串口中断里发送信号给串口接收任务,接收任务里从SBUF取数据,一帧数据以  0x55  0xAA  作为开头,接收任务需要判断发来的数据的前两个字节是不是0x55和0xAA

  1.         while (1)
  2.                 {
  3.                         OSWait(K_SIG,0);//等待串口中断发来信号
  4.                         temp1=SBUF0;
  5.                         if (temp==0x55)
  6.                         {
  7.                                 if (temp1==0xaa)
  8.                                 {
  9.                                         break;
  10.                                 }
  11.                                
  12.                         }
  13.                         temp=temp1;
  14.                 }
  15.                 for (ii=0;ii<NBYTE-2;ii++)
  16.                 {..............
复制代码

按理来说,前两个字节是  0x55  0xAA  的话,会运行到break语句,然后执行for (ii=0;ii<NBYTE-2;ii++)....

但是实践表明,完全不是这样。然后我看了一下反汇编代码:

  1.     48:                 while (1)
  2.     49:                 {
  3.     50:                         OSWait(K_SIG,0);
  4. C:0x0592    E4        CLR      A
  5. C:0x0593    FD        MOV      R5,A
  6. C:0x0594    7F01      MOV      R7,#0x01
  7. C:0x0596    12086D    LCALL    _OSWait(C:086D)
  8.     51:                         temp1=SBUF0;
  9. C:0x0599    85991B    MOV      temp1(0x1B),SBUF0(0x99)
  10.     52:                         if (temp==0x55)
  11. C:0x059C    AF08      MOV      R7,temp(0x08)
  12. C:0x059E    EF        MOV      A,R7
  13. C:0x059F    33        RLC      A
  14. C:0x05A0    95E0      SUBB     A,ACC(0xE0)
  15. C:0x05A2    FE        MOV      R6,A
  16. C:0x05A3    EF        MOV      A,R7
  17. C:0x05A4    6455      XRL      A,#0x55
  18. C:0x05A6    4E        ORL      A,R6
  19. C:0x05A7    700D      JNZ      C:05B6  /////////////看这里
  20.     53:                         {
  21.     54:                                 if (temp1==0xaa)
  22. C:0x05A9    AF1B      MOV      R7,temp1(0x1B)
  23. C:0x05AB    EF        MOV      A,R7
  24. C:0x05AC    33        RLC      A
  25. C:0x05AD    95E0      SUBB     A,ACC(0xE0)
  26. C:0x05AF    FE        MOV      R6,A
  27. C:0x05B0    EF        MOV      A,R7
  28. C:0x05B1    64AA      XRL      A,#0xAA
  29. C:0x05B3    4E        ORL      A,R6
  30. C:0x05B4    6005      JZ       C:05BB  ////////////////////还有这里
  31.     55:                                 {
  32.     56:                                         break;
  33.     57:                                 }
  34.     58:                                
  35.     59:                         }
  36.     60:                         temp=temp1;
  37. C:0x05B6    851B08    MOV      temp(0x08),temp1(0x1B)
  38.     61:                 }
  39. C:0x05B9    80D7      SJMP     Uart0(C:0592)
  40.     62:                 for (ii=0;ii<NBYTE-2;ii++)
  41. C:0x05BB    E4        CLR      A
复制代码

为啥标记的两行不一样捏?然后我改成这样:
  1.        while (1)
  2.                 {
  3.                         OSWait(K_SIG,0);
  4.                         temp1=SBUF0;
  5.                         if (temp==0x55)
  6.                         {
  7.                                 if (temp1!=0xaa)  //////////改成了这样
  8.                                 {
  9.                                         break;
  10.                                 }
  11.                                
  12.                         }
  13.                         temp=temp1;
  14.                 }
  15.                 for (ii=0;ii<NBYTE-2;ii++)
  16.                 {..............
复制代码

发送给单片机  0x55  0xAA  ........时就可以正常运行到break。但是,这不是正确的逻辑啊。。。。

  1.     48:                 while (1)
  2.     49:                 {
  3.     50:                         OSWait(K_SIG,0);
  4. C:0x0592    E4        CLR      A
  5. C:0x0593    FD        MOV      R5,A
  6. C:0x0594    7F01      MOV      R7,#0x01
  7. C:0x0596    12086D    LCALL    _OSWait(C:086D)
  8.     51:                         temp1=SBUF0;
  9. C:0x0599    85991B    MOV      temp1(0x1B),SBUF0(0x99)
  10.     52:                         if (temp==0x55)
  11. C:0x059C    AF08      MOV      R7,temp(0x08)
  12. C:0x059E    EF        MOV      A,R7
  13. C:0x059F    33        RLC      A
  14. C:0x05A0    95E0      SUBB     A,ACC(0xE0)
  15. C:0x05A2    FE        MOV      R6,A
  16. C:0x05A3    EF        MOV      A,R7
  17. C:0x05A4    6455      XRL      A,#0x55
  18. C:0x05A6    4E        ORL      A,R6
  19. C:0x05A7    700D      JNZ      C:05B6  /////////////////看这里
  20.     53:                         {
  21.     54:                                 if (temp1!=0xaa)
  22. C:0x05A9    AF1B      MOV      R7,temp1(0x1B)
  23. C:0x05AB    EF        MOV      A,R7
  24. C:0x05AC    33        RLC      A
  25. C:0x05AD    95E0      SUBB     A,ACC(0xE0)
  26. C:0x05AF    FE        MOV      R6,A
  27. C:0x05B0    EF        MOV      A,R7
  28. C:0x05B1    64AA      XRL      A,#0xAA
  29. C:0x05B3    4E        ORL      A,R6
  30. C:0x05B4    7005      JNZ      C:05BB       /////////////还有这里
  31.     55:                                 {
  32.     56:                                         break;
  33.     57:                                 }
  34.     58:                                
  35.     59:                         }
  36.     60:                         temp=temp1;
  37. C:0x05B6    851B08    MOV      temp(0x08),temp1(0x1B)
  38.     61:                 }
  39. C:0x05B9    80D7      SJMP     Uart0(C:0592)
  40.     62:                 for (ii=0;ii<NBYTE-2;ii++)
  41. C:0x05BB    E4        CLR      A
复制代码


求大神解惑

备注:win7 x86系统       Keil V5.25
友情提示: 此问题已得到解决,问题已经关闭,关闭后问题禁止继续编辑,回答。
11条回答
takashiki
2020-01-14 00:29
LZ,很遗憾的告诉你,这个真是编译器的BUG,马老师说过,Keil发布的新版本修正了。
8位不管是有符号还是无符号数都可以自动类型提升为int类型,因此比较是不会出问题的。但是Keil C51这里却出问题了,那么就是Keil的锅,在没有升级编译器之前你只好自己背了。
但如果是int自动提升为unsigned int,那么没的说,程序员的锅没跑。

一周热门 更多>