Hi,
I have a function with three varibles:
uint8_t address;
uint8_t tmp;
uint32_t data;
Later in the function I do the following:
address = (uint8_t) (data>>24);
tmp = (uint8_t) (data>>16);
if (address != (~tmp))
{
...
return;
}
Now, the value of data is such that the comparison should is false, instead
however, the code inside the statement always runs. On disassembly, this
is what I find:
address = (uint8_t) (data>>24);
fe64: 1e 44 06 00 mov 6(r4), r14 ;
fe68: 1f 44 08 00 mov 8(r4), r15 ;
fe6c: 0e 4f mov r15, r14 ;
fe6e: 0f 43 clr r15 ;
fe70: 8e 10 swpb r14 ;
fe72: 7e f3 and.b #-1, r14 ;r3 As==11
fe74: c4 4e 0b 00 mov.b r14, 11(r4) ;
tmp = (uint8_t) (data>>16);
fe78: 1e 44 06 00 mov 6(r4), r14 ;
fe7c: 1f 44 08 00 mov 8(r4), r15 ;
fe80: 0e 4f mov r15, r14 ;
fe82: 0f 43 clr r15 ;
fe84: c4 4e 0a 00 mov.b r14, 10(r4) ;
if (address != (~tmp))
fe88: 5e 44 0b 00 mov.b 11(r4), r14 ;
fe8c: 5f 44 0a 00 mov.b 10(r4), r15 ;
fe90: 3f e3 inv r15 ;
fe92: 0e 9f cmp r15, r14 ;
fe94: 0a 24 jz $+22 ;abs 0xfeaa
Now, I'm not positive this is the root of the problem, but I think that the
second from last line, the cmp r15, r14, needs to actully be a cmp.b
As evidence of this, with everything else the same, the following statement
does perform as expected:
if ((address & 0x00ff) != ((~tmp) & 0x00ff))
{
...
}
As a strange connected but different problem, in testing I also tried the
following:
address = 0x00;
tmp = ~(address);
if (address != (~tmp)) { ... }
On disassembly, this code always gets run. The opposite test:
address = 0x00;
tmp = ~(address);
if (address == (~tmp)) { ... }
shows on disassembly that it never gets run. Unless I'm really burnt out,
this is exactly backwards. The first code should never run because you're
inverting the same value twice, so you should be back to where you started
and the values are equal, but the test is "!=". And you can follow from
that the second case as well.
Can anybody tell me if I'm wrong or if some bad assembly is getting emitted?
-Charles