Shop OBEX P1 Docs P2 Docs Learn Events
Pointer often are not so easy to understand! Whats going on? — Parallax Forums

Pointer often are not so easy to understand! Whats going on?

ErNaErNa Posts: 1,751
edited 2008-05-16 21:19 in Propeller 1
Never enhance a running software nono.gif

In DAT I create an array of 8 long elements:
TValue    long  0, 0, 0, 0, 0, 0, 0, 0 ' 8 values for 8 traces



Next I define another array of long values:
DAT ProzHPrz long  2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007



I output these values for test issues:
Put9Val (  ProzHPrz, ProzHPrz (1), ProzHPrz (2), ProzHPrz(3), ProzHPrz(4), ProzHPrz(5), ProzPrz(6), ProzHPrz(7), ProzHPrz(8))

and get, as expected:

    2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, xxx



As the array is only 8 longs, value ProzHPrz is arbitrary.


But that was not the reason to make this array, just to have some values. I'd like to have addresses:
DAT ProzGPrz long  @HPrzCmd, @TValue(0), @TValue(1), @TValue(2), @TValue(3) , @TValue(4), @TValue(5), ...


and get, if I output

Put9Val (  @HPrzCmd, @TValue(0), @TValue(1), @TValue(2), @TValue(3) , @TValue(4), @TValue(5), ...
                 340, 484, 488, 492, 496, 500, 504, 508, 512



but if I dump the array:
      Put9Val (   ProzHPrz,    ProzHPrz(1), ProzHPrz(2), ProzHPrz(3), ProzHPrz(4), ProzHPrz(5),  ProzHPrz(6), ProzHPrz(7), ProzHPrz(8))
     
the result is:
    324, 468, 468, 468, 468, ...



324 + offset (16) = 340, 468 + offset = 484, as expected. But then follows just 468, and I cannot see, what I did wrong.

So I did another test:
DAT ProzHPrz long  @HPrzCmd, @TWert(0), 2002, @TWert(2), 2004, @TWert(4), @TWert(5), @SumPhaA


and the dump showed:
       Put9Val (   ProzHPrz,    ProzHPrz(1), ProzHPrz(2), ProzHPrz(3), ProzHPrz(4), ProzHPrz(5),  ProzHPrz(6), ProzHPrz(7), ProzHPrz(8))

   324, 2002, 468, 468, 2004, 468, 468, ...



and again: another surprise!!: 2002 came as the second element, 2004 as the fifth.

Now my brain is squirreld and I have to wait. Maybe someone else know, where my fault is?

Comments

  • stevenmess2004stevenmess2004 Posts: 1,102
    edited 2008-05-15 10:29
    Okay, I assume that a lot of your parenthesis are actually square brackets. When defining data in the DAT section the number in the square brackets creates an array so you are putting in the offset to PropHPrz, then the offset to ProzHPrz, then 2 times then 3 times and you get the idea. In your test with the 2002 I would assume that the compiler is not putting in any value for @TWert(0) because the 0 means that there are no elements in the array.

    Hope that helps.
  • ErNaErNa Posts: 1,751
    edited 2008-05-15 10:36
    as a work around, I just converted the addresses manually by +adding the offset according the array-index. But beautiful is different!

    Dat ProzHPrz long @HPrzCmd, @TWert, @TWert+4, @TWert+8, @TWert+12, @TWert+16, @TWert+20, @SumPhaA
  • ErNaErNa Posts: 1,751
    edited 2008-05-15 10:54
    @steven: your assumption was right, I just don't know, how to make the brackets transparent to the formatter. As I know, I declare array in the var section, but then they are not initialised. In the DAT section I just create a label, and than follow as much (long) data as I need.

    What I do is:
    Create a process control block, that passes pointers to a cognew. Actually I just pass the pointer to the control block and then copy the addresse from the control block. That works fine for pointers to variables. But now my variables are elements of an array and I just want to pass a pointer to this element by getting the address of the n-th element: @Arrayname. But this array is not defined as an array, but is just a label in the data section.

    So: can I define an array in the data section?
  • stevenmess2004stevenmess2004 Posts: 1,102
    edited 2008-05-15 12:18
    You can use this link to format your code and it will fix the brackets so they don't mess anything up www.phipi.com/format/

    Anything in the VAR section is initialised to 0. You can actually treat any variable as an array by using the brackets after it in your code.

    I can't find the reference for the rest of this but I'm pretty sure this is how it works by just testing it with the prop tool and checking the memory used.
    When you declare a variable in the DAT section with square brackets like this
    DAT
    var1 long 3[noparse][[/noparse] 5]
    


    The value 3 will be placed in 5 times. So you would end up with the same effect as this
    DAT
    var long 3,3,3,3,3
    


    And if you make the 5 a 0 then the value isn't included at all.

    If you want a pointer to one of the elements in array do this
    pointer:=@variable+index*(1 for byte, 2 for word or 4 for long)
    



    Even better than the multiply is just a shift left of 1 or 2 because it will be quicker. You should also check out the bit in the prop manual about using the "@" operator in DAT sections.
  • ErNaErNa Posts: 1,751
    edited 2008-05-15 12:58
    Never do an unnecessary preview! When I use the code-formatter and then to a preview, the code is converted and I can start over. Nice lesson!
    So I found the solution adding index*Bytes, but still i can not see, why the 2002 is shifted by one place to the left ? Maybe, its a problem with the compiler!
    Anyway, my program does again, what it did before, but uses much less code!
  • Harrison.Harrison. Posts: 484
    edited 2008-05-15 14:18
    You might want to take a look at the @@ operator on page 279 of the Propeller Manual.

    The @ operator in a DAT block does not do the same thing as if it was used in normal SPIN code. The @ operator in a DAT block only returns the variable's relative address. You have to use the @@ operator on this relative address to get the absolute hub address (@@MyDatVar = variable's relative address + object's base address = variable's absolute address).
  • GatunoGatuno Posts: 23
    edited 2008-05-16 21:19
    Harrison:

    This is my first post to the forum... turn.gif so I think is a sort of newby question.

    I tried as you show, and it worked for VAR arrays, but it didn't work for DAT arrays.
    I made the following example, trying to use the
    long[noparse][[/noparse]ptr2_base+4*i]
    

    sintax (also tried
    long[noparse][[/noparse]ptr2_base][i][/i]
    

    ,
    long[noparse][[/noparse]ptr2_base][noparse][[/noparse]4*i]
    

    , etc).


    [b]CON[/b]                        
      [b]_clkmode[/b] = [b]xtal[/b]1 + [b]pll[/b]16x
      [b]_xinfreq[/b] = 5_000_000
    [b]obj[/b]
      term : "VGA_Text"
      fstr : "FloatString-[b]Float[/b]32"    'OBEX FloatString object modified to use Float32
    [b]CON[/b]
      leng = 4  
    [b]VAR[/b]
      [b]long[/b] array1[noparse][[/noparse]leng]            'array in VAR section
      [b]long[/b] ptr1                     'array1 pointer (defined as long)  
      [b]long[/b] ptr2                     'array2 pointer (defined as long)
      [b]long[/b] ptr1_base                'base address of array1
      [b]long[/b] ptr2_base                'base address of array2
    
    [b]pub[/b] Main | a, b, c, d, temp, i
      term.start(16)                'start vga
      math.start
    
      {loop to show values of [b]VAR[/b] array} 
      term.[b]str[/b]([b]string[/b]("Array1= ",13))
      ptr1_base := @array1                                 'address using @ operator
      [b]repeat[/b] i [b]from[/b] 0 to (leng-1)
        term.dec(i)
        term.[b]str[/b]([b]string[/b](":"))
        ptr1 := @array1[i]                                 'get the address of array1
        [b]long[/b][noparse][[/noparse]ptr1] := math.FFloat(i+1)                     'using ptr1 to assign a value to array1[i]
        'show value, calling it directly: OK
        term.[b]str[/b](fstr.FloatToString(array1[i]))            
        term.[b]str[/b]([b]string[/b]("->"))          
        'accessing by pointer to the base: OK
        term.[b]str[/b](fstr.FloatToString([b]long[/b][noparse][[/noparse]ptr1_base+4*i]))  'multiply by 4 for long variables
        term.[b]str[/b]([b]string[/b]("->"))              
        'accessing by updated pointer: OK
        term.[b]str[/b](fstr.FloatToString([b]long[/b][noparse][[/noparse]ptr1]))
        term.[b]str[/b]([b]string[/b](" ",13))
      term.[b]str[/b]([b]string[/b](13))
      
      {loop to show values of [b]DAT[/b] array}
      term.[b]str[/b]([b]string[/b]("Array2= ",13))
      ptr2_base := @@array2                                'address using @@ operator fot DAT section
      [b]repeat[/b] i [b]from[/b] 0 to (leng-1)
        term.dec(i)
        term.[b]str[/b]([b]string[/b](":"))
        ptr2 := @array2[i]
        'show value, calling it directly: OK
        term.[b]str[/b](fstr.FloatToString(array2[i]))
        term.[b]str[/b]([b]string[/b]("->"))              
        'accessing by pointer to the base: WRONG!
        [color=#FFA500]term.[b]str[/b](fstr.FloatToString([b]long[/b][noparse][[/noparse]ptr2p+4*i]))      'tried also: long[noparse][[/noparse]ptr2p][i] [/color]
        term.[b]str[/b]([b]string[/b]("->"))     
        'accessing by updated pointer: OK         
        term.[b]str[/b](fstr.FloatToString([b]long[/b][noparse][[/noparse]ptr2]))
        term.[b]str[/b]([b]string[/b](" ",13))
      term.[b]str[/b]([b]string[/b](13))
      
    [b]DAT[/b]
      array2 [b]long[/b] 1.5, 2.5, 3.5, 4.5                'array of DAT Section
    [/i][/i][/i][/i][/i][/i]
    



    I get something like:
    [noparse][[/noparse]code]
    Array1=
    0:1->1->1
    1:2->2->2
    2:3->3->3
    3:4->4->4
    Array2=
    0:1.5->3.820601e-37->1.5
    1:2.5->2.204103e-39->2.5
    2:3.5->2.939498e-39->3.5
    3:4.5->6.019468e-34->4.5
    [noparse][[/noparse]code]

    How can I access the DAT values using base address?

    Antonio.
Sign In or Register to comment.