Labels are mainly used to hold numerical values. This comes in handy because we humans are better in remembering names than meaningless values. For this reason labels play a very important role in assemblers.
Labels can hold different types of values like constants, addresses, offsets, SFRs, bit patterns etc.
The SB-Assembler only remembers the label's value, not what type of value it is holding.
This means that you can use these values for any purpose without bothering about type conversion.
This doesn't only give you more freedom as a programmer, it also gives you more responsibility.
Label declarations always start at column 0 of the program line. An optional colon : may follow the label name. This colon is only accepted for compatibility reasons with other assemblers and serves no particular purpose. The label name should be followed by a white space, which is a space, a TAB or an EOL.
The label can get its value in several different ways:
Labels may be declared only once.
The value they get is fixed and may not be changed anymore.
The only exception to this rule are labels that get their value from the .SE directive, their value is variable and may be changed as often as you like.
In a 2-pass assembler, like the SB-Assembler, labels can be used (referenced) before they are declared.
All label values should be resolved at the end of the 1st pass though.
Their actual values are used in the 2nd pass.
Using, or referencing, labels which are not yet declared is called forward referencing.
Note: Most Crosses which support variable length addressing modes allow you to force the use of the shortest addressing mode by preceding the expression by the < symbol.
Be careful though with that function!
The assembled program may fail, big time, without warning if the address doesn't fit in the short addressing mode!
It should only be used when you are sure the forward referenced address will fit in the short addressing mode.
Label names should not be the same as reserved names.
To begin with, there are no reserved names known to the SB-Assembler, so any names can be given to your labels.
The SB-Assembler knows 3 types of labels:
Label names are case insensitive which means that there's no difference between upper and lower case characters.
The label name may be of any length, up to 255 characters.
However only the first 32 characters are actually remembered by the assembler.
This means that the assembler will not notice differences in names beyond the 32nd character.
A Global label name starts with a character from A to Z and may further contain any characters from A to Z, the digits 0 to 9, the underscore _ and a dot . for all subsequent characters.
The SB-Assembler stops parsing the label name if any other character is encountered.
Some assemblers require a colon : behind the label name during declaration.
With the SB-Assembler this colon is optional and serves no particular purpose, other than perhaps readability.
Some examples of Global labels:
RESET CharOut KEY_IN SAMPLE.LABEL EXIT30 WITHCOLON:
A Local label name starts with a dot and follows the same rules as Global labels for all subsequent characters. The character following the dot doesn't necessarily have to be a character from A to Z. The dot is also counted as character in the name length (Only Version 2 of the SB-Assembler).
Some examples of Local labels:
.2 .LOOP .Again .SKIP:
A Macro label name starts with a colon, which is the only difference from Local label names when it comes to syntax.
Some examples of macro labels:
:3 :LOOP :Again :Skip
Global labels can be accessed throughout the entire program. It doesn't matter that they are declared in other include files either. In fact there is only one name space, which holds all Global labels and their values in the SB-Assembler.
The use of Global labels has some small, but important side effects.
Every time a Global label is declared, all previously declared Local labels become inaccessible.
They are not forgotten though, you simply can't reach them anymore.
Local labels are one of the most interesting features of the SB-Assembler. Strangely enough most assemblers must do without them.
Label names should be as descriptive as possible to keep the program readable for us humans.
But inventing unique and meaningful names becomes more and more difficult when our program grows longer and longer.
Especially if you have to use unique names for loops and skips throughout a long program too.
In many assembly programs you see label names like LOOP217, SKIP_XXX, or even more meaningful names like XXXX and X127.
An example using label .LOOP twice
DELAY100 MOV R1,#100 .LOOP DEC R1 JNZ .LOOP RET ; The next line makes the SB-Assembler forget all Local labels DELAY10 MOV R1,#10 .LOOP DEC R1 JNZ .LOOP RET
As you can see the Local label .LOOP is declared twice. This is perfectly legal because the first instance only "lives" from DELAY100 until but not including DELAY10. The first JNZ instruction jumps back to the first instance of the Local label .LOOP. The second JNZ jumps back to the second Local label .LOOP because the first one is not accessible anymore.
Local labels may not be declared until at least one Global label is declared, otherwise the SB-Assembler will report a "Missing Global label error".
In Version 2 of the SB-Assembler it is also not allowed to declare a Local label directly after a macro definition, until a new Global label is declared.
This is done because macro definitions are stored in the same symbol table as labels.
With Version 3 of the SB-Assembler it is now possible to access Local lables belonging to other Global labels. You do that by adding the Global label, to which the desired Local label belongs, in front of the Local label, separated by a collon and omitting the first dot of the Local label.
A silly example
DELAY100 MOV R1,#100 .LOOP DEC R1 JNZ .LOOP RET ; The next line makes the SB-Assembler forget all Local labels DELAY10 MOV R1,#10 .LOOP DEC R1 JNZ DELAY100:LOOP RET
In this silly example the second JNZ instruction now jumps back to the first Local label .LOOP . The Global label is separated from the Local label by a colon, while the first dot of the Local label is omitted.
A more useful example is the imitation of a data set. The SB-Assembler doesn't really know the concept of data sets, but you can imitate them.
A data set imitation example
DATASET .OR $50 Beginning of the data set .COUNTER .BS 2 A 2 byte wide counter .VALUE .BS 1 A 1 byte long value .ERROR .BS 1 A 1 byte long error value .RESULT .BS 4 A 4 byte long result INCCOUNT INC DATASET:COUNTER Increment low byte of counter BNE .NOCARRY No carry to high byte! INC DATASET:COUNTER+1 Increment high byte of counter .NOCARRY RTS
Please note that Global labels and Local labels must be declared on separate lines. For instance you can't declare the label DATASET:COUNTER in one blow. You'd have to declare DATASET first, and then on a separate line you should declare label .COUNTER.
Only Local labels may be combined with Global labels this way. It is not possible (nor disirable) to do this with Global labels and macro labels. Even if the colon may sugest that it should work with macro labels too.
Macro labels are very similar to Local labels, in fact outside Macros they work exactly the same.
Outside macros, Local labels and Macro labels may even be interchanged in Version 3 of the SB-Assembler.
Thus label .LOOP is the same label als label :LOOP (Only in Version 3).
What exactly is the problem with normal Global and Local labels within an expanding Macro?
Suppose I declare a normal Global label within a Macro.
Then I could use (expand) this Macro only once because the Global label would be declared again if I want to expand the Macro for a second time.
But the label will probably get a different value the second time.
This is not acceptable and we have to think of another way of handling this.
Macro labels may not be used until at least one Global label is declared, otherwise the SB-Assembler will report a "Missing global label error".
More detailed information about Macro labels can be found in the special chapter about Macros.