This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

A compiler bug of Keil C V6.21

#include <reg52.h>

// Due to these two options, the
// program always goes wrong.
#pragma NOINTPROMOTE
#pragma OPTIMIZE(7, SPEED)

unsigned long xdata CommonValue;
unsigned char xdata Result;

void UseResult(void)
{
P3=Result;
}

void Func()
{
for (;;)
{
// Surely, Common Value is 100,
if (CommonValue > 0L)
{
// Should come here
Result = 0xff;
}
else
{
// But it always comes here.
Result = 0;
}

UseResult();
}
}

void main(void)
{
CommonValue=100;
Func();
}


Parents
  • 
    #include <reg52.h>
    
    #pragma NOINTPROMOTE
    #pragma OPTIMIZE(7, SPEED)
    
    unsigned long xdata CommonValue;
    unsigned char xdata Result;
    
    void UseResult(void)
    {
      P3=Result;
    }
    
    void Func()
    {
      for (;;) 
      {
        if (CommonValue > 0L) // Surely, Common Value is 100, 
        {
          Result = 0xff;  // Should be here
        } 
        else 
        {
          Result = 0;     // But it always comes here.
        }
    
        UseResult();
      }
    }
    
    void main(void)
    {
      CommonValue=100;
      Func();
    }
    
    

Reply
  • 
    #include <reg52.h>
    
    #pragma NOINTPROMOTE
    #pragma OPTIMIZE(7, SPEED)
    
    unsigned long xdata CommonValue;
    unsigned char xdata Result;
    
    void UseResult(void)
    {
      P3=Result;
    }
    
    void Func()
    {
      for (;;) 
      {
        if (CommonValue > 0L) // Surely, Common Value is 100, 
        {
          Result = 0xff;  // Should be here
        } 
        else 
        {
          Result = 0;     // But it always comes here.
        }
    
        UseResult();
      }
    }
    
    void main(void)
    {
      CommonValue=100;
      Func();
    }
    
    

Children
  • Thanks for the more readable code.

    To return to your original question:

    // Due to these two options, the 
    // program always goes wrong.
    #pragma NOINTPROMOTE
    #pragma OPTIMIZE(7, SPEED)
    
    Do you mean that your program behaves differently with different #pragmas?

    If you do get strange results where the value of a variable seems to be stuck at either binary all zeros or all ones, it may be a good idea to suspect the hardware.
    Your code example is sufficiently simple, that you should be able to work through (or step through) the assembly language listing to see just what is going on.

  • I read the .src file generated by uv2, the very different code will be get by using "0L" and "1L", so I think this is a bug. I just simulate this sample code using uv2, when use "0L" it will reach the wrong way.

  • Can you post the .scr?
    (not foretting the the &ltpre&gt and &lt/pre&gt tags, of course!)

  • <PRE>

    stmt level source

    1 #include <reg52.h>
    2
    3 #pragma NOINTPROMOTE
    4 #pragma OPTIMIZE(7, SPEED)
    5
    6 unsigned long xdata CommonValue;
    7 unsigned char xdata Result;
    8
    9 void UseResult(void)
    10 {
    11 1 P3=Result;
    12 1 }
    13
    14 void Func()
    15 {
    16 1 for (;;)
    17 1 {
    18 2 if (CommonValue > 0L) // Surely, Common Value is 100,
    19 2 {
    20 3 Result = 0xff; // Should be here
    21 3 }
    22 2 else
    23 2 {
    24 3 Result = 0; // But it always comes here.
    25 3 }
    26 2
    27 2 UseResult();
    28 2 }
    29 1 }
    30
    31 void main(void)
    32 {
    33 1 CommonValue=100;
    34 1 Func();
    35 1 }
    36
    C51 COMPILER V6.21 MAIN 12/06/2001 22:51:35 PAGE 2

    ASSEMBLY LISTING OF GENERATED OBJECT CODE


    ; FUNCTION UseResult (BEGIN)
    ; SOURCE LINE # 9
    ; SOURCE LINE # 10
    ; SOURCE LINE # 11
    0000 900000 R MOV DPTR,#Result
    0003 E0 MOVX A,@DPTR
    0004 F5B0 MOV P3,A
    ; SOURCE LINE # 12
    0006 22 RET
    ; FUNCTION UseResult (END)

    ; FUNCTION Func (BEGIN)
    ; SOURCE LINE # 14
    ; SOURCE LINE # 15
    ; SOURCE LINE # 16
    0000 ?C0002:
    ; SOURCE LINE # 17
    ; SOURCE LINE # 18
    0000 900000 R MOV DPTR,#CommonValue
    0003 E0 MOVX A,@DPTR
    0004 FC MOV R4,A
    0005 A3 INC DPTR
    0006 E0 MOVX A,@DPTR
    0007 FD MOV R5,A
    0008 A3 INC DPTR
    0009 E0 MOVX A,@DPTR
    000A FE MOV R6,A
    000B A3 INC DPTR
    000C E0 MOVX A,@DPTR
    000D FF MOV R7,A
    000E EC MOV A,R4
    000F 33 RLC A
    0010 600A JZ ?C0004
    0012 4008 JC ?C0004
    ; SOURCE LINE # 19
    ; SOURCE LINE # 20
    0014 900000 R MOV DPTR,#Result
    0017 74FF MOV A,#0FFH
    0019 F0 MOVX @DPTR,A
    ; SOURCE LINE # 21
    001A 8005 SJMP ?C0005
    001C ?C0004:
    ; SOURCE LINE # 23
    ; SOURCE LINE # 24
    001C E4 CLR A
    001D 900000 R MOV DPTR,#Result
    0020 F0 MOVX @DPTR,A
    ; SOURCE LINE # 25
    0021 ?C0005:
    ; SOURCE LINE # 27
    0021 120000 R LCALL UseResult
    ; SOURCE LINE # 28
    0024 80DA SJMP ?C0002
    0026 22 RET
    ; FUNCTION Func (END)

    ; FUNCTION main (BEGIN)
    ; SOURCE LINE # 31
    ; SOURCE LINE # 32
    C51 COMPILER V6.21 MAIN 12/06/2001 22:51:35 PAGE 3

    ; SOURCE LINE # 33
    0000 900000 R MOV DPTR,#CommonValue
    0003 120000 E LCALL ?C?LSTKXDATA
    0006 00 DB 00H
    0007 00 DB 00H
    0008 00 DB 00H
    0009 64 DB 064H
    ; SOURCE LINE # 34
    000A 120000 R LCALL Func
    ; SOURCE LINE # 35
    000D 22 RET
    ; FUNCTION main (END)

    C51 COMPILER V6.21 MAIN .
    .
    .
    </PRE>

  • I just use:

    {
      bit SavedIe = IE; IE = 0;
      //the synchronize code
      IE = SavedIe; 
    }
    

  • Ignore the above message. It was posted to the wrong thread.

  • The assembly language for line 18 does not look right to me. The code reads the four bytes of CommonValue into R4, R5, R6 and R7. Fine. The code then does an RLC on the byte in R4 before checking its value - very odd...

    One thing you should try is to lower the level of optimisation to 0 and see if you get sensible looking assembly code and a working program. If you do, increment the optimisation level one step at a time to find out where things start to go wrong. I'm sure Keil support will be interested to hear your results.


  • The source is the same except this line
    "if (CommonValue > 0L)":
    ^^here

    This is the result by using "0L"

    ;     if (CommonValue > 0L) // Surely, Common Value is 100, 
    			; SOURCE LINE # 19
    	MOV  	DPTR,#CommonValue
    	MOVX 	A,@DPTR
    	MOV  	R4,A
    	INC  	DPTR
    	MOVX 	A,@DPTR
    	MOV  	R5,A
    	INC  	DPTR
    	MOVX 	A,@DPTR
    	MOV  	R6,A
    	INC  	DPTR
    	MOVX 	A,@DPTR
    	MOV  	R7,A
    	MOV  	A,R4
    	RLC  	A
    	JZ   	?C0004
    	JC   	?C0004
    

    and this is the result by using "2L"
    ;     if (CommonValue > 2L) // Surely, Common Value is 100, 
    			; SOURCE LINE # 19
    	MOV  	DPTR,#CommonValue
    	MOVX 	A,@DPTR
    	MOV  	R4,A
    	INC  	DPTR
    	MOVX 	A,@DPTR
    	MOV  	R5,A
    	INC  	DPTR
    	MOVX 	A,@DPTR
    	MOV  	R6,A
    	INC  	DPTR
    	MOVX 	A,@DPTR
    	MOV  	R7,A
    	CLR  	A
    	MOV  	R3,#02H
    	MOV  	R2,A
    	MOV  	R1,A
    	MOV  	R0,A
    	CLR  	C
    	LCALL	?C?SLCMP
    	JNC  	?C0004