Hi!
In a full project a simple unsigned long ( u32 )returned value from a function lead to this (odd) assembler code. It make us think that the u32 is considered as s16 ( signed short ).
If the sub-function th_microSecondsNow() returns the u32 0x0000FFCA the local_us returned will be 0xFFFFFFCA. If the returned u32 is 0x00120233 the local_us returned will be 0x00000233.
For example the value is well settled in R4 = 00, R5 = 12, R6 = 02, R7 = 33 but at the end R4 = 00, R5 = 00, R6 = 02, R7 = 33
We tried the same code in an empty project and in this case the function's behaviour is totally normal ( returned local_us values 0x0000FFCA or 0x00120233 ).
Any Ideas of what went wrong?
Many thanks in advance.
//please find below the assembler code abstract
271: u32 microSecondsNow(void) 272: { 273: u32 local_us; 274: local_us = th_microSecondsNow(); C:0x8DCB 1287A5 LCALL th_microSecondsNow(C:87A5) C:0x8DCE EE MOV A,R6 C:0x8DCF 33 RLC A C:0x8DD0 95E0 SUBB A,ACC(0xE0) C:0x8DD2 FD MOV R5,A C:0x8DD3 FC MOV R4,A C:0x8DD4 900D1C MOV DPTR,#0x0D1C C:0x8DD7 121DD0 LCALL C?LSTXDATA(C:1DD0) 275: return local_us;
Traditional C assumes that functions takes int parameters and returns int. And that variables without a type is int.
And this will result in big problems when you have an 8-bit processor with 16-bit int and a function that returns 32-bit unsigned.
This is a reason why using C++ (even for C-style programs) makes C++ a better C. Type-safe linking makes sure that you don't accidentally call a function with wrong parameter or return type.
I'm not sure exactly what makes the compiler decide that the uint32 pointer parameter of the second function should be giving an error while the other function without parameters should just result in a warning. Best is if the compiler is configured to upgrade all warnings about missing prototypes into full errors to avoid producing programs that looks like they should work but secretly produces broken results.