We are running a survey to help us improve the experience for all of our members. If you see the survey appear, please take the time to tell us about your experience if you can.
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.
"The important thing is that the compiler make a wrong logical judge."
Looks like that the compiler optimisation is smarter than the programmer.
Yes, but still not as smart as it should be. It should have optimized away everything except the first line. If the variable pop_value isn't used anywhere in a non-trivial way, it should have optimized away the first line too. Bottom line: the source code should compile into nothing.
Yes, but still not as smart as it should be. It should have optimized away everything except the first line. maybe not, but Keil, in their infinite wisdom, do all optimizing in the linker.
Erik
maybe not, but Keil, in their infinite wisdom, do all optimizing in the linker
Not all --- not by a rather wide margin. I'm pretty sure none of the linker-based optimazation are relevant to the example under study. This should be optimized to nothing before the linker is even run.
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.
I still wonder why the making a switch an indirect jump instead of a combersome calculation (when the state values are 'organized') is not done in the compiler but in the linker
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