Shop OBEX P1 Docs P2 Docs Learn Events
spin/assembler labels computed incorrectly? — Parallax Forums

spin/assembler labels computed incorrectly?

ManAtWorkManAtWork Posts: 2,183
edited 2011-09-20 10:04 in Propeller 1
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:
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,$04C7
To 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

  • Cluso99Cluso99 Posts: 18,069
    edited 2011-09-20 04:11
    Firstly, the offset of $10 is because the first 16 longs in hub are used by spin. It has always been that way.

    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.
  • ManAtWorkManAtWork Posts: 2,183
    edited 2011-09-20 05:39
    Errr, yes, spin uses the first 16 bytes. So what. Spin passes the correct adress (with $10 added) when I use @table in the cognew call. The question is, why doesn't it also add $10 when I use @table directly in a DAT section? And yes, I know how to pass parameters to PASM and I use it frequently. I just wanted to "optimize" my parameter table and omit parameters that are constant anyway. But if the direct way doesn't work without pitfalls, of course I can add a constant parameter to my list (that is a bit longer in reality than in the example above).

    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...
  • tonyp12tonyp12 Posts: 1,951
    edited 2011-09-20 05:52
    You can not include the address at time of compile.
    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)
  • Heater.Heater. Posts: 21,230
    edited 2011-09-20 05:55
    ManAtWork,

    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:)
  • Heater.Heater. Posts: 21,230
    edited 2011-09-20 05:57
    P.S. If you use the BST tool instead of the Parallax tool then you can use @@@ to get the right thing.
  • RS_JimRS_Jim Posts: 1,773
    edited 2011-09-20 06:00
    ManAtWork,
    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
  • ManAtWorkManAtWork Posts: 2,183
    edited 2011-09-20 06:38
    Ok, I don't understand all of Heater's thread. What I do understand is that
    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
    VAR
      long  parameter1
      long  parameter2
      long ...
      long  tableAdr
    
    PUB main
      ...
      tableAdr:= @table
      cognew (@startTest, @parameter1)
    
    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.
  • Dave HeinDave Hein Posts: 6,347
    edited 2011-09-20 08:25
    ManAtWork,

    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
  • ManAtWorkManAtWork Posts: 2,183
    edited 2011-09-20 10:04
    Dave, very good explanation! This should be printed somewhere in the propeller manual, really.
Sign In or Register to comment.