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
 ********************************************************************/


Reply via email to