Shop OBEX P1 Docs P2 Docs Learn Events
@, @@, and sub-objects: What's the correct way to pass hub var addresses in Sp — Parallax Forums

@, @@, and sub-objects: What's the correct way to pass hub var addresses in Sp

Dennis FerronDennis Ferron Posts: 480
edited 2008-10-20 18:11 in Propeller 1
I'm a little confused about the proper use of @ and @@, and how to effectively get the address of a hub variable in Spin. In my code I've been using @ exclusively, but I recently ran into a problem when I tried to take the @ address of a variable in a sub-object, and use it within that sub-object, while the sub-object is called by a larger program. From reading the Propeller manual, I came under the impression that the problem is that @ is a relative address and that @@ gives absolute addresses by adding the base address of the object to the relative address at runtime. My guess is that when my code using @ addresses is the topmost object, then the base address is 0, so there is no difference between absolute and relative addresses, but when it is a sub-object, that's no longer true and my code fails. However, when I tried using @@, I still had a problem! The only way I could get the code to work was to pull the var I was trying to access out of the sub-object, and into the topmost object, from whence I could grab the @-address of the var and pass it down to the sub-object as a function argument, which worked.

So, I'm a little confused: is @@ not for what I think it's for? I get that it must be runtime calculated because if the same object is included multiple times, then there is 1 copy of the code but many copies of the vars, so you have to have the base address for which copy of the vars you mean. But, it looks like that happens "automatically" so I should be able to say "@@var" and get the address - right?

Edit: Ah! Answered my own question - the construction I needed was "@@(@var)"! When you read the section in the manual about @@, you have to read it VERY carefully. I assumed @@ adds the object base to the ADDRESS of var, actually it adds object base to the VALUE of var. We should add this to Propeller Tricks and Traps!

You can also write this "@@@var", which is nice because you can sort of think of it as "the triple @ operator" that does a third thing besides @ and @@, but really it's just the combination of @@ and @.



Edit 2: Uh, maybe not. Some more tests I did lead me to believe that neither @@(0) nor @@@ do what I think they do either! Can anyone shed light on this? (For instance, @@(0) in a top level object is 10, not 0 as I assumed.)

Post Edited (Dennis Ferron) : 10/18/2008 7:45:26 PM GMT

Comments

  • mparkmpark Posts: 1,305
    edited 2008-10-19 00:51
    @symbol in a PUB or PRI will give you the absolute address of symbol (unless it's inside CONSTANT()).
    @symbol in a DAT section will give you the relative address.

    Is that not what you're seeing?

    What the heck does this mean?
    dennis said...
    The only way I could get the code to work was to pull the var I was trying to access out of the sub-object, and into the topmost object, from whence I could grab the @-address of the var and pass it down to the sub-object as a function argument, which worked.
  • Dennis FerronDennis Ferron Posts: 480
    edited 2008-10-19 14:28
    Thanks mpark.

    What I meant by the section you quoted is that this crashes with a memory corruption (seems to have written to the wrong address):

    ' TopObject.spin
    OBJ
      sub : "subobject"
    
    PUB
      sub.DoStuff
    
    ' SubObject.spin
    VAR
      long buf[noparse][[/noparse]100]
    
    PUB DoStuff
      ' start assembly routine with @buf
    
    DAT
      ' Assembly routine writes to buffer
    
    



    But changing the code to this made it work as expected:

    ' TopObject.spin
    VAR newbuf
    
    OBJ
      sub : "subobject"
    
    PUB
      sub.DoStuff(@newbuf)
    
    ' SubObject.spin
    
    PUB DoStuff(ptr)
      ' start assembly routine with ptr
    
    DAT
      ' Assembly routine writes to buffer
    
    



    Furthermore, this worked too, but I think it shouldn't have, so now I'm really confused:

    ' TopObject.spin
    OBJ
      sub : "subobject"
    
    PUB
      sub.DoStuff
    
    ' SubObject.spin
    VAR
      long buf[noparse][[/noparse]100]
    
    PUB DoStuff
      ' start assembly routine with @@@buf
    
    DAT
      ' Assembly routine writes to buffer
    
    
  • hippyhippy Posts: 1,981
    edited 2008-10-19 14:55
    ' start assembly routine with @@@buf

    I guess this is going to become an increasingly common problem; second guessing which tool is being used to compile the code.

    It's always been my experience that for PropTool @var will return the absolute hub address of where the variable is in memory regardless of being in top level or sub-object when using Spin, but an @ does behave differently when used in a DAT section.
  • mparkmpark Posts: 1,305
    edited 2008-10-19 16:22
    Dennis, that doesn't make any sense. I think that there's a bug in your assembly routine, and it works with different pointers only by chance.

    Hippy, I'd not realized that @@@ is actually valid syntax in Proptool, being @@ followed by @. Of course it doesn't make a lot of sense to do that, but your point about confusion with the non-standard @@@ operator is a good one. We really should come up with a better name for @@@.
  • hippyhippy Posts: 1,981
    edited 2008-10-19 16:59
    I didn't think @@@ was valid with PropTool which is where I went on to assume it wasn't PropTool being used !

    I did go and check when using @@@ was suggested but, with hindsight, only tested it within DAT sections as that was the problem we were seeking to solve there :-o

    I think the proposed @@@ for DAT may do the same as Spin does so it would be acceptable to keep with the @@@ for DAT / PASM.

    I'll have to admit I've never used @@ nor @@@
  • heaterheater Posts: 3,370
    edited 2008-10-19 19:07
    Isn't this getting out of hand?

    I suggested they use ¤ instead of @@@ but, no, they wouldn't listen [noparse]:)[/noparse]

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    For me, the past is not over yet.
  • Dennis FerronDennis Ferron Posts: 480
    edited 2008-10-19 23:34
    Thanks mpark, you're right, it doesn't make any sense. I'll look for a bug in my assembly routine. [noparse]:)[/noparse]
  • Paul BakerPaul Baker Posts: 6,351
    edited 2008-10-20 18:11
    Hi Dennis (et all),
    ·There's some confusion going on here that I think I can clear up. When an @ is encountered by the compiler, it does not compute the address at that point in time, because the linking stage hasn't occured yet, so the compiler only knows the offset address and the object to which it belongs (but not the address that object will be placed in memory since linking hasn't occured).

    What happens with the @ depends on where it's located. If it's in a method (ie in a place where the interpreter will be fetching executable code) a token + offset is generated and placed in the code. This token has the meaning of "figure out the base address of this object and add the following offset", so that at runtime this address is generated. When this address is computed, it is absolute and is usable by any object to obtain access to the location.

    The use of @@ comes into play when you are doing double indirection, the interpretor needs to know that this is occuring. Say for instance you have a bunch of variable length strings defined, and you want to create a handy index table into them:

    DAT
      str1 BYTE "This is a string",0
      str2 BYTE "This is another string",0
      str3 BYTE "And this is yet another string",0
     
      Strings LONG @str1, @str2, @str3
    

    When storing the addresses of str1-str3, the compiler cannot use the token + offset trick as described above because it is stored in a DAT section. First off there isn't room, minimum 1 byte token + 4 byte offset > a LONG. And it's also data, the compiler wouldn't know that it has to interpret data (after all it's data not code). So what it does is store just the offset from the base of the object in Strings. The @@ operator indicates to the interpretor that only the offset is stored, and an extra step of adding the object's base must be performed.

    So when you go to use Strings, @@Strings takes the offest stored there and adds the base of the object so that an absolute address is generated.

    Don't feel bad about this not being immediately clear, I've had to ask Jeff to explain this to me more than once.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Paul Baker
    Propeller Applications Engineer

    Parallax, Inc.

    Post Edited (Paul Baker (Parallax)) : 10/20/2008 6:16:30 PM GMT
Sign In or Register to comment.