Hello,
I am working with CCS V4.0.0.16000, developing for a MSP430F2618 (X architecture) microcontroller in C and I have run into an issue with pointer math calculations generated by the compiler for what I would think should only need simple arithmetic calculations.
For this line of code:
pxLink->pxNextBlock = pxLink + pxLink->uiBlockLength;
The compiler generates the following dissassembly:
26 pxLink->pxNextBlock = pxLink + pxLink->uiBlockLength;0x0316a: 422F MOV.W #4,R150x0316c: 1800 515F 0004 ADDX.A 0x00004(SP),R150x03172: 4F2C MOV.W @R15,R120x03174: 430D CLR.W R130x03176: 403E 0006 MOV.W #0x0006,R140x0317a: 430F CLR.W R150x0317c: 13B0 331A CALLA #__mpyl_hw0x03180: 013E 0004 MOVA 0x0004(SP),R140x03184: 4D0F MOV.W R13,R150x03186: 0E4F RLAM.A #4,R150x03188: 0E4F RLAM.A #4,R150x0318a: 0E4F RLAM.A #4,R150x0318c: 0E4F RLAM.A #4,R150x0318e: 1800 DC4F BISX.A R12,R150x03192: 0FEE ADDA R15,R140x03194: 013F 0004 MOVA 0x0004(SP),R150x03198: 0E7F 0000 MOVA R14,0x0000(R15)
The assembly always produces the wrong results for the "pxLink + pxLink->uiBlockLength" part of the code which messes up everything else. Functionally the assembly multiplies the pxLink->uiBlockLength by the length of the pxLink struct. I don't understand why it would use the hardware multiplier under these circumstances at all though.
Just for some context, this code is coming out of a memory management routine that uses a linked list header in each block subdividing the heap. I have uploaded some code that exhibits this issue here. You can also take a look on pastebin: http://pastebin.com/m16b19f8a
I appreciate any help or insight into what might be causing this issue.
-Aaron
C math operations on pointers treat the pointers with the knowledge of what they are pointing to. If you wrote
pxLink += 1;
then the compiler would increment pxLink by 1 struct size so it will be pointing to the next struct. And this method should always work for accurately reaching the next struct in an array.
Adding whatever uiBlockLength represents will result in multiplying the space taken up by the struct (usually the size of the struct) by the addend uiBlockLength. It is possible on some devices and some struct configurations for an alignment hole to be left between adjacent structs; this means that sizeof(struct-type) might not be the same as the distance between adjacent structs.
The += 1 may be what you need to do for your case, but that is just making assumptions on my part about your application.
RandyP, your answer helped explain what the compiler was generating and I think I have developed a work around.
The pxLink pointers aren't referencing elements in an array, but rather elements in a linked list. Each list element is a header to a memory block of a variable size used to manage and segment the heap so when I increment the pointer it needs to be by the size of the structure + the size of its associated memory block. It looks like I can cast pxLink as a size_t and then add pxLink->uiBlockSize and then recast the result as a xBlockLink pointer. This eliminates the multiplication step and gives the correct address of the next block in memory.
Thanks again for your help.
The canonical way to do this sort of thing is to cast the pointer to a "char *" before the arithmetic. Using size_t will work in this case, but isn't strictly speaking portable. The cast to "char *" is portable.
Thanks for pointing that out. Either way the variable type will be determined by the compiler but at least "char *" makes it more explicit and readable.
ALL CONTENT AND MATERIALS ON THIS SITE ARE PROVIDED "AS IS". TI AND ITS RESPECTIVE SUPPLIERS MAKE NO REPRESENTATIONS ABOUT THE SUITABILITY OF THESE MATERIALS FOR ANY PURPOSE AND DISCLAIM ALL WARRANTIES AND CONDITIONS WITH REGARD TO THESE MATERIALS, INCLUDING BUT NOT LIMITED TO, ALL IMPLIED WARRANTIES AND CONDITIONS OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT OF ANY THIRD PARTY INTELLECTUAL PROPERTY RIGHT. NO LICENSE, EITHER EXPRESS OR IMPLIED, BY ESTOPPEL OR OTHERWISE, IS GRANTED BY TI. USE OF THE INFORMATION ON THIS SITE MAY REQUIRE A LICENSE FROM A THIRD PARTY, OR A LICENSE FROM TI.
Content on this site may contain or be subject to specific guidelines or limitations on use. All postings and use of the content on this site are subject to the Terms of Use of the site; third parties using this content agree to abide by any limitations or guidelines and to comply with the Terms of Use of this site. TI and its suppliers reserve the right to make corrections, deletions, modifications, enhancements, improvements and other changes to the content and materials, its products, programs and services at any time or to move or discontinue any content, products, programs, or services without notice.