BrownFrog 0 Posted April 12, 2007 Report Share Posted April 12, 2007 Using IDE version: 6.70 Compiler: BoostC for PIC18 Compiler version: 6.70 Target device: PIC18F25J10 OS: Windows XP SP2 The += statement at the end of this code segment compiles incorrectly: #include <system.h> typedef struct _SOCKET_INFO { unsigned char smState; unsigned char TxBuffer; unsigned int TxCount; unsigned int RxCount; unsigned long SND_SEQ; unsigned SND_ACK; } SOCKET_INFO; SOCKET_INFO TCB[4]; void main(void) { SOCKET_INFO *ps; ps = &TCB[1]; // This statement compiles incorrectly ps->SND_SEQ += (unsigned long)ps->TxCount; } The assembler produced is: ps->SND_SEQ += (unsigned long)ps->TxCount; 000C 5032 MOVF main_1_ps+D'1', W 000E 6EEA MOVWF FSR0H 0010 5031 MOVF main_1_ps, W 0012 6EE9 MOVWF FSR0L 0014 0E06 MOVLW 0x06 0016 26E9 ADDWF FSR0L, F 0018 50EF MOVF INDF0, W 001A 6E37 MOVWF CompTempVar494 001C 50EC MOVF PREINC0, W 001E 6E38 MOVWF CompTempVar494+D'1' 0020 50EC MOVF PREINC0, W 0022 6E39 MOVWF CompTempVar494+D'2' 0024 50EC MOVF PREINC0, W 0026 6E3A MOVWF CompTempVar494+D'3' 0028 5032 MOVF main_1_ps+D'1', W 002A 6EEA MOVWF FSR0H 002C 5031 MOVF main_1_ps, W 002E 6EE9 MOVWF FSR0L 0030 0E02 MOVLW 0x02 0032 26E9 ADDWF FSR0L, F 0034 50EE MOVF POSTINC0, W 0036 6E33 MOVWF CompTempVar492 0038 50EF MOVF INDF0, W 003A 6E34 MOVWF CompTempVar492+D'1' 003C 6A35 CLRF CompTempVar492+D'2' 003E 6A36 CLRF CompTempVar492+D'3' 0040 5033 MOVF CompTempVar492, W 0042 2637 ADDWF CompTempVar494, F 0044 5034 MOVF CompTempVar492+D'1', W 0046 2238 ADDWFC CompTempVar494+D'1', F 0048 5035 MOVF CompTempVar492+D'2', W 004A 2239 ADDWFC CompTempVar494+D'2', F 004C 5036 MOVF CompTempVar492+D'3', W 004E 223A ADDWFC CompTempVar494+D'3', F 0050 5037 MOVF CompTempVar494, W 0052 06E9 DECF FSR0L, F 0054 06E9 DECF FSR0L, F 0056 06E9 DECF FSR0L, F 0058 6EEF MOVWF INDF0 005A 5038 MOVF CompTempVar494+D'1', W 005C 6EEC MOVWF PREINC0 005E 5039 MOVF CompTempVar494+D'2', W 0060 6EEC MOVWF PREINC0 0062 503A MOVF CompTempVar494+D'3', W 0064 6EEC MOVWF PREINC0 Note that TxCount is at offset 2 in the structure and SND_SEQ is at offset 6. The assembler code first loads the SND_SEQ member into CompTempVar494 then the TxCount member into CompTempVar492, correctly promoting the 16 bit int to a 32 bit long by clearing the two upper bytes. The 32 bit addition goes into CompTempVar494 and then this is written to the wrong location: the compiler is behaving as if the last location read was the destination of the +=, which it is not. Furthermore, because FSR0 has been incremented only once reading the 2 byte value TxCount, the adjustment of the FSR0 pointer back by 3 bytes means that the 32 bit result is written starting two bytes before the TxCount member, so the two char members smState and TxBuffer are clobbered as well as TxCount. Writing the += as an explict ps->SND_SEQ = ps->SND_SEQ + ps->TxCount produces code that looks correct. The += statement also seems to work if there is no promotion involved eg if we use ps->RxCount in place of ps->SND_SEQ (assembler does addition in-place). Cheers John Quote Link to post Share on other sites
Dave 0 Posted April 12, 2007 Report Share Posted April 12, 2007 John, The += statement at the end of this code segment compiles incorrectly:... <{POST_SNAPBACK}> I've added this to our bugs list.Note: Its also a problem on PIC16 targets. Regards Dave Quote Link to post Share on other sites
Recommended Posts
Join the conversation
You are posting as a guest. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.