Shop OBEX P1 Docs P2 Docs Learn Events
Difference between "@" and "#" in PASM? — Parallax Forums

Difference between "@" and "#" in PASM?

agsags Posts: 386
edited 2013-04-19 11:25 in Propeller 1
Looking at some code examples, I see patterns like:
label mov dest, #src
src res 1
dest res 1

which makes sense: take the the location (address) of the register represented by the symbol "src" and use it as a immediate value (as compared to the contents of the register represented by the symbol "src") and move that to the register (address) represented by the symbol "dest". The end result is the register represented by the symbol "dest" will contain the location (address) of the register represented by the symbol "src".

However, I've also seen (and used) a construct like this:
label mov dest, @src
src res 1
dest res 1

This says: take the address of the register represented by "src" and move it's contents (since there is no "#" specifying immediate mode for the move instruction) to the register (location) represented by the symbol "dest".

However, I"ve used the second style in code that works (with problems) like I would expect the first style (immediate mode) and I can't belive that it would ever work if I was understanding what's going on here - but it does (apparently). If "#" causes the "i" bit of the instruction/word to be set meaning that the src value is not a register address but an immediate numerical value, I can't reconcile that with the meaning of the "@" modifyer. In PASM, isn't the "@" always implied?l Meaning, the value inserted into the the src or dest fields of the instruction is always the location represented by the symbol provided as an operand(s) to the instruction, and for the src location, using "#" designates that it is a literal, immediate value?

Thanks.
«1

Comments

  • kuronekokuroneko Posts: 3,623
    edited 2011-07-26 23:17
    ags wrote: »
    label mov dest, @src
    src res 1
    dest res 1
    

    This says: take the address of the register represented by "src" and move it's contents (since there is no "#" specifying immediate mode for the move instruction) to the register (location) represented by the symbol "dest".
    @src normally represents the hub address of the label src relative to the object it's defined in (if used in PASM). So with an otherwise empty DAT section the mov will reference $000C for its source slot. Whatever that means in the end ... Given res involvement this makes its use rather questionable.

    Certainly not wrong but rather confusing, never used it myself in PASM context.
  • agsags Posts: 386
    edited 2011-07-26 23:35
    Two questions, then:

    1) how did you arrive at $0C as the address for the src register? If it is the second line of the DAT section, why woudln't that be $01 (given that is PASM, cog memory is addressed in long word (32 bit) chunks? Each instruction (instr, zrci, cond, dest, src) requires just 32 bits.
    2) the burning question is still why the assembler would recognize the "@src" as an immediate value, as compared to the address of a register in which the value to be used is contained?
  • kuronekokuroneko Posts: 3,623
    edited 2011-07-26 23:47
    ags wrote: »
    1) how did you arrive at $0C as the address for the src register? If it is the second line of the DAT section, why woudln't that be $01 (given that is PASM, cog memory is addressed in long word (32 bit) chunks? Each instruction (instr, zrci, cond, dest, src) requires just 32 bits.
    This is based on a minimal SPIN file:
    PUB null
    DAT
    label           mov     dest, @src
    src             res     1
    dest            res     1
    
    Compile it and place the cursor over the src label (PropTool). It will show you the object offset and the cog location. Since you use @ you'll get the relative hub offset (which is basically the long after the mov instruction in the current object in hub memory). Had you used mov dest, src you'd gotten 1 as the source address.
    2) the burning question is still why the assembler would recognize the "@src" as an immediate value, as compared to the address of a register in which the value to be used is contained?
    It doesn't, for that you'd want #@src :) Anyway, @ only resolves hub (related) addresses so you'll get one. Incidentally, can you point at the code you say is using it? Would be interesting to see as to why it's done like this.
  • Dave HeinDave Hein Posts: 6,347
    edited 2011-07-27 06:45
    A label has two values. One value is its address in cog memory, which is accessed by just using the label's name. The other value is its address relative to the start of the object, which is accessed by putting a "@" character before the name. The cog address increments by 1 for each cog location. The relative object address increments by 1 for each byte, which would be an increment of 4 for each long.

    In the example above, "label" has a value of 0, "src" is 1 and "dest" is 2. If the object's method table uses 8 bytes then the values of "@label", "@src" and "@dest" will be $8, $C and $10 respectively. In general, the relative object address is not useful in PASM unless you know the object's start address.

    The top object always starts at $10 (unless it's manually moved to another location). I have done something like "mov addr,#@src+$10" to get the absolute hub address of "src" into the cog variable "addr". Note that this only works if "src" is located in the top object and its absolute address is less than 512. For larger addresses I do something like this:
        mov addr,src_addr
        ...
    src_addr long @src+$10
    
    Once again, this only works if "src" is in the top object and the code hasn't been relocated to another location.

    Dave
  • K2K2 Posts: 693
    edited 2011-07-27 14:48
    Dave Hein wrote: »
    A label has two values. One value is its address in cog memory, which is accessed by just using the label's name.

    Surely you don't mean this. The label name by itself refers to the value of the long located there, not the address of it.
  • Dave HeinDave Hein Posts: 6,347
    edited 2011-07-27 15:45
    Yes, I did mean this. And don't call me Shirley. :)

    I am referring to the values associated with the label, and not the value at the location that the label refers to. The following statements use the values of the label:
            mov reg, label         ' Get contents at the cog location pointed to by label
            mov reg, #label        ' Get the cog location for label
            mov reg, #@label       ' Get the object byte offset for label
            mov reg, obj_offset    ' Get the cog location for label
            mov reg, cog_address   ' Get the object byte offset for label
            ....
    label long 123
    obj_offset long @label
    cog_address long label
    
    The value stored at the location addressed by "label" is 123, but the value of "label" when used as a constant is its hub address, and the value of "@label" is its byte offset within the object. The symbols "label" and "@label" can be use like any other constants, such as in an expression like "label*4 + 3".
  • kuronekokuroneko Posts: 3,623
    edited 2011-07-27 16:38
    Dave Hein wrote: »
    In the example above, "label" has a value of 0, "src" is 1 and "dest" is 2. If the object's method table uses 8 bytes then the values of "@label", "@src" and "@dest" will be $8, $C and $10 respectively. In general, the relative object address is not useful in PASM unless you know the object's start address.
    Both src and dest are marked as res so @ resolves to $8, $C and $C.
  • K2K2 Posts: 693
    edited 2011-07-27 16:45
    mov reg, label         ' Get contents at the cog location pointed to by label
    

    Shirley Dave, I'm slow today. How is this different than what I said?
  • Dave HeinDave Hein Posts: 6,347
    edited 2011-07-27 19:20
    @K2, that line demonstrates what you said. The other lines demonstrate what I said.

    @kuroneko, I hadn't noticed that they were defined with res statements. Thanks for pointing that out.
  • agsags Posts: 386
    edited 2011-07-28 00:30
    For my question, I think the important aspect to focus on is the difference between this:
    (1)
    mov someDestLabel, @someSrcLabel

    and this:
    (2)
    mov someDestLabel, someSrcLabel

    and this:
    (3)
    mov someDestLabel, #someSrcLabel

    If I'm understanding the comments here, the difference between the 1st and 2nd examples above is that the first will resolve to the offset, in bytes, of the "someSrcLabel" register, and move the contents of that location into the "someDestLabel" register location. The second will do the same thing, but the offset to "someSrcLabel" will be in terms of long words (1/4 the value in the 1st case) and move the contents of that location into the "someDestLabel" register location. The 3rd example (which is what I meant to do) will directly load the location (address) of the "someSrcLabel" register, in long words, into the "someDestLabel" register location.

    In other words, the difference between the 1st and 2nd examples is loading the value from one location (offset) in COG RAM vs. a location/4. The 3rd example doesn't deal with contents of a register location, but the address/offset/location (in long words - limited to 0-511) directly (immediate mode).

    If this is correct, it's a miracle that my code worked at all. I'm including it to help the discussion, but it will probably have little value as a snippet. The full code listing is too long. My intention was to define an "array" of long word values in COG RAM, and then iterate through each long (to get a single bit value). I hard-coded a limit of 32 longs as the array to be used. It seems that what was actually happening was that by using "@" instead of "#" (to set the immediate mode instruction flag), the value stored in the location I intended to use "cogArray" (value = 32) was multiplied by 4 (byte offset, not long word location) which is 128 and is beyond the extent of the DAT block that I defined. So, I ended up using different registers than expected, but they were (luckily) stil able to be pressed into service without a problem here. (When storing the values I was loading from HUB RAM, I used the same technique (mov someLocation, @cogArray) to load the value from HUB RAM, so if I did it incorrectly both times, then it could work (accessing the same location) but if any other part of the code used those locations then things would go very bad very quickly.

    Thanks for the help.
            mov cogAddress, @cogArray
            ' loop over all series words, bounded by #NUM_CHANNELS
    :word_iter
            movd :target, cogAddress
            nop 
    :target and   cogArray, current_bit_mask       wc, nr
            muxc  parallel_word, temp_bit_mask
            add   cogAddress, #%1                     ' Only increment by one because cog only addresses LONG words
            shl   temp_bit_mask, #1
            add   channelIndex, #1
            xor   channelIndex, #NUM_CHANNELS       wz, nr
      if_nz jmp   #:word_iter
     
    cogArray                res     32
    
  • kuronekokuroneko Posts: 3,623
    edited 2011-07-28 04:32
    ags wrote: »
    If I'm understanding the comments here, the 1st and 2nd examples is that the first will resolve to the offset, in bytes, of the "someSrcLabel" register, and move the contents of that location into the "someDestLabel" register location. The second will do the same thing, but the offset to "someSrcLabel" will be in terms of long words (1/4 the value in the 1st case) and move the contents of that location into the "someDestLabel" register location.
    Careful here! @ gives you a hub address and since this is used in a DAT section you get compile time behaviour which means an address which is relative to the start of the object (using it in SPIN will give you run-time behaviour, i.e. the real (absolute) address in hub). Not using @ gives a register index in cog memory which is controlled by org.

    Example 1:
    PUB null
    DAT     [COLOR="blue"]org     0[/COLOR]
    
            mov     outa, a
            mov     outb, @a
    
    a       long    5
    
    here outa is loaded from register $002, outb from register $010.

    Example 2:
    PUB null
    DAT     [COLOR="red"]org     32[/COLOR]
    
            mov     outa, a
            mov     outb, @a
    
    a       long    5
    
    here outa is loaded from register $022, outb (still) from register $010.

    There is no direct relationship between @label and label (especially not simply dividing by 4).
  • agsags Posts: 386
    edited 2011-07-28 10:57
    kuroneko wrote: »
    Careful here! @ gives you a hub address and since this is used in a DAT section you get compile time behaviour which means an address which is relative to the start of the object (using it in SPIN will give you run-time behaviour, i.e. the real (absolute) address in hub). Not using @ gives a register index in cog memory which is controlled by org.

    Example 1:
    PUB null
    DAT [COLOR=blue]org 0[/COLOR]
     
    mov outa, a
    mov outb, @a
     
    a long 5
    
    here outa is loaded from register $002, outb from register $010.

    This is quite a bit different than I originally thought.

    I'm going to suggest that for this discussion we not include the use of @ in SPIN code. That seems to operate much as I expected ("address of" as in C/C++) and it doesn't seem to be very tricky - if used in a PUB block (which implies SPIN code)

    I'm also going to suggest that in reality, there are very few meaningful uses for the @ operator in a DAT block (implying PASM code). At least I can't figure out any use for it. It would be an unlikely coincidence if it actually provided a value that is related to the intended use - for anyone other than a very, very advanced user - and in general, it is likely to be a mistake to use the @ operator in a DAT block.

    However, I am still learning, even if indirectly, from the discussion, and would like to continue. What I see is that the value calculated at compile time (@a) will be the address, in bytes, of memory in HUB RAM represented by the symbol "a", for that DAT block as it exists in HUB RAM. However, the DAT block will be copied into COG RAM, and executed in COG RAM - where register addresssing is in longs, the absolute location of the DAT contents are guaranteed to not be the same as in HUB RAM, and the compile-time value of @a is unchanged. Is this correct?

    I have some strong opinions about the utility of the existing documentation (the Propeller Manual v1.1) that I'll share separately so as not to make this even more lengthy.
  • Dave HeinDave Hein Posts: 6,347
    edited 2011-07-28 12:09
    Your statement about the @ operator is correct, except that the value is not the hub byte address, but is a byte offset from the beginning of the object. The @@ operator will convert a hub offset to an abosolute address at runtime by adding the starting address of the object. The @@ operator is only valid in a PUB/PRI section.

    The meaning of the @ operator depends on whether it is used in a DAT section or a PUB/PRI section. In a DAT section it produces the object byte offset of the label. In a PUB/PRI section it produces the absolute address.

    This is documented in the Prop manual, but it is a bit confusing.
  • agsags Posts: 386
    edited 2011-07-28 12:57
    I'm astonished at the difference between how I thought this works and how it actually works - and even moreso that my code ever worked. Sheer stupid luck, I guess.

    I'm going to ammend my previous statement, and make it more concrete (and perhaps incorrect - please correct me if so):

    There is no meaningful use for the "@" operator operating on a PASM instruction operand (source or destination).
    Using the "@" operator in a DAT block containing constant values does provide some utility (e.g. tables) - but must be dealt with carefully by using the SPIN-only "@@" operator to resolve the value from object-relative to absolute.
    Using the "@" operator in a PUB/PRI block works as expected, without risk or special attention (other than remembering it's an address not the value at an address).

    Does anyone disagree with this (maybe not-so) bold statement?
  • Dave HeinDave Hein Posts: 6,347
    edited 2011-07-28 13:10
    The only thing I would disagree with is the statement "There is no meaningful use for the "@" operator operating on a PASM instruction operand (source or destination)." The object offset can be useful if you know the object's starting address. For the top object, you can get the absolute address by adding 16 to the offset. You could directly access a table in hub RAM if the absolute address is less than 511. The following PASM routine could make use of such a table.
    dat
    hexchars byte "0123456789abcdef"
    ...
    ' This routine converts the 4-bit value in "nybble" to an ASCII hex character in "hexchar"
    ' It uses the table of hex characters located at hexchars
    nybble_to_hexchar
            mov addr,#@hexchars+16
            add addr, nybble
            rdbyte hexchar, addr
    nybble_to_hexchar_ret
            ret
    
  • agsags Posts: 386
    edited 2011-07-28 15:35
    This continues to be very interesting. Not to argue, but to learn: I think I'm still sticking by my statement that you disagree with. It's not that it *can't* be used, I'm suggesting that there is no *meaningful* use. After pondering your example (and realizing it is just an example, not a real-world application where the technique is employed - and thus the source for error in my statement, since I'm not experienced with this), I see how it works, but I wonder why anyone would do that. The bytes containing the ASCII values now exist in hub RAM and cog RAM. And, you're now paying the 7-22 cycle penalty for accesing the values in hub RAM, when it could be accessed in cog RAM in 4 cycles. Hardcoding the position of "hexchars" in cog RAM (in this case, $000) doesn't seem any more risky to me than adding 16 to the hub RAM object offset (and ensuring that it is really to first block).

    Again, let me be clear on this: this is not mean to be argumentative, and you have demonstrated that this technique *could* be used. I'm also not asserting that I'm an expert by any means. I'll gladly admit that I do not have years of experience with the Properller, and I am certain, based on other threads I've participated in, there are many contributors to this forum with much more knowledge than I have. However, my thinking is that it actually never *would* be used, other than as an academic exercise. Am I still missing something?

    Thanks for the replies.
  • Dave HeinDave Hein Posts: 6,347
    edited 2011-07-28 16:37
    ags, it looks like you have a good understanding of how @ and # work in PASM now.
  • pjvpjv Posts: 1,903
    edited 2011-07-28 16:41
    Hello ags;

    Well, I for one use in many projects, exactly the technique Dave Hein demonstrated, so there is your real world example. Todate I have written most of my code in assembler, and one of the things I do is store many lists in hubram because space in cogram is just too precious. These lists can be text lists, or pseudocode lists that a specialized interpreter in a cog reads and executes, and several other applications.

    In fact in one significant approach I store many small (a dozen or two) short assembler driver sequences such as UART, I2C, OneWire etc. in hubram that any cog can dynamically download for execution, and when finished get flushed. This way, because program sections are not permanently resident, much larger programs can be executed in a cog than otherwise, yet at full assembler speed. The swapping in of these drivers is only 10 to 20-ish microseconds.... the length of a single typical SPIN instruction.

    So, There is a practical use for @ in assembler....

    By the way, for convenience I park all these DAT lists in the top object, so that the $10 offset remains constant.

    Cheers,

    Peter (pjv)
  • kuronekokuroneko Posts: 3,623
    edited 2011-07-28 16:41
    ags wrote: »
    I see how it works, but I wonder why anyone would do that. The bytes containing the ASCII values now exist in hub RAM and cog RAM. And, you're now paying the 8-23 cycle penalty for accesing the values in hub RAM, when it could be accessed in cog RAM in 4 cycles. Hardcoding the position of "hexchars" in cog RAM (in this case, $000) doesn't seem any more risky to me than adding 16 to the hub RAM object offset (and ensuring that it is really to first block).
    The thing here is that you want to reference e.g. a table which simply doesn't fit into the cog memory. Yes, the head may appear inside the cog due to the way cog memory is initialised but you still don't have access to the whole table while staying in cog.

    See it as one odd way of getting a hub reference. Personally I communicate stuff like that through par which is clean. The +$10 method will immediatly fail if the object is used as a child object.
  • AribaAriba Posts: 2,690
    edited 2011-07-28 17:28
    kuroneko wrote: »
    ...
    See it as one odd way of getting a hub reference. Personally I communicate stuff like that through par which is clean. The +$10 method will immediatly fail if the object is used as a child object.

    ... and if you know the address of one variable, the @ operator is useful to calculate the addresses of other variables (not more than 512 bytes away):
    DAT
    var1 long 0
    ...
    varN long 0
    
    asm  org 0
         mov pntr1,par           'par points to var1
         mov pntrN,par
         add pntrN,#@varN-@var1
    
    

    Andy
  • agsags Posts: 386
    edited 2011-07-29 18:06
    @pjv: OK, I see that now. That makes sense to me. While I would describe that as somewhat esoteric (or at least advanced) I can see the merit and utility of that. Particularly the ability to swap PASM code into a cog as needed. How the heck to you guys come up with this stuff? Really, I wonder if the designers had all this capability in mind or if it even surprises them when they see the "tricks" that ingenious users come up with to get things done.

    @Dave Hein: Thanks for your patience and help with this. I do think I understand now, and it is much different than I thought. I am still dumbfounded that my code worked at all.

    Having said all that, I now find myself wanting to validate my understaning of how the 6 blocks are arranged in hub RAM, (and how DAT blocks are loaded into cog RAM). I read the bit about "org" in the manual, and it doesn't clearly describe how it would be used other than "org 0". I'm not clear how the technique described here to reference data that is too big to fit into cog RAM could work; if it's too big to fit into cog RAM, then how can it be in a DAT block? Isn't the DAT block copied to cog RAM upon initialization?

    Is there somewhere that I can read all about this? I know it must be pretty basic stuff.

    Thanks again.
  • kuronekokuroneko Posts: 3,623
    edited 2011-07-29 18:22
    A DAT block is not limited to 512 longs. You can easily place e.g. long -1[1024] into it and get away with it. Or think of the file command/directive for inclusion of external data. And a DAT block can also contain PASM (disguised as data if you want). The limitation here is that cog RAM only holds 512 longs which means only this amount is transferred starting at the address passed to cognew/coginit. Which has the side effect that you may end up with SPIN code (follows DAT) in cog memory if your PASM program (or in fact DAT section) is small enough.
  • K2K2 Posts: 693
    edited 2011-07-29 19:57
    ags wrote: »
    How the heck to you guys come up with this stuff?

    I'm with you! I've been so occupied with making cogs do one thing that it never occurred to me to do what pjv outlined. The sudden awareness of all the additional possibilities is blowing my mind. Maybe this is why Cluso, Heater, and others are so enamored with Hub RAM, and are constantly pining for more. It never seemed that useful to me except as a temporary code repository between EEPROM and COG RAM. Like Edwin Starr once said, "Hub - What is it good for? Absolutely nothing!" Or maybe he didn't say that.
  • agsags Posts: 386
    edited 2011-07-29 21:30
    K2 wrote: »
    Like Edwin Starr once said, "Hub - What is it good for? Absolutely nothing!" Or maybe he didn't say that.

    Now that's funny. I think we may be conteporaries - and many others may be as bewildered by that comment as I have recently been with the nuances uncovered by this thread...
  • agsags Posts: 386
    edited 2013-04-13 09:44
    @Dave Hein et al:

    So I've come back to this thread for a refresh of my understanding, as I'm in the midst of a nasty debugging effort (and have run out of other ideas) and I found this to be a very helpful discussion the first time around. After the nth re-read, either I still don't understand this 100% correctly or there are some mistakes (or clarifications). Would you agree with these edits?
    Dave Hein wrote: »
    Yes, I did mean this. And don't call me Shirley. :)

    I am referring to the values associated with the label, and not the value at the location that the label refers to. The following statements use the values of the label:
            mov reg, label         ' Get contents at the cog location pointed to by label
            mov reg, #label        ' Get the cog location for label
            mov reg, #@label       ' Get the object byte offset for label
            mov reg, obj_offset    ' Get the [s]cog location[/s] [B]object byte offset[/B] for label
            mov reg, cog_address   ' Get the [s]object byte offset[/s] [B]cog location[/B] for label
            ....
    label long 123
    obj_offset long @label
    cog_address long label
    
    The value stored at the location addressed by "label" is 123, but the value of "label" when used as a constant is its hub address cog location, and the value of "@label" is its byte offset within the object. The symbols "label" and "@label" can be use like any other constants, such as in an expression like "label*4 + 3".

    ...and when used in a variable expression (i.e. SPIN PUB|PRI block), "label" refers to the contents of the hub memory location that label refers to.
  • Heater.Heater. Posts: 21,230
    edited 2013-04-13 10:33
    As far as I recall @ is insane. Using @ to initialize a pointer in a DAT secition gives a different result than using it in Spin code:
    VAR
    long someVar
    
    DAT
    addr1 long @someVar
    
    PUB start | addr2
        addr2 := @someVar   ' Not the same as addr1
    

    It confused me so much I never use it ouside of Spin and pass all addresses in via par, which as kuroneko says, is clean.

    Whish I had a Prop here to try it out on again.
  • Dave HeinDave Hein Posts: 6,347
    edited 2013-04-13 11:52
    ags, your edits are correct. Thanks, for catching my errors.
  • agsags Posts: 386
    edited 2013-04-13 16:47
    I think the Propeller manual does say what is happening with the @ operator. I'm not suggesting that it is incorrect, or even unclear, but for me, the way I am beginning to think of @ is that it is really two different operators (or an overloaded operator, or an operator and a compiler directive). It's not so much where it's used (DAT, PUB|PRI) so much as when it is evaluated. I'm not offering any content here that hasn't already been said (much of it in this thread) - but a different way of presenting the information, in an attempt to help make understanding what I've heard others say is confusing clearer and concrete.

    1) When the compiler is evaluating @ (e.g. when initializing data, which of course means in a DAT block) the compiler has to figure out the value (at compile time). The compiler can't know the absolute address since it depends on where the object is located when the entire application is loaded into hub memory, so it can only supply an object-relative address.

    2) When the SPIN interpreter is evaluating @ (e.g. in a variable expression, which means in a PUB|PRI block) the SPIN interpreter does have all the information needed to determine the absolute address in hub ram (runtime evaluation). This is why I am now tending to think of these as two different operators: one is a compiler "directive" (sort of), resolved at compile time; the other is actually a SPIN operator, resolved at run time (presumably) by executing some SPIN byte code to determine both the offset of the object in the application and the offset of the symbol within the object. As another way of thinking, it's almost as though the compiler evaluates @ during compile time in exactly the same way (in DAT and PUB|PRI blocks), and in addition inserts an "@@" SPIN (runtime) operator as well when in a PUB|PRI block.

    This may not be the way others think of this, and I'm not saying it's necessarily the best way to think of it. But for the purpose of internalizing an accurate understanding of what is happening (in each use case), if anyone sees anything incorrect about this model of how @ works, please correct me.

    PS - not that I'm an expert. I still haven't debugged my problem...
  • Heater.Heater. Posts: 21,230
    edited 2013-04-14 00:58
    I think you are getting to the point.

    There are three different cases aren't there?
    1) Knowing the offset of something within a module when the module is compiled. At that point the compiler does not know where the module is goiing to be in HUB so an offset is the best it can do.
    2) Knowing the actual HUB address of something when modules are linked together. Now the linker knows where things will be.
    3) Knowing the address of something that can move. The address of local variables and parameters can change depending an from where a method is called and the resulting stack depth.

    The fisrt to can all be done statically ay build time. The last can only be done at run time.

    But it seems the @s in Spin are fixed up when linking is done but the @'s in DAT are not, hence @someVar can be different in each case.
  • agsags Posts: 386
    edited 2013-04-17 21:35
    Yes, I think your way of describing this is probably more accurate than mine. It's probably not the SPIN interpreter that is determining the runtime value of "@@" - it's done during "linking". I hadn't thought of the final assembly of objects (OBJ blocks) as a linking stage until you pointed that out. I suppose that's just what it is - dealing with all the inter-OBJ (relocatable) symbol resolution.

    I was trying to think of a reason why all "@" (DAT and PUB|PRI) couldn't be resolved at "link" time. I was wondering if there was some cyclic problem that could occur (like the value of some constant (DAT) impacting the size of the OBJ itself, thus modifying the location of the OBJ and the value of the "@" when resolved) that would prevent "link"-time resolution, but couldn't come up with a realistic example of this.
Sign In or Register to comment.