| back |  | Last regenerated: 2022-04-20 17:31:36 kio

# zasm - Z80 Assembler – Version 4.4

# Expressions

[<prev] [next>]

| ### Numeric expressions The assembler has an Expressions 8080 Assembler: Expressions expression evaluator which supports various formats for numbers and operators with priority order. You may also use brackets, but don't start an Expressions 8080 Assembler: Expressions expression for an immediate value with an opening bracket. The assembler thinks that an Expressions 8080 Assembler: Expressions expression which starts with an opening bracket indicates direct memory addressing. Assembler directives: #if, #elif, #else, #endif Pseudo instructions: if, endif If you really need to start an immediate value Expressions 8080 Assembler: Expressions expression with brackets, precede it with the '+' monadic operator or a hash '#'. #### Numeric literals Numeric literals are the 'numbers' in an Expressions 8080 Assembler: Expressions expression. They can be written in a multitude of formats:
    12345    decimal number
    12345d   decimal number
    $1234    hexadecimal number
    &1234    hexadecimal number  (since 4.3.4)
    1234h    hexadecimal number
    0x1234   hexadecimal number
    %1010    binary number
    1010b    binary number
    0b1010   binary number
    'a'      character literal
All number literals may be prefixed by a sign, either '+' or '-', which is actually handled as a monadic operator internally. A character literal must be either a 7-bit ascii character or it is converted from utf-8. (note: all source files are expected to be either 7-bit ascii or utf-8 encoded.) Character literals are translated to the target system's character Pseudo instructions: defl, set and '=' Labels: SET set Assembler directives: #if, #elif, #else, #endif Pseudo instructions: if, endif if the assembler directive '#charset' was used to define one. Else the character must be in range 0 to 255. Assembler directives: #if, #elif, #else, #endif Pseudo instructions: if, endif If the character is not available in the target character Pseudo instructions: defl, set and '=' Labels: SET set the assembler reports an error. Assembler directives: #if, #elif, #else, #endif Pseudo instructions: if, endif If the values are stored with 'defb' or similar, all values must fit in a byte each. Then characters like '€' will raise an error. Assembler directives: #if, #elif, #else, #endif Pseudo instructions: if, endif If they are stored with 'defw' then '€' will be ok. #### Labels Of course Pseudo instructions: Label definition Numeric expressions: Labels 8080 Assembler: Labels labels can be used in Expressions 8080 Assembler: Expressions expressions. Pseudo instructions: Label definition Numeric expressions: Labels 8080 Assembler: Labels Labels may refer to Assembler directives: #local, #endlocal, .local and .endlocal Pseudo instructions: #local, #endlocal, .local and .endlocal Including C Source Files: #local, #endlocal, .local and .endlocal local or global symbols, depending on whether they were defined inside the current Assembler directives: #local, #endlocal, .local and .endlocal Pseudo instructions: #local, #endlocal, .local and .endlocal Including C Source Files: #local, #endlocal, .local and .endlocal#local context (Assembler directives: #if, #elif, #else, #endif Pseudo instructions: if, endif if any) or outside any Assembler directives: #local, #endlocal, .local and .endlocal Pseudo instructions: #local, #endlocal, .local and .endlocal Including C Source Files: #local, #endlocal, .local and .endlocal local context. See chapter 'Assembler directives: #local, #endlocal, .local and .endlocal Pseudo instructions: #local, #endlocal, .local and .endlocal Including C Source Files: #local, #endlocal, .local and .endlocal#local' for more information. ##### Predefined labels The assembler defines Pseudo instructions: Label definition Numeric expressions: Labels 8080 Assembler: Labels labels which can be tested with 'defined(NAME)' to test Assembler directives: #if, #elif, #else, #endif Pseudo instructions: if, endif if certain Differences from v3 to v4: Command line options Command Line Options Command Line Options: Command line options command line options are Pseudo instructions: defl, set and '=' Labels: SET set. The handling of these predefined labels changed slightly in version 4.3.4. _z80_ This Pseudo instructions: Label definition Numeric expressions: Labels 8080 Assembler: Labels label is defined Assembler directives: #if, #elif, #else, #endif Pseudo instructions: if, endif if option --Command Line Options: --z80 Pseudo instructions: .z80, .z180 and .8080 Targets: #target Z80 z80 is Pseudo instructions: defl, set and '=' Labels: SET set on the command line or after the .Command Line Options: --z80 Pseudo instructions: .z80, .z180 and .8080 Targets: #target Z80 z80 Pseudo instructions 8080 Assembler: 8080 pseudo instructions pseudo instruction. It is not Pseudo instructions: defl, set and '=' Labels: SET set Assembler directives: #if, #elif, #else, #endif Pseudo instructions: if, endif if target Command Line Options: --z80 Pseudo instructions: .z80, .z180 and .8080 Targets: #target Z80 z80 is used by default. _z180_ This Pseudo instructions: Label definition Numeric expressions: Labels 8080 Assembler: Labels label is defined Assembler directives: #if, #elif, #else, #endif Pseudo instructions: if, endif if option --Command Line Options: --z180 Pseudo instructions: .z80, .z180 and .8080 z180 is Pseudo instructions: defl, set and '=' Labels: SET set on the command line or after the .Command Line Options: --z180 Pseudo instructions: .z80, .z180 and .8080 z180 Pseudo instructions 8080 Assembler: 8080 pseudo instructions pseudo instruction. _8080_ This Pseudo instructions: Label definition Numeric expressions: Labels 8080 Assembler: Labels label is defined Assembler directives: #if, #elif, #else, #endif Pseudo instructions: if, endif if option --8080 is Pseudo instructions: defl, set and '=' Labels: SET set on the command line or after the .8080 Pseudo instructions 8080 Assembler: 8080 pseudo instructions pseudo instruction. It is not Pseudo instructions: defl, set and '=' Labels: SET set Assembler directives: #if, #elif, #else, #endif Pseudo instructions: if, endif if target 8080 is used by default. _ixcbr2_ This Pseudo instructions: Label definition Numeric expressions: Labels 8080 Assembler: Labels label is defined Assembler directives: #if, #elif, #else, #endif Pseudo instructions: if, endif if the option '--Command Line Options: --ixcbxh, .ixcbxh, _ixcbxh_ --ixcbr2, .ixcbr2, _ixcbr2_ Commands for command line options: --ixcbxh, .ixcbxh, _ixcbxh_ --ixcbr2, .ixcbr2, _ixcbr2_ixcbr2' was Pseudo instructions: defl, set and '=' Labels: SET set on the command line or after the Pseudo instructions 8080 Assembler: 8080 pseudo instructions pseudo instruction '.Command Line Options: --ixcbxh, .ixcbxh, _ixcbxh_ --ixcbr2, .ixcbr2, _ixcbr2_ Commands for command line options: --ixcbxh, .ixcbxh, _ixcbxh_ --ixcbr2, .ixcbr2, _ixcbr2_ixcbr2'. _ixcbxh_ This Pseudo instructions: Label definition Numeric expressions: Labels 8080 Assembler: Labels label is defined Assembler directives: #if, #elif, #else, #endif Pseudo instructions: if, endif if the option '--Command Line Options: --ixcbxh, .ixcbxh, _ixcbxh_ --ixcbr2, .ixcbr2, _ixcbr2_ Commands for command line options: --ixcbxh, .ixcbxh, _ixcbxh_ --ixcbr2, .ixcbr2, _ixcbr2_ixcbxh' was Pseudo instructions: defl, set and '=' Labels: SET set on the command line or after the Pseudo instructions 8080 Assembler: 8080 pseudo instructions pseudo instruction '.Command Line Options: --ixcbxh, .ixcbxh, _ixcbxh_ --ixcbr2, .ixcbr2, _ixcbr2_ Commands for command line options: --ixcbxh, .ixcbxh, _ixcbxh_ --ixcbr2, .ixcbr2, _ixcbr2_ixcbxh'. Note, that source line 1 is also used to Pseudo instructions: defl, set and '=' Labels: SET set Differences from v3 to v4: Command line options Command Line Options Command Line Options: Command line options command line options Assembler directives: #if, #elif, #else, #endif Pseudo instructions: if, endif if it starts with a shebang "#!". #### '$' and '.' (code address) '$' and '.' are used to get the value of the current logical code position. It always refers to the start of a statement, e.g. to the first byte of an instruction or the postition of the first byte in a 'defb' instruction:
    foo:    djnz $      ; jump to foo
    bar:    defb $,$,$  ; stores 3x the value of bar
'.' is recognized for old sources only, do not use it in new code. #### '$$' (physical code address) '$$' refers to the physical code position. For an explanation of 'physical' vs. 'logical' code position see instruction '.phase'. #### __line__ Inserts the current line number. E.g.:
    .Pseudo instructions: macro, .macro, endm and .endm
    8080 pseudo instructions: MACROmacro abort
        ld  de, __line__
        jp  abort
    .Pseudo instructions: macro, .macro, endm and .endm
    Pseudo instructions: rept, .rept, endm and .endmendm
#### hi() and lo() hi(NN) gets the high byte of a 2-byte word. Similar to `NN >> 8`. lo(NN) gets the low byte of a 2-byte word. Similar to `NN & 0xFF`. Function names must be lowercase except Assembler directives: #if, #elif, #else, #endif Pseudo instructions: if, endif if --Command Line Options: --casefold, .casefold Commands for command line options: --casefold, .casefold Label definition: --casefold casefold or --asm8080 is selected. E.g. Assembler directives: #if, #elif, #else, #endif Pseudo instructions: if, endif if you have a table which must be located completely inside a page, then you can automatically raise the table base Assembler directives: #if, #elif, #else, #endif Pseudo instructions: if, endif if the table would cross a page boundary: (note: use a calculated Expressions 8080 Assembler: Expressions expression for .align Assembler directives: #if, #elif, #else, #endif Pseudo instructions: if, endif if the code address is not yet valid in pass 1.)
    .align hi($) != hi($+table_size-1)  ? 256 : 1
    table:  Pseudo instructions: defs, ds, .ds, .block, .blkb and data
    8080 pseudo instructions: DSds  table_size
#### min() and max() min(N1,N2) gets the value of the smaller of two values. max(N1,N2) gets the value of the bigger of two values. Function names must be lowercase except Assembler directives: #if, #elif, #else, #endif Pseudo instructions: if, endif if --Command Line Options: --casefold, .casefold Commands for command line options: --casefold, .casefold Label definition: --casefold casefold or --asm8080 is selected. You can also pass more than 2 arguments to min and max. e.g. calculate size for a scratch pad:
    scratch: Pseudo instructions: defs, ds, .ds, .block, .blkb and data
    8080 pseudo instructions: DSds max(fp_scratch,txt_scratch,gfx_scratch)
#### sin() and cos() sin(ANGLE,N2,N3) calculate the sinus of an angle. cos(ANGLE,N2,N3) calculate the cosinus of an angle. Function names must be lowercase except Assembler directives: #if, #elif, #else, #endif Pseudo instructions: if, endif if --Command Line Options: --casefold, .casefold Commands for command line options: --casefold, .casefold Label definition: --casefold casefold or --asm8080 is selected. The angle is scaled according to argument N2, which defines the value for a full circle. The result is scaled with argument N3. E.g. to generate a sine table with 256 values scaled to range ±127 use it in conjuction with Pseudo instructions 8080 Assembler: 8080 pseudo instructions pseudo instruction .Pseudo instructions: rept, .rept, endm and .endm 8080 pseudo instructions: REPT rept:
    angle = 0
    .Pseudo instructions: rept, .rept, endm and .endm
    8080 pseudo instructions: REPTrept 256
        Pseudo instructions: defb, db, .db and .byte
    8080 pseudo instructions: DBdb  sin(angle,256,127)
    angle = angle +1
    .Pseudo instructions: macro, .macro, endm and .endm
    Pseudo instructions: rept, .rept, endm and .endmendm
#### opcode() Function 'opcode(…)' can be used to get the major byte of an opcode. This is useful Assembler directives: #if, #elif, #else, #endif Pseudo instructions: if, endif if you want to poke an opcode byte into some self-modifying portions of code or to skip over the first 1-byte opcode of a second entry point to a subroutine with `Pseudo instructions: defb, db, .db and .byte 8080 pseudo instructions: DBdb opcode(cp a,N)`, which is faster and shorter than `jr $+3`. The 'major byte' is the first byte for most opcodes, the byte after 0xCB, 0xED, 0xDD or 0xFD for most others or the 4th byte of a 0xDD 0xCB or 0xFD 0xCB instruction. (note: 0xDD and 0xFD are the index register prefixes.) 'opcode' must be lowercase except Assembler directives: #if, #elif, #else, #endif Pseudo instructions: if, endif if --Command Line Options: --casefold, .casefold Commands for command line options: --casefold, .casefold Label definition: --casefold casefold or --asm8080 is selected. All opcodes for the Command Line Options: --z80 Pseudo instructions: .z80, .z180 and .8080 Targets: #target Z80 Z80 cpu as well as the additional opcodes of the Command Line Options: --z180 Pseudo instructions: .z80, .z180 and .8080 Z180 cpu are supported. Assembler directives: #if, #elif, #else, #endif Pseudo instructions: if, endif If 8080 assembler is selected with --asm8080 then 8080 assembler mnemonics must be used. Opcode names follow these rules: • names should be in lower case • arguments can be: • a register name: af, af', bc, de, hl, sp, ix, iy, pc, a, f, b, c, d, e, h, l, r, i for xh, xl, yh and yl simply use h and l. • a flag name: z, nz, c, nc, po, pe, m, p • register indirect: (bc), (de), (hl), (sp), (c) • index register with offset: (ix+N), (iy+N) and variants: (ix+dis), (iy+dis), (ix+offs), (iy+offs) • immediate value and memory: N, NN, (N), (NN) and variants: dis, offs • fixed values: 0, 1, 2, 3, 4, 5, 6, 7, 8, 16, .. 56 and variants: $00, $08 .. $38, 0x00 … 0x38, 00h .. 38h E.g.:
    Pseudo instructions: defb, db, .db and .byte
    8080 pseudo instructions: DBdb opcode(nop)              just the name for opcodes without argument
    Pseudo instructions: defb, db, .db and .byte
    8080 pseudo instructions: DBdb opcode(ld a,b)           name plus arguments which go into the opcode
    Pseudo instructions: defb, db, .db and .byte
    8080 pseudo instructions: DBdb opcode(bit 3,(hl))       '3' is part of the opcode!
    Pseudo instructions: defb, db, .db and .byte
    8080 pseudo instructions: DBdb opcode(rst 8)
    Pseudo instructions: defb, db, .db and .byte
    8080 pseudo instructions: DBdb opcode(ld a,N)
    Pseudo instructions: defb, db, .db and .byte
    8080 pseudo instructions: DBdb opcode(ld a,(NN))
    Pseudo instructions: defb, db, .db and .byte
    8080 pseudo instructions: DBdb opcode(ld a,(bc))
    Pseudo instructions: defb, db, .db and .byte
    8080 pseudo instructions: DBdb opcode(ld a,(ix+offs))   you can use 'ld a,(hl)' here as well
    Pseudo instructions: defb, db, .db and .byte
    8080 pseudo instructions: DBdb opcode(jr c,NN)
    Pseudo instructions: defb, db, .db and .byte
    8080 pseudo instructions: DBdb opcode(ex af,af')
#insert: Examples: #assert: Example: incbin: Examples: #assert: Example:Examples:
    ; jump over an opcode:
        Pseudo instructions: defb, db, .db and .byte
    8080 pseudo instructions: DBdb  opcode(cp a,N)  ; shorter and faster than 'jr'
    1$: ld  a,e

    ; self modifying code:
        ld  (opcode1), opcode(inc l)
        ld  (opcode2), opcode(inc h)
#### defined(LABEL) This results in 0 or 1 depending on whether the named Pseudo instructions: Label definition Numeric expressions: Labels 8080 Assembler: Labels label is already defined at this position in source. 'defined' must be lowercase except Assembler directives: #if, #elif, #else, #endif Pseudo instructions: if, endif if --Command Line Options: --casefold, .casefold Commands for command line options: --casefold, .casefold Label definition: --casefold casefold or --asm8080 is selected. note: use of this function in a Assembler directives: #local, #endlocal, .local and .endlocal Pseudo instructions: #local, #endlocal, .local and .endlocal Including C Source Files: #local, #endlocal, .local and .endlocal local context may malfunction Assembler directives: #if, #elif, #else, #endif Pseudo instructions: if, endif if a Assembler directives: #local, #endlocal, .local and .endlocal Pseudo instructions: #local, #endlocal, .local and .endlocal Including C Source Files: #local, #endlocal, .local and .endlocal local name of this name is defined after this test. E.g.:
    #if defined(logline)
        ld  hl, __line__
        call    logline
    #endif
#### required(LABEL) This results in 0 or 1 depending on whether the named Pseudo instructions: Label definition Numeric expressions: Labels 8080 Assembler: Labels label was used but not yet defined at this position in source. E.g.:
    #if required(mul_hl_de)
    Assembler directives: #include
    Including C Source Files: #include#include "lib/mul_hl_de.s"
    #endif
#### target(NAME) Test whether the named Assembler directives: #target Including C Source Files: #target#target is selected. Use this Assembler directives: #if, #elif, #else, #endif Pseudo instructions: if, endif if you made it selectable for some reason in your source. Result is 0 or 1. Possible targets are: ROM, BIN, Command Line Options: --z80 Pseudo instructions: .z80, .z180 and .8080 Targets: #target Z80 Z80, SNA, TAP, TAPE, O, P, 80, 81, P81 and ACE. 'target' must be lowercase except Assembler directives: #if, #elif, #else, #endif Pseudo instructions: if, endif if --Command Line Options: --casefold, .casefold Commands for command line options: --casefold, .casefold Label definition: --casefold casefold or --asm8080 is selected. #insert: Examples: #assert: Example: incbin: Examples: #assert: Example:Example:
    ; include a tape header Assembler directives: #if, #elif, #else, #endif
    Pseudo instructions: if, endifif Assembler directives: #target
    Including C Source Files: #target#target is Pseudo instructions: defl, set and '='
    Labels: SETset to TAPE:
    #if target(TAPE)
    Assembler directives: #code
    Including C Source Files: #code#code CODE_HEADER, 0, 17, headerflag
        defb    3, "mcode     "
        defw    code_size,load_address,0
    #endif
#### segment(NAME) Test whether the named segment is the currently selected Assembler directives: #code Including C Source Files: #code#code or Assembler directives: #data Including C Source Files: #data#data segment. Result is 0 or 1. 'segment' must be lowercase except Assembler directives: #if, #elif, #else, #endif Pseudo instructions: if, endif if --Command Line Options: --casefold, .casefold Commands for command line options: --casefold, .casefold Label definition: --casefold casefold or --asm8080 is selected. #insert: Examples: #assert: Example: incbin: Examples: #assert: Example:Example:
    ; don't include 'ret' opcode Assembler directives: #if, #elif, #else, #endif
    Pseudo instructions: if, endifif this is in boot code:
    #if !segment(GSINIT)
        ret
    #endif
#### Operators The following operators are recognized and listed in order of precedence:
    brackets            ( ... )
    monadic operators   + - ~ !         plus sign, minus sign, 2's complement, negation
    shifting            << >>           shift left or right; left operand is target
                        shl shr
    bit masking         & | ^           bitwise and, or, xor
                        and or xor
    mult/div            * / %           multiply, divide, remainder ('\' is no longer recognized)
    add/sub             + -             add, subtract
    comparisions        > < >= <= = <>  greater than etc.; result is 0 or 1
                        == != eq ne
                        gt lt ge le
    boolean             && ||           pruning
    selector            ? :             pruning
Since 4.0.21: The backslash '\' is no longer recognized as the remainder operation. The backslash is now used to separate multiple opcodes in one line. Up to 4.0.22: The first argument of a pruning operator must be valid in pass 1. Since 4.0.23: The first argument of a pruning operator should be valid in pass 1. Assembler directives: #if, #elif, #else, #endif Pseudo instructions: if, endif If it isn't, then both sub Expressions 8080 Assembler: Expressions expressions are evaluated in pass 1. Assembler directives: #if, #elif, #else, #endif Pseudo instructions: if, endif If there is an undefined Pseudo instructions: Label definition Numeric expressions: Labels 8080 Assembler: Labels label referenced in a later pruned path it will be still required and the assembler will report it as undefined. Assembler directives: #if, #elif, #else, #endif Pseudo instructions: if, endif If you used Differences from v3 to v4: Command line options Command Line Options Command Line Options: Command line options command line option '--Command Line Options: --flatops, .flatops Commands for command line options: --flatops, .flatops flatops' then all operators are evaluated strictly from left to right. ### String expressions
        defm "<some text>" [ + <value> ]
        defm '<some text>' [ + <value> ]
Strings cannot be stored in Pseudo instructions: Label definition Numeric expressions: Labels 8080 Assembler: Labels labels and therefore most string operations make no sense. Strings can just occur as a string literal, either enclosed in a pair of ''' or a pair of '"'. Whichever character is chosen it must not occur inside the string. Note: special characters in string cannot be escaped with '\'. This syntax was (probably) invented later for the programming language 'C'.
        defm "say 'Hello!'",0
        defm 'say "Hello!"',0
Characters in the string are translated to the target system's character Pseudo instructions: defl, set and '=' Labels: SET set Assembler directives: #if, #elif, #else, #endif Pseudo instructions: if, endif if the assembler directive '#charset' was used to define one. Else the characters must be in range 0 to 255. Assembler directives: #if, #elif, #else, #endif Pseudo instructions: if, endif If the character is not available in the target character Pseudo instructions: defl, set and '=' Labels: SET set the assembler reports an error. The last character of a string may be modified by a numeric operation, most commonly used is setting bit 7 of the last character:
        defm "foobar"+0x80
The following operators are allowed: '+', '-', '&', '|', '^'. There are 4 predefined strings available in the 'defm' instruction: __date__, __time__, __file__ and __line__. |

[<prev] [top] [next>]