How do you find the hub address of initialized data?

If I include initialized data in a SPIN program (PASM at this point), how do I find the hub address of that initialized data? I looked at Chips ROM monitor code and he takes some very elaborate steps to statically calculate the offsets and store them as immediates, but I want to know the right way of finding the hub address of a variable.
Comments
What I do is look at the object listing in Pnut, then add the load address to it, which is usually $e80, but can be $1000, or something else
TYPE: 4B VALUE: 013402B8 NAME: XMIN TYPE: 4B VALUE: 013802BC NAME: YMIN TYPE: 4B VALUE: 013C02C0 NAME: XMAX TYPE: 4B VALUE: 014002C4 NAME: YMAX TYPE: 4B VALUE: 014402C8 NAME: MAX_COMPUTE TYPE: 4B VALUE: 014802CC NAME: COLOR_MUL
That is from the object listing for the fractal thing I just did. The VALUE: field is two words. For YMAX, these are 0140 02C4. The lower word is the HUB address, starting from 0. The upper word is the address relative to the ORG last issued.
So then, YMAX lives at $0e80+$02c4 absolute HUB address.
The "@" operator generally just needs the load address added to it for things to work nicely, if you've not padded the code with an array.
IMHO, the monitor being in low RAM warrants and ORG and OBJ operator... or some other thing that specifies an address offset to work with.
There is a more detailed explanation aimed at using the monitor to modify values, start COGS, etc... You can find that document here: http://forums.parallax.com/attachment.php?attachmentid=98587&d=1357887830
setptrb buffer mov buf, #fox shl buf, #2 add buf, cogbase call #print_string print_string setptra buf :loop rdbytec c, PTRA++ wz if_nz or c, color if_nz wrword c, PTRB++ if_nz jmp #:loop print_string_ret ret cogbase long $E80 fox byte "The quick brown fox jumped over the lazy dog.",0
CON _ROM_SIZE = $E80 ' length of ROM (i.e. the start of Hub Ram) _RESERVED = $180 ' reserved for drivers $00E80-$00FFF _COG_BASE = _ROM_SIZE+_RESERVED ' cog code entry _clkmode = xinput _xinfreq = 60_000_000 ''============================[ DAT ]============================================================ DAT byte 0[_ROM_SIZE] ' filler for ROM space $e80 byte 0[_RESERVED] ' filler for reserved HUB space $180 '$01000 org 0 entry setptrb buffer mov buf, ptrfox call #print_string print_string setptra buf :loop rdbytec c, PTRA++ wz if_nz or c, color if_nz wrword c, PTRB++ if_nz jmp #:loop print_string_ret ret fox byte "The quick brown fox jumped over the lazy dog.",0 . ptrfox long @fox ' the hub address of string1
and use p2load like this...
p2load -v -s xxxx.obj -h -T
p2load (-s) skips the first $e80 longs, and starts cog execution at (-h) $1000 hub.
This method saves worrying about the $e80 offset.
If you remove the -h, then execution will start at $e80, so delete the line allocating the
byte 0[_RESERVED]