Hi Mike, Your example shows just how important it is for embedded programmers to look at what their compiler does and tailor their habits to this. I've got three examples here and the last produces the targeted 4 instructions once the page bits are set: I get 9 , 6 and finally 4 instructions. All examples were done with Rev 1.4 of the Bytecraft MPC compiler. Here we do the standard shift and add. Makes no difference if workbuf is char or unsigned char and we have 9 instructions. 005B typedef long int16; 0147 unsigned int16 eth_length; 0149 000A char workbuff[10]; void test (void) { 08D0 1283 BCF STATUS,RP0 eth_length = (workbuff[3] << 8) + workbuff[2]; 08D1 1703 BSF STATUS,RP1 08D2 084C MOVF 4C,W 08D3 00FE MOVWF 7E 08D4 0100 CLRW 08D5 074B ADDWF 4B,W 08D6 00C7 MOVWF 47 08D7 3000 MOVLW 00h 08D8 00FE MOVWF 7E 08D9 0D7E RLF 7E,W 08DA 00C8 MOVWF 48 08DB 0008 RETURN } When I use the OR instead of the '+' I get rid of the signed number stuff and down to 6 instructions. 005B typedef long int16; 0147 unsigned int16 eth_length; 0149 000A char workbuff[10]; void test (void) { 08D0 1283 BCF STATUS,RP0 eth_length = (workbuff[3] << 8) | workbuff[2]; 08D1 1703 BSF STATUS,RP1 08D2 084C MOVF 4C,W 08D3 00FE MOVWF 7E 08D4 0100 CLRW 08D5 044B IORWF 4B,W 08D6 01C8 CLRF 48 08D7 00C7 MOVWF 47 08D8 0008 RETURN } And finally when I do it my way we have the desired 4 instructions: 005B typedef long int16; 0147 unsigned int16 eth_length; 0149 000A char workbuff[10]; void test (void) { 08D0 1283 BCF STATUS,RP0 eth_length = * (int16 *) &workbuff[2]; 08D1 1703 BSF STATUS,RP1 08D2 084B MOVF 4B,W 08D3 00C7 MOVWF 47 08D4 084C MOVF 4C,W 08D5 00C8 MOVWF 48 08D6 0008 RETURN } Each method from the C perspective is correct. The first two examples are the most readable from a coding point of view. I'd look at that and know immediately what was happening. The union examples leave me perplexed with all the braces etc and unless they made the most optimal code I wouldn't allow that style. The third example does require an understanding of pointers and needs to be read from right to left. I suggest that whatever compiler someone is using that they do some of these basic examples and document them in a .h file with the defines for WORD, BYTE LONGWORD, UI, UC, etc. They key word is documentation and why the choice was made. For this example it's obvious that the Bytecraft creates more efficient code than the CCS. For your example below on the comparison if the variable I'm assigning the bytes into is a WORD then the tests if (word_var2 > word_var) works. What I found when I tried your structures in the comparison that the code became horrendously complicated even with the type coercions. The shortest code was the compare mentioned above. Regards, John Dammeyer > -----Original Message----- > From: pic microcontroller discussion list > [mailto:PICLIST@MITVMA.MIT.EDU] On Behalf Of Mike Mansheim > Sent: Thursday, April 11, 2002 2:05 PM > To: PICLIST@MITVMA.MIT.EDU > Subject: Re: [pic] c compiler comparison > > > Should this go [OT]?? > > >From Bob A: > > So, try this: > > > ( (union_lo_hi *) ð_length)->b.l = 123; // assign low byte > ^ > took this out > > This doesn't compile either - same error messages. Is this a CCS > problem? > > >From John D (a while ago - sorry): > > > My_16bitInt = *(WORD *)&bytearray[5]; > > This does compile, although with the CCS compiler it is not quite as > efficient. To address your other comments, I am always checking to > see what the compiler is producing - that's how I got involved in this > thread! > > This seems to be getting quite complex for the original problem. To > recap, this part of this thread is discussing a c standard way of > addressing the low and high bytes of a word variable, to force more > efficient compiling for situations like assigning consecutive array > bytes to a word: > word_var = byte_array[2] + byte_array[3] * 256; > > CCS compiles this in 7 instructions with the 18 instruction set - it > should be able to do this in 2 - so we really are quibbling > about small > amounts of code here - but for me, has raised all sorts of interesting > c possibiities. John's suggestion above compiles in 9 instructions, > while I haven't been able to get the advanced structure/union stuff to > compile at all. I've always used CCS's '#byte' directive, which is > non-standard c. I thought I would look for something simpler, but I > still have questions, if anyone is still hanging with me. > It seems just a structure would give the desired access: > > struct lo_hi {char lo; char hi;}; > struct lo_hi word_var; > > word_var.lo = byte_array[2]; > word_var.hi = byte_array[3]; > > This compiles in the desired 2 instructions; however, when I want to > just use the full variable, > > this works: word_var = 1000; > but this doesn't: if (word_var2 > word_var) > > for the compare, CCS insists on a structure element; I want it treated > as a single 16 bit variable. > Is this how how these *should* be treated?? > > Thanks again for any suggestions. > > -- > http://www.piclist.com hint: To leave the PICList > mailto:piclist-unsubscribe-request@mitvma.mit.edu > > > > -- http://www.piclist.com hint: To leave the PICList mailto:piclist-unsubscribe-request@mitvma.mit.edu