1
0
mirror of https://github.com/cc65/cc65.git synced 2024-12-27 00:29:31 +00:00

Explain more new stuff

git-svn-id: svn://svn.cc65.org/cc65/trunk@2715 b7a2c559-68d2-44c3-8de9-860c34a00d81
This commit is contained in:
cuz 2003-12-05 22:30:18 +00:00
parent 140dee0eea
commit 35e639aac6

View File

@ -800,22 +800,139 @@ id="scopesearch" name=""Scope search order"">).
<sect1>Structs, unions and enums<p>
Structs, unions and enums are explained in a <ref id="structs" name="separate
section">, I do only cover them here, because if they are declared with a
name, they open a nested scope, similar to <tt/<ref id=".SCOPE"
name=".SCOPE">/. However, when no name is specified, the behaviour is
different: In this case, no new scope will be opened, symbols declared within
a struct, union, or enum declaration will then be added to the enclosing scope
instead.
<sect1>Explicit scope specification<label id="scopesyntax"><p>
Accessing symbols from other scopes is possible by using an explicit scope
specification, provided that the scope where the symbol lives in has a name.
The namespace token (<tt/::/) is used to access other scopes:
<tscreen><verb>
.scope foo
bar: .word 0
.endscope
...
lda foo::bar ; Access foo in scope bar
</verb></tscreen>
The only way to deny access to a scope from the outside is to declare a scope
without a name (using the <tt/<ref id=".SCOPE" name=".SCOPE">/ command).
A special syntax is used to specify the global scope: If a symbol or scope is
preceeded by the namespace token, the global scope is searched:
<tscreen><verb>
bar = 3
.scope foo
bar = 2
lda #::bar ; Access the global bar (which is 3)
.endscope
</verb></tscreen>
<sect1>Scope search order<label id="scopesearch"><p>
The assembler searches for a scope in a similar way as for a symbol. First, it
looks in the current scope, and then it walks up the enclosing scopes until
the scope is found.
However, one important thing to note when using explicit scope syntax is, that
a symbol may be accessed before it is defined, but a scope may <bf/not/ be
used without a preceeding definition. This means that in the following
example:
<tscreen><verb>
.scope foo
bar = 3
.endscope
.scope outer
lda #foo::bar ; Will load 3, not 2!
.scope foo
bar = 2
.endscope
.endscope
</verb></tscreen>
the reference to the scope <tt/foo/ will use the global scope, and not the
local one, because the local one is not visible at the point where it is
referenced.
Things get more complex if a complete chain of scopes is specified:
<tscreen><verb>
.scope foo
.scope outer
.scope inner
bar = 1
.endscope
.endscope
.scope another
.scope nested
lda #outer::inner::bar ; 1
.endscope
.endscope
.endscope
.scope outer
.scope inner
bar = 2
.endscope
.endscope
</verb></tscreen>
When <tt/outer::inner::bar/ is referenced in the <tt/lda/ instruction, the
assembler will first search in the local scope for a scope named <tt/outer/.
Since none is found, the enclosing scope (<tt/another/) is checked. There is
still no scope named <tt/outer/, so scope <tt/foo/ is checked, and finally
scope <tt/outer/ is found. Within this scope, <tt/inner/ is searched, and in
this scope, the assembler looks for a symbol named <tt/bar/.
Please note that once the anchor scope is found, all following scopes
(<tt/inner/ in this case) are expected to be found exactly in this scope. The
assembler will search the scope tree only for the first scope (if it is not
anchored in the root scope). Starting from there on, there is no flexibility,
so if the scope named <tt/outer/ found by the assembler does not contain a
scope named <tt/inner/, this would be an error, even if such a pair does exist
(one level up in global scope).
Ambiguities that may be introduced by this search algorithm may be removed by
anchoring the scope specification in the global scope. In the example above,
if you want to access the "other" symbol <tt/bar/, you would have to write:
<tscreen><verb>
.scope foo
.scope outer
.scope inner
bar = 1
.endscope
.endscope
.scope another
.scope nested
lda #::outer::inner::bar ; 2
.endscope
.endscope
.endscope
.scope outer
.scope inner
bar = 2
.endscope
.endscope
</verb></tscreen>
<sect>Address sizes<label id="address-sizes">
<p>
<sect>Address sizes<label id="address-sizes"><p>
@ -2493,6 +2610,51 @@ Here's a list of all control commands and a description, what they do:
<tt><ref id=".PSC02" name=".PSC02"></tt>
<sect1><tt>.SIZEOF</tt><label id=".SIZEOF"><p>
<tt/.SIZEOF/ is a pseudo function that returns the size of its argument. The
argument can be a struct/union, a struct member, a procedure, or a label. In
case of a procedure or label, its size is defined by the amount of data
placed in the segment where the label is relative to. If a line of code
switches segments (for example in a macro) data placed in other segments
does not count for the size.
Please note that a symbol or scope must exist, before it is used together with
<tt/.SIZEOF/ (this may get relaxed later, but will always be true for scopes).
A scope has preference over a symbol with the same name, so if the last part
of a name represents both, a scope and a symbol, the scope is choosen over the
symbol.
Usage examples:
<tscreen><verb>
.struct Point ; Struct size = 4
xcoord .word
xcoord .word
.endstruct
P: .tag Point ; Declare a point
.code
.proc Code ; 3 bytes
nop
nop
nop
.endproc
.proc Data ; 4 bytes
.data ; Segment switch!!!
.res 4
.endproc
lda #.sizeof(Point) ; Loads 4
lda #.sizeof(Point::xcoord) ; Loads 2
lda #.sizeof(P) ; Loads 4
lda #.sizeof(Code) ; Loads 3
lda #.sizeof(Data) ; Loads 0
</verb></tscreen>
<sect1><tt>.SMART</tt><label id=".SMART"><p>
Switch on or off smart mode. The command must be followed by a '+' or
@ -2500,13 +2662,21 @@ Here's a list of all control commands and a description, what they do:
is off (that is, the assembler doesn't try to be smart), but this
default may be changed by the -s switch on the command line.
In smart mode the assembler will track usage of the <tt/REP/ and <tt/SEP/
instructions in 65816 mode and update the operand sizes accordingly. If
the operand of such an instruction cannot be evaluated by the assembler
(for example, because the operand is an imported symbol), a warning is
issued. Beware: Since the assembler cannot trace the execution flow this
may lead to false results in some cases. If in doubt, use the <tt/.Inn/ and
<tt/.Ann/ instructions to tell the assembler about the current settings.
In smart mode the assembler will do the following:
<itemize>
<item>Track usage of the <tt/REP/ and <tt/SEP/ instructions in 65816 mode
and update the operand sizes accordingly. If the operand of such an
instruction cannot be evaluated by the assembler (for example, because
the operand is an imported symbol), a warning is issued. Beware: Since
the assembler cannot trace the execution flow this may lead to false
results in some cases. If in doubt, use the <tt/.Inn/ and <tt/.Ann/
instructions to tell the assembler about the current settings.
<item>In 65816 mode, replace a <tt/RTS/ instruction by <tt/RTL/ if it is
used within a procedure declared as <tt/far/, or if the procedure has
no explicit address specification, but it is <tt/far/ because of the
memory model used.
</itemize>
Example:
@ -2515,6 +2685,11 @@ Here's a list of all control commands and a description, what they do:
.smart - ; Stop being smart
</verb></tscreen>
See: <tt><ref id=".A16" name=".A16"></tt>,
<tt><ref id=".A8" name=".A8"></tt>,
<tt><ref id=".I16" name=".I16"></tt>,
<tt><ref id=".I8" name=".I8"></tt>
<sect1><tt>.STRAT</tt><label id=".STRAT"><p>