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

KeilC51 can not compile this code correctly

hi: I have a code below:

     char pop_value = 0X80;
     if(pop_value == 0X80)
     {
         pop_value = pop_value;//point 1

     }
     pop_value = pop_value;//point 2

I would have thought the code would jump to point 1 after logical judge, but the simulating result exceed my expectations that the code jumped to point 2. I watch the Disassembly code :

    82:             pop_value = 0X80; 
C:0x0A68    7853     MOV      R0,#pop_value(0x53)
C:0x0A6A    7680     MOV      @R0,#P0(0x80)
     83:             if(pop_value == 0X80) 
C:0x0A6C    E6       MOV      A,@R0
C:0x0A6D    FF       MOV      R7,A
C:0x0A6E    FD       MOV      R5,A
C:0x0A6F    33       RLC      A
C:0x0A70    95E0     SUBB     A,ACC(0xE0)
C:0x0A72    FC       MOV      R4,A
C:0x0A73    ED       MOV      A,R5
C:0x0A74    6480     XRL      A,#P0(0x80)
C:0x0A76    4C       ORL      A,R4
C:0x0A77    7002     JNZ      C:0A7B
    84:             {
    85:             pop_value = pop_value;
    86: 
C:0x0A79    A607     MOV      @R0,0x07
    87:             }
C:0x0A7B    22       RET
                 PUTCHAR:


I can not find the error happened.so I also compile this C code in another project. the code can jump to point 1 after logical judge ,nor jump to point 2.I watch the the Disassembly code at once:

    61:      item = 0X80; 
C:0x0A94    752400   MOV      0x24,#malloc_mempool(0x00)
C:0x0A97    752580   MOV      0x25,#P0(0x80)
    62:      if( item== 0x80) 
C:0x0A9A    E525     MOV      A,0x25
C:0x0A9C    6480     XRL      A,#P0(0x80)
C:0x0A9E    4524     ORL      A,0x24
C:0x0AA0    7006     JNZ      C:0AA8
    63:      {
    64:      item =item; 
C:0x0AA2    852424   MOV      0x24,0x24
C:0x0AA5    852525   MOV      0x25,0x25
    65:      }


my keiC51 version is V8.16. I don't know why the same C code has different assemble code in different project. The important thing is that the compiler make a wrong logical judge.

Parents
  • I can not find the error happened.

    Well, then how you do know there is an error to be found?

    so I also compile this C code in another project.

    No, you didn't. That's not the same code. For starters, 'item' has a different data type than 'pop_value'.

    The important thing is that the compiler make a wrong logical judge.

    No. The important thing is for you to understand that you're wrong about what the compiler is required to do, and what it's not. It's not required to compile that conditional instruction into any code at all. And statements like

    item=item;
    

    don't do anything (unless 'item' is volatile), so they can be removed entirely.

Reply
  • I can not find the error happened.

    Well, then how you do know there is an error to be found?

    so I also compile this C code in another project.

    No, you didn't. That's not the same code. For starters, 'item' has a different data type than 'pop_value'.

    The important thing is that the compiler make a wrong logical judge.

    No. The important thing is for you to understand that you're wrong about what the compiler is required to do, and what it's not. It's not required to compile that conditional instruction into any code at all. And statements like

    item=item;
    

    don't do anything (unless 'item' is volatile), so they can be removed entirely.

Children
  • hi: Thanks your advice. But I just want to know how to solve this problem or avoid this error happening again.how to change the keil compiler to produce correct assemble language .I found the keil compiler produce wrong code sometime .It is associate with what problem.My code has bug or the compiler's wrong?

  • Start by finding an example where the compiler produces the wrong code - and where you haven't made too many assumptions about what the compiler should do when you give it meaningless code to chew on.

  • "how to change the keil compiler to produce correct assemble language."

    To overcome the situation you consider to be an error, I would suggest that you find a compiler that is guaranteed to produce totally non-optimised code.

  • Does setting the optimisation to minimum in C51 achieve that?

    But do note that no 'C' compiler is required to give a 1:1 direct, in-sequence relationship between source code and executable - that's a fundamental principle of HLLs! If you want that, then you have to write in Assembler!

  • I don't think it does - But may be wrong.

    Many years ago, when I first looked into C compilers, the one-to-one relationship appeared to be quite common and any form of optimization was an extra.

  • You may be right:

    Level-0 (ie, minimum) optimisations are:

    "Constant Folding: The compiler performs calculations that reduce expressions to numeric constants, where possible. This includes calculations of run-time addresses.

    "Simple Access Optimizing: The compiler optimizes access of internal data and bit addresses in the 8051 system.

    "Jump Optimizing: The compiler always extends jumps to the final target. Jumps to jumps are eliminated."

    Level-1 optimisations are:

    "Dead Code Elimination: Unused code fragments and artifacts are eliminated.

    "Jump Negation: Conditional jumps are closely examined to see if they can be streamlined or eliminated by the inversion of the test logic."

    http://www.keil.com/support/man/docs/c51/c51_optimize.htm

  • But I just want to know how to solve this problem or avoid this error happening again

    You have not shown us any problem worth solving, much less an actual error!

    how to change the keil compiler to produce correct assemble language

    You don't. Because it's brutally obvious that you don't know what correct or incorrect assembly code is, in this context.

    My code has bug or the compiler's wrong?

    So far: neither. The only thing you have demonstrated to be wrong so far is your understanding of what the job of a C compiler is.

  • hi: everybody,I have found the reason that the pop_value variable should be defined unsigned char type,or the compiler would produce wrong disassemble code.But I do not why?

  • the pop_value variable should be defined unsigned char type,or the compiler would produce wrong disassemble code.But I do not why?
    the previous post said"
    So far: neither. The only thing you have demonstrated to be wrong so far is your understanding of what the job of a C compiler is.
    now we can add
    The other thing you have demonstrated to be wrong is your understanding of C and the '51

    Erik

  • Read this and thought it must be 1st April.

    Surely this is a [really rather poor] wind-up.

  • I have found the reason

    No, you haven't. You haven't found anything. What you have done so far is imagine things.

    or the compiler would produce wrong disassemble code.

    So you've been claiming all through this thread. And all that while this judgement of yours has been based on incorrect assumptions about what qualifies compiler output as correct.

    I.e. you haven't found anything, and you haven't learned anything either. Which begs the question why you're even bothering to ask questions, given that you couldn't care less about the answers.