PDA

View Full Version : Pointer often are not so easy to understand! Whats going on?



ErNa
05-15-2008, 05:01 PM
Never enhance a running software http://forums.parallax.com/images/smilies/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?

stevenmess2004
05-15-2008, 05:29 PM
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.

ErNa
05-15-2008, 05:36 PM
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

ErNa
05-15-2008, 05:54 PM
@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?

stevenmess2004
05-15-2008, 07:18 PM
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/ (http://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[ 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.

ErNa
05-15-2008, 07:58 PM
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.
05-15-2008, 09:18 PM
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).

Gatuno
05-17-2008, 04:19 AM
Harrison:

This is my first post to the forum... http://forums.parallax.com/images/smilies/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[ptr2_base+4*i]

sintax (also tried

long[ptr2_base]

,

long[ptr2_base][4*i]

, etc).





CON
_clkmode = xtal1 + pll16x
_xinfreq = 5_000_000
obj
term : "VGA_Text"
fstr : "FloatString-Float32" 'OBEX FloatString object modified to use Float32
CON
leng = 4
VAR
long array1[leng] 'array in VAR section
long ptr1 'array1 pointer (defined as long)
long ptr2 'array2 pointer (defined as long)
long ptr1_base 'base address of array1
long ptr2_base 'base address of array2

pub Main | a, b, c, d, temp, i
term.start(16) 'start vga
math.start

{loop to show values of VAR array}
term.str(string("Array1= ",13))
ptr1_base := @array1 'address using @ operator
repeat i from 0 to (leng-1)
term.dec(i)
term.str(string(":"))
ptr1 := @array1 'get the address of array1
long[ptr1] := math.FFloat(i+1) 'using ptr1 to assign a value to array1
'show value, calling it directly: OK
term.str(fstr.FloatToString(array1))
term.str(string("->"))
'accessing by pointer to the base: OK
term.str(fstr.FloatToString(long[ptr1_base+4*i])) 'multiply by 4 for long variables
term.str(string("->"))
'accessing by updated pointer: OK
term.str(fstr.FloatToString(long[ptr1]))
term.str(string(" ",13))
term.str(string(13))

{loop to show values of DAT array}
term.str(string("Array2= ",13))
ptr2_base := @@array2 'address using @@ operator fot DAT section
repeat i from 0 to (leng-1)
term.dec(i)
term.str(string(":"))
ptr2 := @array2
'show value, calling it directly: OK
term.str(fstr.FloatToString(array2))
term.str(string("->"))
'accessing by pointer to the base: WRONG!
term.str(fstr.FloatToString(long[ptr2p+4*i])) 'tried also: long[ptr2p]
term.str(string("->"))
'accessing by updated pointer: OK
term.str(fstr.FloatToString(long[ptr2]))
term.str(string(" ",13))
term.str(string(13))

DAT
array2 long 1.5, 2.5, 3.5, 4.5 'array of DAT Section




I get something like:
[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
[code]

How can I access the DAT values using base address?

Antonio.