Well, this problem is more 'general C' than msp430 I think... Agree, this is not documented (yet), however:
Well, pointers usually have to same size as 'int'. In case of msp430 this is 2 bytes. Usually, compilers operate with pointers as with 'unsigned int' variable. (at least in case of mspgcc unless you pass -mint8). However, when you 'diff' two pointers gcc considers this to be 'signed int' (still 2 bytes). Then divides this 'diff' by type size in order 'diff' to be equial the number of 'type' elements between two pointers. So, the thing you see in your example: (0x7000 - 0x1000) >> 2 == 0x1800; 2 bytes. Extend to 4 byte var gives 0x00001800 (0xf000-0x1000) >> 2 == 0xe000>>2 == 0xf800; 2 bytes. Extend to 4 bytes gives 0xfffff800 In case you're play with i368, the last numbers are: (0x0000f0000 - 0x000010000) >>2 == 0x0000e000 >> 2 == 0x00003800 To prove this, try 0x10000000 and 0xf0000000 on i368 and check. Hope this helps. ~d On Tuesday 31 December 2002 05:17, Walt Spicker wrote: > David, > > Your point is well taken. I guess this could be considered > inconsequential given the memory layout of the MSP430s. I stumbled > across it in an application that transmits large chunks of data stored > in an external memory. I don't have the external memory available at > present, so I was just dumping the contents of flash in order to have > something to send. I then noticed that my pointers did not have the > expected values when I started walking through memory. So I contrived > a simple example to demonstrate the problem, and here we are. > > I don't really think that I need to see this get fixed, but it does seem > to expose a weakness in the generated code that may have more important > side affects elsewhere. > > Thanks again, > > Walt > > David Dyck wrote: > >Your initial test program should get people thinking, > >but perhaps it is now time to go back to the mailing > >list with the assembly language pointer divide by 4. > > > >maybe post a simplified program, although the list > >may argue that the result is undefined since at this > >time you can have an array of longs that are this big > >in the msp430, but a "long" checksum routine with > >60k of flash may be a contrived example. > > > >perhaps even a const long array in the code section > >that just happens to cross the 32k byte boundary > >would also experience this size failure. > > > >On Mon, 30 Dec 2002 at 17:14 -0500, walt spicker <wspic...@salientsystems.c...: > >>From: walt spicker <wspic...@salientsystems.com> > >>To: David Dyck <david.d...@fluke.com> > >>Date: Mon, 30 Dec 2002 17:14:09 -0500 > >>Subject: Re: [Mspgcc-users] Pointer Arithmetic Error > >> > >>David, > >> > >>As you suggest, I took a peek at the assembly, and it appears to me that > >>there is a problem with the instruction used to do the divide by 4. > >>Indeed the compiler is using "rra" to divide the pointer value "0xf000" > >>by 4. with the resulting value being "0xf800", probably not what was > >>intended. > >> > >>Is there a mechanism to report a "bug", or do we just hope this bubbles > >>up and and gets the attention of somone with the ability to fix it? > >> > >>Thanks for your help, > >> > >>Walt > >> > >>David Dyck wrote: > >> > >> > >>Walt, > >> > >> perhaps it is time to look at the assembly code generated, perhaps > >> > >>the msp code is treating the number as signed. > >> > >> > >> > >>Another thing to try would be to check out the same code with > >> > >>pointers to characters instead of longs, so the compiler wouldn't > >> > >>have to do divisions by 4 (maybe right shift). > >> > >> > >> > >>Also, what optimizations are the compiler generating - perhaps > >> > >>it can pre-compute some of the math - so there are a couple > >>opportunities > >> > >>for errors here... > >> > >> > >> > >> > >> > >> > >> > >> > >> > >>On Mon, 30 Dec 2002 at 15:27 -0500, walt spicker < > >>wspic...@salientsystems.c...: <mailto:wspic...@salientsystems.c...:> > >> > >> > >> > >> > >> > >>Thanks for your reply. I sort of see what you are getting at, but that > >> > >>does not appear to be the problem. > >> > >> > >> > >>Here is a modified test, first on the 430: > >> > >> > >> > >> unsigned long *p1=(void*)0x1000LU, *p2=(void*)0x7000LU, > >>*p3=(void*)0xf000LU; > >> > >> unsigned long p2p1 = p2-p1; > >> > >> unsigned long p3p1 = p3-p1; > >> > >> static char buf[80]; > >> > >> snprintf (buf, sizeof(buf), "%8.8lx %8.8lx %p %p %p %i", > >> > >> p2p1, p3p1, p1, p2, p3, sizeof(p3)); > >> > >> PrintLine (buf); > >> > >> > >> > >> > >> > >>Output from 430 test: > >> > >> > >> > >>00001800 fffff800 0x1000 0x7000 0xf000 2 > >> > >> > >> > >> > >> > >>Here is the modified test, on the 386/Linux > >> > >> > >> > >>main(){ > >> > >> unsigned long *p1=(void*)0x1000LU, *p2=(void*)0x7000LU, > >>*p3=(void*)0xf000LU; > >> > >> unsigned long p2p1 = p2-p1; > >> > >> unsigned long p3p1 = p3-p1; > >> > >> > >> > >> printf ("%8.8lx %8.8lx %p %p %p %i \n", p2p1, p3p1, p1, p2, p3, > >>sizeof(p3)); > >> > >> > >> > >>} > >> > >> > >> > >>Output 386/Linux > >> > >> > >> > >>00001800 00003800 0x1000 0x7000 0xf000 4 > >> > >> > >> > >> > >> > >>OK, so the size of the pointer on the 430 is two bytes vs. 4 bytes on > >>the I386. I do not see what role that plays here. > >> > >> > >> > >>My expectation is that the difference between two pointers of the same > >>type will yield the number of those items that would fit in memory > >>between the two addresses. This seems to be true on the 430 only when > >>the MSB of the pointers is zero. > >> > >> > >> > >>Please let me know if you still think that I'm missing something here. -- /******************************************************************** ("`-''-/").___..--''"`-._ (\ Dimmy the Wild UA1ACZ `6_ 6 ) `-. ( ).`-.__.`) Enterprise Information Sys (_Y_.)' ._ ) `._ `. ``-..-' Nevsky prospekt, 20 / 44 _..`--'_..-_/ /--'_.' ,' Saint Petersburg, Russia (il),-'' (li),' ((!.-' +7 (812) 3468202, 5585314 ********************************************************************/