In Z80 assembly, you can define labels and symbols. Both constructs are syntactically the same, but there is some difference in their semantics. While we define labels to mark addresses (code points) in the program so that we can jump to those addresses, read or write their contents, symbols are not as specific, they just store values we intend to use. From now on, I will mention “label” for both constructs and will do otherwise only when the context requires. When you write a SpectNetIDE assembly instruction, you can start the line with a label:
MyStart: ld hl,0
Here, in this sample,
MyStart is a label. The assembler allows you to omit the colon after the label name, so this line is valid:
MyStart ld hl,0
Some developers like to put a label in a separate line from the instruction it belongs. You can use the same hanging label style within SpectNetIDE. In this case, the label should go before its instruction. Take a look at this code snippet:
MyStart: ld hl,0 MyNext ; Use B as a counter ld b,32
This code is entirely correct. Note, the
ld b,32 instruction belongs to the
MyNext label. As you see from the sample, the colon character is optional for hanging labels, too. You can have multiple line breaks between a label and its instruction, and the space can include comments.
Label and Symbol Declarations
As you will learn later, you can define symbols with the
.VAR pragmas. While
.EQU allows you to assign a constant value to a symbol — and so it cannot change its value after the declaration,
.VAR let’s you re-assign the initial value.
SpectNetIDE supports the idea of lexical scopes. When you create the program, it starts with a global (outermost) lexical scope. Particular language elements, such a statements create their own nested lexical scope. Labels and symbols are always created within the current lexical scope. Nonetheless, when resolving them, the assembler starts with the innermost scope and goes through all outers scopes until it manages to find the label declaration. This mechanism means that you can declare labels within a nested scope so that those hide labels and symbols in outer scopes. You can learn more about this topic in the Statements section.
SpectNetIDE also supports modules, which allow you to use namespace-like constructs (see the Modules section for details).
The assembler considers labels that start with a backtick (`) character as temporary labels. Their scope is the area between the last persistent label preceding the temporary and the first persistent label following the temporary one.
This code snippet demonstrates this concept:
SetPixels: ; Persistent label ld hl, #4000 ld a,#AA ld b,#20 `loop: ; Temporary label (scope #1) ld (hl),a inc hl djnz `loop SetAttr: ; Persistent label, scope #1 disposed here ld hl,#5800 ld a,#32 ld b,#20 `loop: ; Temporary label (scope #2) ld (hl),a inc hl djnz `loop ret ; scope #2 still lives here ; ... Another: ; Persistent label, scope #2 disposed here ld a,b
As you see, the two occurrences of `loop belong to two separate temporary scopes. The first scope is between from
SetAttr, the second one between