All expressions are evaluated with (at least) 32 bit precision. An expression may contain constant values and any combination of internal and external symbols. Expressions that cannot be evaluated at assembly time are stored inside the object file for evaluation by the linker. Expressions referencing imported symbols must always be evaluated by the linker.
Sometimes, the assembler must know about the size of the value that is the result of an expression. This is usually the case, if a decision has to be made, to generate a zero page or an absolute memory references. In this case, the assembler has to make some assumptions about the result of an expression:
Note: If the assembler is not able to evaluate the expression at assembly time, the linker will evaluate it and check for range errors as soon as the result is known.
In the context of a boolean expression, any non zero value is evaluated as
true, any other value to false. The result of a boolean expression is 1 if
it's true, and zero if it's false. There are boolean operators with extreme
low precedence with version 2.x (where x > 0). The .AND
and .OR
operators are shortcut operators. That is, if the result of the expression is
already known, after evaluating the left hand side, the right hand side is
not evaluated.
Sometimes an expression must evaluate to a constant without looking at any
further input. One such example is the
.IF
command
that decides if parts of the code are assembled or not. An expression used in
the .IF
command cannot reference a symbol defined later, because the
decision about the .IF
must be made at the point when it is read. If the
expression used in such a context contains only constant numerical values,
there is no problem. When unresolvable symbols are involved it may get harder
for the assembler to determine if the expression is actually constant, and it
is even possible to create expressions that aren't recognized as constant.
Simplifying the expressions will often help.
In cases where the result of the expression is not needed immediately, the assembler will delay evaluation until all input is read, at which point all symbols are known. So using arbitrary complex constant expressions is no problem in most cases.
Available operators sorted by precedence:
Op | Description | Precedence |
Builtin string functions | 0 | |
Builtin pseudo variables | 1 | |
Builtin pseudo functions | 1 | |
+ | Unary plus | 1 |
- | Unary minus | 1 |
~ | Unary bitwise not | 1 |
.BITNOT | Unary bitwise not | 1 |
< | Low byte operator | 1 |
> | High byte operator | 1 |
^ | Bank byte operator | 1 |
* | Multiplication | 2 |
/ | Division | 2 |
.MOD | Modulo operation | 2 |
& | Bitwise and | 2 |
.BITAND | Bitwise and | 2 |
^ | Bitwise xor | 2 |
.BITXOR | Bitwise xor | 2 |
<< | Shift left operator | 2 |
.SHL | Shift left operator | 2 |
>> | Shift right operato | r |
.SHR | Shift right operator | 2 |
+ | Binary plus | 3 |
- | Binary minus | 3 |
| | Binary or | 3 |
.BITOR | Binary or | 3 |
= | Compare operation (equal) | 4 |
<> | Compare operation (not equal) | 4 |
< | Compare operation (less) | 4 |
> | Compare operation (greater) | 4 |
<= | Compare operation (less or equal) | 4 |
>= | Compare operation (greater or equal) | 4 |
&& | Boolean and | 5 |
.AND | Boolean and | 5 |
.XOR | Boolean xor | 5 |
|| | Boolean or | 6 |
.OR | Boolean or | 6 |
! | Boolean not | 7 |
.NOT | Boolean not | 7 |
To force a specific order of evaluation, braces may be used as usual.