spin/assembler labels computed incorrectly?

Hi,
I encountered a problem with a program with mixed assembler and spin. I have a table in hub ram that I want to access from assembler. It seems that the starting address of the table is calculated incorrectly. To demonstrate the problem I have stripped down the code to a short example:
I encountered a problem with a program with mixed assembler and spin. I have a table in hub ram that I want to access from assembler. It seems that the starting address of the table is calculated incorrectly. To demonstrate the problem I have stripped down the code to a short example:
OBJ com: "FullDuplexSerial" VAR long para PUB main | t cognew (@startTest, @para) com.Start(31, 30, 0, baudRate) com.str (string("Result=")) com.hex (para, 8) repeat DAT ' Assembler ORG startTest mov adrTest,PAR mov tst,#$12 ' index to $02DE add tst,adrTable ' add hub address of table rdword tst,tst ' read from table wrlong tst,adrTest ' write result end jmp #end adrTest long 0 tst long 0 adrTable long @table DAT table word $0000,$0052,$00A3,$00F5,$0146,$0198,$01E9,$023B word $028D,$02DE,$0330,$0381,$03D3,$0424,$0476,$04C7To my understanding, the program should output "Result=02DE" but instead it does "Result=0052". It seems that @table differs by an offset of $10 from the actual address. Is there a workaround, e.g. can I trust that this number will always stay the same?
Comments
However, your cognew should be cognew(@startTest, @table)
The value passed in par will be the hub address of table.
Chip's VGA example will show the passing of a number of parameters in a table to pasm.
I just wanted to know if that's a bug or if it's intended to be that way. Or maybe there is a more clever way to pass the address...
You either pass it along with cognew and it will show up in par.
Or you let spin self/pre-modify your code (yes your code is in hubram first) before it's sends it away to the new cog.
adrTable := @table.
cognew (@startTest,0)
Seem my thread form 2008 where I asked the same question:
http://forums.parallax.com/showthread.php?102979-What-does-do-in-PASM
Upshot is that @ used in Spin code and @ used DAT declarations does NOT do the same thing.
You will find reasoning and advice on that thread.
I still think it is totally nuts:)
The address that you are passing to your asm cog is para not "table" The distance between para and table is not predictable. Cluso is correct, pass the pointer to table not para.
Jim
a) the spin compiler's view of addresses is very complicated and
b) it's dangerous to use "@" in PASM code.
I still disagree that the table adress is unknown at compile time. When I pass @something to cognew() it seems to be well known and always works. So the correct way to do it seems to be and to add the offset from parameter1 to tableAdr to PAR and to RDLONG tableAdr to get the hub address of table inside the PASM code. This uses a bit more memory than the direct way of using a constant hub address but I don't care as long as it works reliably.
Thaks to all for the explanations.
I think every Spin programmer encounters this issue with using the @ operator in a DAT section at some point. In a DAT section, the @ operator produces an address that is relative to the object's starting address. The top object always starts at address $10 because of the 16-byte header mentioned before. Other objects in a program will have different starting addresses. When the @ operator is used in a PUB or PRI section it will produce the absolute address of a location.
You're correct that the table address is known at compile time, but the Spin tool doesn't provide the capability to get the absolute address in a DAT section. Spin contains an @@ operatior that can be used in a PUB/PRI section at run time to convert an object offset into an absolute address. As Heater mentioned, BST provides an additional operator, @@@, that will produce the absolute address in a DAT section.
Dave