Recently, I have seen a very strange behaviour on uvision4.
When I use a local double variable in my function, it compiles but I see NOP on disassamble window which corresponds to my variable.What is more, double operations which I implement in function has meaningless assemble code as well. However when I change my local variable to static double, it compiles and generates assemble code for my variable and also for my double operations as well.
So I thought that could be limitation for evaluation software, and compile the same code on a licensed computer. Guess what, It generates working code.Everything is OK. So I was wondering if this is a limitation for evaluation software which claims only limitation is 32K code size?
Regards, Deha
Most likely, useless code was optimized away. That would be a feature.
Not true: http://www.keil.com/demo/limits.asp
But, as Mike says, optimisation sounds more likeyl...
I don't think it is an optimization, because it generates assembly code for the SAME source code in a licensed uvision.What is more, the reason that I found out this issue is, I was doing lots of operations with a double variable in one of my functions, and I am always getting an error. When I start debugging, I saw that compiler does not generate any instruction for my operations.
You should give it a try, just do some local operations with a double variable in blinky example. Examine the assembly code. You will see that, in every line of code that does something with your double variable, compiler generates NOP or MOV r0,r0 instruction.
Here is wait function in blinky example
void wait (void) { /* Wait function */ int d; double test = 54.0987 ; d = AD_last; /* Read AD_last value */ if (d != AD_last) /* Make sure that AD interrupt did */ d = AD_last; /* not interfere with value reading */ d *= 500; d += 50000; test = 123456.8 / test ; /* Scale analog value for delay */ /* lower value -> longer delay */ while (d--); /* Only to delay for LED flashes */ }
And here below is generated assembly code for this function
23: double test = 54.0987 ; 0x000002AC E1A00000 NOP 24: d = AD_last; /* Read AD_last value */ 0x000002B0 E59F12E8 LDR R1,[PC,#0x02E8] 0x000002B4 E1D100F0 LDRSH R0,[R1] 25: if (d != AD_last) /* Make sure that AD interrupt did */ 0x000002B8 E1D110F0 LDRSH R1,[R1] 0x000002BC E1500001 CMP R0,R1 0x000002C0 0A000001 BEQ 0x000002CC 26: d = AD_last; /* not interfere with value reading */ 27: 0x000002C4 E59F12D4 LDR R1,[PC,#0x02D4] 0x000002C8 E1D100F0 LDRSH R0,[R1] 28: d *= 500; 0x000002CC E3A01F7D MOV R1,#0x000001F4 0x000002D0 E0000091 MUL R0,R1,R0 29: d += 50000; 30: 0x000002D4 E2800903 ADD R0,R0,#0x0000C000 0x000002D8 E2800E35 ADD R0,R0,#0x00000350 31: test = 123456.8 / test ; /* Scale analog value for delay */ 32: /* lower value -> longer delay */ 0x000002DC E1A00000 NOP 33: while (d--); /* Only to delay for LED flashes */ 0x000002E0 E1A00000 NOP 0x000002E4 E1B01000 MOVS R1,R0 0x000002E8 E2400001 SUB R0,R0,#0x00000001 0x000002EC 1AFFFFFC BNE 0x000002E4 34: }
Any ideas?
Yes. Optimization. The code as shown gives the compiler the right to ignore the variable test.
Wow, it sounds loud and clear.
Thanx Fellas
Change your function in such way it returns 'test' and use the value returned by this function. See if it will generate similar code again