今天做项目的时候发现Keil中一个重大疑惑,也许是Keil的一个BUG.如下:
(STC89C52,请留意红色字体!)
第一种情况:(正确的)
先进行位定义
sbit    P10   =     P1^0;
sbit    P11   =     P1^1;
sbit    P12   =     P1^2;
sbit    P13   =     P1^3;
然后在函数中使用
for(i=0;ip;
        
if(P10==0){
          keyTmp = (i*4+1);
          goto out1;
        
}else if(P11==0){
          keyTmp = (i*4+2);
          goto out1;
        
}else if(P12==0){
          keyTmp = (i*4+3);
          goto out1;
         
}else if(P13==0){
          keyTmp = (i*4+4);
          goto out1;
         }
         tmp<<=1;
        }
Keil的汇编结果如下:
    50:         for(i=0;i<4;i++){
C:0x005C    E4       CLR      A
C:0x005D    FD       MOV      R5,A
    51:                 P1=~tmp;
C:0x005E    EF       MOV      A,R7
C:0x005F    F4       CPL      A
C:0x0060    F590     MOV      P1(0x90),A
    52:               
if(P10==0){
C:0x0062    209009   JB       P10(0x90.0),C:006E
    53:                         keyTmp = (i*4+1);
C:0x0065    ED       MOV      A,R5
C:0x0066    25E0     ADD      A,ACC(0xE0)
C:0x0068    25E0     ADD      A,ACC(0xE0)
C:0x006A    04       INC      A
C:0x006B    FE       MOV      R6,A
    54:                         goto out1;
C:0x006C    804D     SJMP     C:00BB
    55:               
}else if(P11==0){
C:0x006E    20910A   JB       P11(0x90.1),C:007B
    56:                         keyTmp = (i*4+2);
C:0x0071    ED       MOV      A,R5
C:0x0072    25E0     ADD      A,ACC(0xE0)
C:0x0074    25E0     ADD      A,ACC(0xE0)
C:0x0076    2402     ADD      A,#0x02
C:0x0078    FE       MOV      R6,A
    57:                         goto out1;
C:0x0079    8040     SJMP     C:00BB
   
58:                 }else if(P12==0){
C:0x007B    20920A   JB       P12(0x90.2),C:0088
    59:                         keyTmp = (i*4+3);
C:0x007E    ED       MOV      A,R5
C:0x007F    25E0     ADD      A,ACC(0xE0)
C:0x0081    25E0     ADD      A,ACC(0xE0)
C:0x0083    2403     ADD      A,#0x03
C:0x0085    FE       MOV      R6,A
    60:                         goto out1;
C:0x0086    8033     SJMP     C:00BB
    61:                 }else if(P13==0){
C:0x0088    20930A   JB       P13(0x90.3),C:0095
    62:                         keyTmp = (i*4+4);
C:0x008B    ED       MOV      A,R5
C:0x008C    25E0     ADD      A,ACC(0xE0)
C:0x008E    25E0     ADD      A,ACC(0xE0)
C:0x0090    2404     ADD      A,#0x04
C:0x0092    FE       MOV      R6,A
    63:                         goto out1;
C:0x0093    8026     SJMP     C:00BB
    64:                 }
这种方法是我想要的结果。

第二种情况:
不进行位宏定义,直接在函数中使用
for(i=0;i<4;i++){
         P1=~tmp;
      
  if(P1^0==0){
          keyTmp = (i*4+1);
          goto out1;
        
}else if(P1^1==0){
          keyTmp = (i*4+2);
          goto out1;
         
}else if(P1^2==0){
          keyTmp = (i*4+3);
          goto out1;
        
}else if(P1^3==0){
          keyTmp = (i*4+4);
          goto out1;
         }
         tmp<<=1;
        }
此时Keil的汇编结果如下:
    50:         for(i=0;i<4;i++){
C:0x005F    E4       CLR      A
C:0x0060    FD       MOV      R5,A
    51:                 P1=~tmp;
C:0x0061    EF       MOV      A,R7
C:0x0062    F4       CPL      A
C:0x0063    F590     MOV      P1(0x90),A
    52:                 if(P1^0==0){
C:0x0065    E590     MOV      A,P1(0x90)
C:0x0067    6401     XRL      A,#0x01
C:0x0069    6009     JZ       C:0074
    53:                         keyTmp = (i*4+1);
C:0x006B    ED       MOV      A,R5
C:0x006C    25E0     ADD      A,ACC(0xE0)
C:0x006E    25E0     ADD      A,ACC(0xE0)
C:0x0070    04       INC      A
C:0x0071    FE       MOV      R6,A
    54:                         goto out1;
C:0x0072    8050     SJMP     C:00C4
    55:                 }else if(P1^1==0){
C:0x0074    E590     MOV      A,P1(0x90)
C:0x0076    600A     JZ       C:0082
    56:                         keyTmp = (i*4+2);
C:0x0078    ED       MOV      A,R5
C:0x0079    25E0     ADD      A,ACC(0xE0)
C:0x007B    25E0     ADD      A,ACC(0xE0)
C:0x007D    2402     ADD      A,#0x02
C:0x007F    FE       MOV      R6,A
    57:                         goto out1;
C:0x0080    8042     SJMP     C:00C4
    58:                 }else if(P1^2==0){
C:0x0082    E590     MOV      A,P1(0x90)
C:0x0084    600A     JZ       C:0090
    59:                         keyTmp = (i*4+3);
C:0x0086    ED       MOV      A,R5
C:0x0087    25E0     ADD      A,ACC(0xE0)
C:0x0089    25E0     ADD      A,ACC(0xE0)
C:0x008B    2403     ADD      A,#0x03
C:0x008D    FE       MOV      R6,A
    60:                         goto out1;
C:0x008E    8034     SJMP     C:00C4
    61:                 }else if(P1^3==0){
C:0x0090    E590     MOV      A,P1(0x90)
C:0x0092    600A     JZ       C:009E
    62:                         keyTmp = (i*4+4);
C:0x0094    ED       MOV      A,R5
C:0x0095    25E0     ADD      A,ACC(0xE0)
C:0x0097    25E0     ADD      A,ACC(0xE0)
C:0x0099    2404     ADD      A,#0x04
C:0x009B    FE       MOV      R6,A
    63:                         goto out1;
C:0x009C    8026     SJMP     C:00C4
    64:                 }
变成了判断P1是否为0,与我想要的结果大相径庭!
因为这个问题,让我足足调试时间花多一个多小时呀!
哪位高手能解释下是什么原因吗?