Addressing and labeling syntax
Seairth
Posts: 2,474
(as of the 2015-10-13 PNUT release)
So. Because the addressing and labeling syntax has been a bit of a moving target, I wanted to try to document this thoroughly. Yes, some of this is obvious, but I wanted a "big picture" coverage of the topic. So here it is...
Labels:
Label values:
For expressions:
Does this look right to everyone else? Anything to add, change, or remove?
(edit: clarified expression branching vs. non-branching immediate values, as suggested by @Electrodude.)
(edit: clarified label naming and fixed typo, as pointed out by @mindrobots and @potatohead.)
(edit: Updated "@" usage to better align with comments by @cgracey.)
So. Because the addressing and labeling syntax has been a bit of a moving target, I wanted to try to document this thoroughly. Yes, some of this is obvious, but I wanted a "big picture" coverage of the topic. So here it is...
Labels:
- Labels are either globally-scoped or locally-scoped.
- A globally-scoped label must begin with an underscore or letter (a-z, A-Z). All other characters must be an underscore, letter (a-z, A-Z) or number (0-9).
- A locally-scoped label must begin with a period, followed by an underscore or letter (a-z, A-Z). All other characters must be an underscore, letter (a-z, A-Z) or number (0-9).
- Each local scope begins immediately after each global label and ends immediately before the next global label.
- All labels must be unique within the scope they belong to.
Label values:
- Labels defined in an ORGH section resolve to a hub address or offset (in bytes), regardless of whether the label is referenced in an ORGH or ORG section.
- Labels defined in an ORG section resolve to a cog address or offset (in longs), regardless of whether the label is referenced in an ORGH or ORG section.
- When the effective hub address or offset is needed for a label that is defined in an ORG section, the label may be preceded by a "@" to force resolution to a hub address or offset.
- Though it is possible to apply the "@" to labels defined in ORGH sections, it has no effect.
For expressions:
- Expressions can contain numbers, labels, and nested expressions. The simplest expression is either a single number or label.
- An expression that begins with # or ## is known as an "immediate" value.
- For branching instructions, immediate values can be either "absolute" or "relative", depending on context.
- For non-branching instructions, immediate values are always "absolute".
- "Absolute immediate" interpretation can be forced by using "#\" or "##\".
- There is no operator for forcing a "relative immediate" interpretation.
- # means 9-bit (short-form) or 20-bit (long-form) immediate value:
- For short-form branch instructions, this is a 9-bit relative immediate.
- For long-form branch instructions that change execution mode (cog <-> hub), this is a 20-bit absolute immediate.
- For long-form branch instructions that do not change execution mode, this is a 20-bit relative immediate.
- For all other instructions, this is a 9-bit absolute immediate.
- In circumstances where an absolute immediate must be forced, the expression is prefaced with "#\".
- ## means 32-bit immediate value
- An implicit AUGx will precede the instruction containing the expression.
- The lower 9 bits will be encoded in the instruction and the upper 23 bits will be encoded in the AUGx.
- For short-form branch instructions, this is a 20-bit relative immediate. The upper 12 bits are ignored.
- For non-branch instructions, this is a 32-bit absolute immediate.
- This is meaningless for long-form branche instructions. PNUT throws an error.
- For BYTE/WORD/LONG, the expression is encoded as raw data. If the expression begins with # or ##, PNUT throws an error.
- For all other expressions that do not begin with # or ##, the expression is encoded as a register address and must be between $000 and $1FF.
Does this look right to everyone else? Anything to add, change, or remove?
(edit: clarified expression branching vs. non-branching immediate values, as suggested by @Electrodude.)
(edit: clarified label naming and fixed typo, as pointed out by @mindrobots and @potatohead.)
(edit: Updated "@" usage to better align with comments by @cgracey.)
Comments
"add x, #y" adds the absolute cogram address of y, not the distance from the pc to y, into x. "add x, #\y" would throw an error.
Nice work.
This is detailed in the sub-lists. However, I agree that it could be made more explicit. So I've updated it (see bullets 3 and 4 of "For expressions...".
Grep anyone? [.]?[_a-zA-Z][_a-zA-Z0-9]+
I'm not sure this is a generic enough explanation for anyone that doesn't grok grep. Words are always nice:
"Global labels begin with an underscore or any upper or lowercase letter followed by any number of underscores, letter or numbers. Local labels must begin with a ".", this can them be followed by any combination of letters, numbers or underscores. "
I think you dropped some words in the last bullet:
"For all other expressions that do not between with # or ##, the expression is encoded as a register address and must be between $000 and $1FF."
That do not WHAT between???? The curious want to know!
Updated as words instead.
Huh. Even after proofreading it, I still read it as "begin". Fixed.
When did things get so complicated in the Propeller ?
Basically, when hub exec was added (and, to a lesser extent, LUT exec). Without that, we would not need any long-form branches or short-form branches with AUGx. And all short-form branches would always be relative.
Nope. Not until P2 Spin development has actually started.
I hope this is not all so hard to write as it is to read about...
When labels declared under ORG are referenced, they return cog address values.
@label is only needed when you want to know the hub address of a label declared under ORG.
@label is superfluous when used on labels that were declared under ORGH.
If "@label" is the same as "label" on P2, then I wonder how we will get the object offset in Spin 2. Or maybe Spin 2 won't use object offsets.
The # prefix on a label is one example, and restricts the ability of the ASM to check scope.
Once you tag immediate on anything, that becomes just a number.
So this is a very rare usage ?
Can you give an example of when someone would want to declare a hub address under ORG ?
I expected that ORGH set a Hub segment and ORG sets COG segment, and the Assembler would know which label was within each.
Because code now has two possible locations, it will help if users can hop between segments in a relocatable manner.
Some functions may be coded to be COG based and others nearby may be HUB.
An example could be INIT code, where you do not mind if that is a little slower, and can stay in HUB, but faster 'inner loops' may be very much COG focused.
Code assembles into hub space sequentially, regardless of whether it's under ORGs or ORGHs. The only sort-of exception is when ORGH is followed by a value, in which case $00's are filled to that point.
I was thinking that it would be really neat to have the development tool always be able to give you a graphical representation of memory usage by ORG/ORGH type, maybe showing 1 pixel per byte or long. Then, you would always know at a glance how things were laid out. This could be expanded in spin to incorporate Spin and VAR sections. It could really clear the air. The most important thing is to give the programmer a clear understanding, so that he can program confidently. Makes things go way faster.
I don't see why anyone would want to do that. In cases of ORG (cog) code, though, you might need the hub address, which is what @ is for.
Sounds like it needs some form of segment support added ?
Good MAP files can do that, and I prefer ASCII files over GUIs as ASCII files can be saved, parsed, and run through version-checkers....
Initialize data in a COG image in hubram before you do COGINIT; tweak an instruction (pre-modify self modifying code); probably more, we're a resourceful bunch at times! Hub exec will challenge us to try the unlikely.
Yes, that is true when using "@label" within a Spin method. But on the P1, "@label" used in the DAT section provides the object offset and not the hub address. It seems that I must not be explaining this very well, so I'll just quit commenting on it until the issue comes up later on when P2 Spin is implemented.