A link-time solution would require tagging all the locations that would need adjustment when compiling, and then adding the object offset when linking. That's not how the Spin compiler/linker works. The Spin interpreter resolves the addresses at run time by adding the object offset (PBASE) whenever a DAT variable is accessed. The @ operator just results in the sum of PBASE plus the offset. The @@ operator adds PBASE to the following number. "@@0" will give you the value of PBASE.
The following code
DAT
temp long 0
PUB main
result := temp
compiles the object offset of "temp" into the code. When the Spin interpreter executes "result := temp" it must add PBASE to temp's object offset to determine it's address. Using object offsets allows an object to be moved to anywhere in hub RAM as long as PBASE is set to the beginning of that object. This eliminates a lot of complexity from the linker, but does add a small burden to the interpreter.
I don't know what was in the minds of the creator(s) when SPIN was conceived and implemented. There may be a good reason for this, but without having participated in the design, it's hard for me to understand how it made sense to simplify the compiler/linker (write once, run millions of times) at the expense of the use model (write millions of times).
The overhead for using object offsets is just one extra add instruction. These extra 4 cycles are small compared to the number of cycles required to execute a Spin bytecode. One feature of using object offsets is that a snippet of Spin code can be loaded anywhere in memory and executed without having to fix up the addresses. This makes it possible to load Spin code from an SD card and run it in a separate cog while continuing to run the boot code in cog 0. I'm not sure if Chip anticipated using Spin this way, but it's a nice feature.
The use of object offsets is consistent with the way stack variables and VAR variables are accessed. These memory spaces are determined by the values of PBASE, DBASE and VBASE. VBASE is important because it makes it easy to implement multiple instances of an object just by setting VBASE to point to the beginning of an object's VAR space. DBASE points to the beginning of a method's stack space. It's basically the address of the RESULT variable. All stack variables are addressed as an offset from DBASE.
Yes, but I am still waiting for a rational expanation of why @ in some Spin code yeilds a different result than @ in a data declaration in a DAT section.
Of course taking @ of something in a VAR section should perhaps be relative to the object as there are possibly many instances . But then taking the @ of something in a DAT section is different because DAT is unique and shared amoung object instances.
Then there is @@ which does not work either in some cases which is why BST has @@@.
It's all very confusing. at the end of the day all you want is the friggin HUB addresss of whatever it is.
Comments
The following code compiles the object offset of "temp" into the code. When the Spin interpreter executes "result := temp" it must add PBASE to temp's object offset to determine it's address. Using object offsets allows an object to be moved to anywhere in hub RAM as long as PBASE is set to the beginning of that object. This eliminates a lot of complexity from the linker, but does add a small burden to the interpreter.
The use of object offsets is consistent with the way stack variables and VAR variables are accessed. These memory spaces are determined by the values of PBASE, DBASE and VBASE. VBASE is important because it makes it easy to implement multiple instances of an object just by setting VBASE to point to the beginning of an object's VAR space. DBASE points to the beginning of a method's stack space. It's basically the address of the RESULT variable. All stack variables are addressed as an offset from DBASE.
Yes, but I am still waiting for a rational expanation of why @ in some Spin code yeilds a different result than @ in a data declaration in a DAT section.
Of course taking @ of something in a VAR section should perhaps be relative to the object as there are possibly many instances . But then taking the @ of something in a DAT section is different because DAT is unique and shared amoung object instances.
Then there is @@ which does not work either in some cases which is why BST has @@@.
It's all very confusing. at the end of the day all you want is the friggin HUB addresss of whatever it is.