Hi there,
Included below is a sample disassembly output of some code I just discovered not behaving the way I think it should. Basically, it seems the compiler has determined that there is no need to return from the current function and instead can safely jump into the next function and return from that. Unfortunately, it cocks up the argument registers before it jumps!!!
The call to InitE888Receive from CANStr_GetSpecialChannelSetup mucks up the registers. See the note in the middle of the disassembly below to see how!
Code is:
UCAN_SPECIAL_CHAN_SETUP * InitE888Receive(uint32 ACANID) { // Malloc a struct and then initialise it... UCAN_SPECIAL_CHAN_SETUP * specialSetup = UCAN_AllocSpecialSetup(2); if(specialSetup != NULL) { specialSetup->fptrRxCallBack = E888Receive; specialSetup->CANIDs[0] = ACANID; specialSetup->CANIDs[1] = ACANID + 1; } return specialSetup; } UCAN_SPECIAL_CHAN_SETUP * CANStr_GetSpecialChannelSetup(uint8 AMode, uint32 ACANID) { if(AMode == 138) { return InitE888Receive(ACANID); } else { return NULL; } /*switch(AMode) <-- This has the same problem as above too! { case 138: return InitE888Receive(ACANID); default: return NULL; }*/ } 182: UCAN_SPECIAL_CHAN_SETUP * InitE888Receive(uint32 ACANID) 00046D86 ECFE PUSH R14 00046D88 ECFF PUSH R15 00046D8A F0E8 MOV R14,R8 00046D8C F0F9 MOV R15,R9 183: { 184: // Malloc a struct and then initialise it... 185: UCAN_SPECIAL_CHAN_SETUP * specialSetup = UCAN_AllocSpecialSetup(2); 00046D8E E028 MOV R8,#0x02 00046D90 DA0368AF CALLS UCAN_AllocSpecialSetup(0x3AF68) 00046D94 F0A4 MOV R10,R4 00046D96 F0B5 MOV R11,R5 186: if(specialSetup != NULL) 187: { 00046D98 7045 OR R4,R5 00046D9A 2D1F JMPR CC_Z,0x046DDA 188: specialSetup->fptrRxCallBack = E888Receive; 00046D9C E6F6726D MOV R6,#0x6D72 00046DA0 E6F70400 MOV R7,#0x0004 00046DA4 DC7B EXTP R11,#4 00046DA6 C46A0400 MOV [R10+#0x0004],R6 00046DAA C47A0600 MOV [R10+#0x0006],R7 189: specialSetup->CANIDs[0] = ACANID; 00046DAE D45A0C00 MOV R5,[R10+#0x000C] 00046DB2 D44A0A00 MOV R4,[R10+#0x000A] 00046DB6 DC55 EXTP R5,#2 00046DB8 B8E4 MOV [R4],R14 00046DBA C4F40200 MOV [R4+#0x0002],R15 190: specialSetup->CANIDs[1] = ACANID + 1; 00046DBE F08E MOV R8,R14 00046DC0 F09F MOV R9,R15 00046DC2 0881 ADD R8,#1 00046DC4 1890 ADDC R9,#0 00046DC6 DC5B EXTP R11,#2 00046DC8 D45A0C00 MOV R5,[R10+#0x000C] 00046DCC D44A0A00 MOV R4,[R10+#0x000A] 00046DD0 DC55 EXTP R5,#2 00046DD2 C4840400 MOV [R4+#0x0004],R8 00046DD6 C4940600 MOV [R4+#0x0006],R9 191: } 192: return specialSetup; 00046DDA F05B MOV R5,R11 00046DDC F04A MOV R4,R10 193: } 194: 00046DDE FCFF POP R15 00046DE0 FCFE POP R14 00046DE2 DB00 RETS 195: UCAN_SPECIAL_CHAN_SETUP * CANStr_GetSpecialChannelSetup(uint8 AMode, uint32 ACANID) 196: { 197: if(AMode == 138) 198: { 00046DE4 F048 MOV R4,R8 00046DE6 47F88A00 CMPB RL4,#0x008A 00046DEA 3D04 JMPR CC_NZ,0x046DF4 199: return InitE888Receive(ACANID); ********* GOES WRONG HERE ********* This should be putting R14/R15 into R8/R9 Instead it copies R10 into R8/R9 which weird as it should actually be a 32 bit copy anyways!!! 00046DEC F09A MOV R9,R10 00046DEE F08A MOV R8,R10 00046DF0 FA04866D JMPS InitE888Receive(0x46D86) 200: } 201: else 202: { 203: return NULL; 00046DF4 E004 MOV R4,#0x00 00046DF6 E005 MOV R5,#0x00 204: } 00046DF8 DB00 RETS