-

Changes

Jump to: navigation, search

Z80 Assembler Reference Manual

23,261 bytes added, 13:16, 28 July 2017
Created page with "== Introduction == The assembler incorporated in the HI-TECH C compiler system is a full-featured relocating macro assembler accept- ing Zilog mnemonics. These mnemonics a..."
== Introduction ==

The assembler incorporated in the HI-TECH C compiler
system is a full-featured relocating macro assembler accept-
ing Zilog mnemonics. These mnemonics and the syntax of the
Z80 assembly language are described in the "Z80 Assembly
Language Handbook" published by Zilog and are included at
the end of this manual as a reference. The assembler imple-
ments certain extensions to the operands allowed, and cer-
tain additional pseudo-ops, which are described here. The
assembler also accepts the additional opcodes for the Hita-
chi 64180 and Z180 processors.

== Usage ==

The assembler is named zas, and is invoked as follows:

ZAS options files ...


The files are one or more assembler source files which
will be assembled, but note that all the files are assembled
as one, not as separate files. To assemble separate files,
the assembler must be invoked on each file separately. The
options are zero or more options from the following list:

-N Ignore arithmetic overflow in expressions. The -N
option suppresses the normal check for arithmetic over-
flow. The assembler follows the "Z80 Assembly Language
Handbook" in its treatment of overflow, and in certain
instances this can lead to an error where in fact the
expression does evaluate to what the user intended.
This option may be used to override the overflow check-
ing.

-J Attempt to optimize jumps to branches. The -J option
will request the assembler to attempt to assemble jumps
and conditional jumps as relative branches where possi-
ble. Only those conditional jumps with branch
equivalents will be optimized, and jumps will only be
optimized to branches where the target is in branch
range. Note that the use of this option slows the
assembly down, due to the necessity for the assembler
to make an additional pass over the input code.

-U Treat undefined symbols as external. The -U option
will suppress error messages relating to undefined sym-
bols. Such symbols are treated as externals in any
case. The use of this option will not alter the object
code generated, but merely serves to suppress the error
messages.


-O_�f_�i_�l_�e
Place the object code in _�f_�i_�l_�e. The default object file
name is constructed from the name of the first source
file. Any suffix or file type (i.e. anything following
the rightmost dot ('.') in the name is stripped, and
the suffix .obj appended. Thus the command

ZAS file1.as file2.z80

will produce an object file called file1.obj. The use
of the -O option will override this default convention,
allowing the object file to be arbitrarily named. For
example:

ZAS -ox.obj file1.obj

will place the object code in x.obj.

-L_�l_�i_�s_�t
Place an assembly listing in the file _�l_�i_�s_�t, or on stan-
dard output if _�l_�i_�s_�t is null A listfile may be produced
with the -L option. If a file name is supplied to the
option, the list file will be created with that name,
otherwise the listing will be written to standard out-
put (i.e. the console). List file names such as CON:
and LST: are acceptable.

-W_�w_�i_�d_�t_�h
The listing is to be formatted for a printer of given
_�w_�i_�d_�t_�h The -W option specifies the width to which the
listing is to be formatted. E.g.

ZAS -Llst: -W80 x.as

will output a listing formatted for an 80 column
printer to the list device.

-C This options requests ZAS to produce cross reference
information in a file. The file will be called _�x_�x_�x.crf
where _�x_�x_�x is the base part of the first source file
name. It will then be necessary to run the CREF utility
to turn this information into a formatted listing.

== The Assembly Language

As mentioned above, the assembly language accepted by
zas is based on the Zilog mnemonics. You should have some
reference book such as the "Z80 Assembly Language Handbook".
Described below are those areas in which zas differs, or has
extensions, compared to the standard Zilog assembly
language.

=== Symbols ===

The symbols (labels) accepted by the assembler may be
of any length, and all characters are significant. The char-
acters used to form a symbol may be chosen from the upper
and lower case alphabetics, the digits 0-9, and the special

symbols underscore ('_'), dollar ('$') and question mark
('?'). The first character may not be numeric. Upper and
lower case are distinct. The following are all legal and
distinct symbols.

An_identifier
an_identifier
an_identifier1
$$$
?$_123455


Note that the symbol $ is special (representing the
current location) and may not be used as a label. Nor may
any opcode or pseudo-op mnemonic, register name or condition
code name. You should note the additional condition code
names described later.

==== Temporary Labels ====

The assembler implements a system of temporary labels,
useful for use within a localized section of code. These
help eliminate the need to generate names for labels which
are referenced only in the immediate vicinity of their
definition, for example where a loop is implemented.

A temporary label takes the form of a digit string. A
reference to such a label requires the same digit string,
plus an appended b or f to signify a backward or forward
reference respectively. Here is an example of the use of
such labels.

entry_point: ;This is referenced from far away
ld b,10
1: dec c
jr nz,2f ;if zero, branch forward to 2:
ld c,8
djnz 1b ;decrement and branch back to 1:
jr 1f ;this does not branch to the
;same label as the djnz
2: call fred ;get here from the jr nz,2f
1: ret ;get here from the jr 1f


The digit string may be any positive decimal number 0
to 65535. A temporary label value may be re-used any number
of times. Where a reference to e.g. 1b is made, this will
reference the closest label 1: found by looking backwards
from the current point in the file. Similarly 23f will
reference the first label 23: found by looking forwards from
the current point in the file.

=== Constants ===

Constants may be entered in one of the radices 2, 8, 10
or 16. The default is 10. Constants in the other radices may
be denoted by a trailing character drawn from the following
set:


Character Radix Name

B 2 binary
O 8 octal
Q 8 octal
o 8 octal
q 8 octal
H 16 hexadecimal
h 16 hexadecimal


Hexadecimal constants may also be specified in C style,
for example LD A,0x21. Note that a lower case b may not be
used to indicate a binary number, since 1b is a backward
reference to a temporary label 1:.

==== Character Constants ====

A character constant is a single character enclosed in
single quotes ('). Multi character constants may be used
only as an operand to a DEFM pseudo-op.

==== Floating Constants ====

A floating constant in the usual notation (e.g. 1.234
or 1234e-3) may be used as the operand to a DEFF pseudo-op.

==== Opcode Constants ====

Any z80 opcode may be used as a constant in an expres-
sion. The value of the opcode in this context will be the
byte that the opcode would have assembled to if used in the
normal way. If the opcode is a 2-byte opcode (CB or ED pre-
fix byte) only the second byte of the opcode will be used.
This is particularly useful when setting up jump vectors.
For example:

ld a,jp ;a jump instruction
ld (0),a ;0 is jump to warm boot
ld hl,boot ;done here
ld (1),hl


=== Expressions ===

Expressions are constructed largely as described in the
"Z80 Assembly Language Handbook".

==== Operators ====

The following operators may be used in expressions:

Operator Meaning

& Bitwise AND
* Multiplication
+ Addition
- Subtraction






HI-TECH C USER'S MANUAL Page 39

.and. Bitwise AND
.eq. Equality test
.gt. Signed greater than
.high. Hi byte of operand
.low. Low byte of operand
.lt. Signed less than
.mod. Modulus
.not. Bitwise complement
.or. Bitwise or
.shl. Shift left
.shr. Shift right
.ult. Unsigned less than
.ugt. Unsigned greater than
.xor. Exclusive or
/ Divison
< Signed less than
= Equality
> Signed greater than
^ Bitwise or


Operators starting with a dot "." should be delimited
by spaces, thus label .and. 1 is valid but label.and.1 is
not.

==== Relocatability ====

Zas produces object code which is relocatable; this
means that it is not necessary to specify assembly time
where the code is to be located in memory. It is possible to
do so, by use of the ORG pseudo-op, however the preferred
approach is to use program sections or psects. A psect is a
named section of the program, in which code or data may be
defined at assembly time. All parts of a psect will be
loaded contiguously into memory, even if they were defined
in separate files, or in the same file but separated by code
for another psect. For example, the following code will load
some executable instructions into the psect named text, and
some data bytes into the data psect.


psect text, global

alabel:
ld hl,astring
call putit
ld hl,anotherstring

psect data, global
astring:
defm 'A string of chars'
defb 0
anotherstring:
defm 'Another string'
defb 0

psect text

putit:
ld a,(hl)
or a
ret z
call outchar
inc hl
jr putit


Note that even though the two blocks of code in the
text psect are separated by a block in the data psect, the
two text psect blocks will be contiguous when loaded by the
linker. The instruction "ld hl,anotherstring" will fall
through to the label "putit:" during execution. The actual
location in memory of the two psects will be determined by
the linker. See the linker manual for information on how
psect addresses are determined.

A label defined in a psect is said to be relocatable,
that is, its actual memory address is not determined at
assembly time. Note that this does not apply if the label is
in the default (unnamed) psect, or in a psect declared abso-
lute (see the PSECT pseudo-op description below). Any
labels declared in an absolute psect will be absolute, that
is their address will be determined by the assembler.

With the version of ZAS supplied with version 7 or
later of HI-TECH C, relocatable expressions may be combined
freely in expressions. Older versions of ZAS allowed only
limited arithmetic on relocatable expressions.

=== Pseudo-ops ===

The pseudo-ops are based on those described in the "Z80
Assembly Language Handbook", with some additions.

==== DEFB, DB ====

This pseudo-op should be followed by a comma-separated
list of expressions, which will be assembled into sequential


byte locations. Each expression must have a value between
-128 and 255 inclusive. DB can be used as a synonym for
DEFB. Example:

DEFB 10, 20, 'a', 0FFH
DB 'hello world',13,10,0



==== DEFF ====

This pseudo-op assembles floating point constants into
32 bit HI-TECH C format floating point constants. For exam-
ple:

pi: DEFF 3.14159



==== DEFW ====

This operates in a similar fashion to DEFB, except that
it assembles expressions into words, without the value res-
triction. Example:

DEFW -1, 3664H, 'A', 3777Q



==== DEFS ====

Defs reserves memory locations without initializing
them. Its operand is an absolute expression, representing
the number of bytes to be reserved. This expression is
added to the current location counter. Note however that
locations reserved by DEFS may be initialized to zero by the
linker if the reserved locations are in the middle of the
program. Example:

DEFS 20h ;reserve 32 bytes of memory



==== EQU ====

Equ sets the value of a symbol on the left of EQU to
the expression on the right. It is illegal to set the value
of a symbol which is already defined. Example:

SIZE equ 46



==== DEFL ====

This is identical to EQU except that it may redefine
existing symbols. Example:


SIZE defl 48



==== DEFM ====

Defm should be followed by a string of characters,
enclosed in single quotes. The ASCII values of these char-
acters are assembled into successive memory locations.
Example:

DEFM 'A string of funny *@$ characters'



==== END ====

The end of an assembly is signified by the end of the
source file, or the END pseudo-op. The END pseudo-op may
optionally be followed by an expression which will define
the start address of the program. This is not actually use-
ful for CP/M. Only one start address may be defined per pro-
gram, and the linker will complain if there are more. Exam-
ple:

END somelabel



==== COND, IF, ELSE, ENDC ====

Conditional assembly is introduced by the COND pseudo-
op. The operand to COND must be an absolute expression. If
its value is false (zero) the code following the COND up to
the corresponding ENDC pseudo-op will not be assembled.
COND/ENDC pairs may be nested. IF may be used as a synonym
for COND. The ELSE pseudo operation may be included within
a COND/ENDC block, for example:

IF CPM
call 5
ELSE
call os_func
ENDC



==== ELSE ====

See COND.

==== ENDC ====

See COND.


==== ENDM ====

See MACRO.

==== PSECT ====

This pseudo-op allows specification of relocatable pro-
gram sections. Its arguments are a psect name, optionally
followed by a list of psect flags. The psect name is a sym-
bol constructed according to the same rules as for labels,
however a psect may have the same name as a label without
conflict. Psect names are recognized only after a PSECT
pseudo-op. The psect flags are as follows:

ABS Psect is absolute

GLOBAL Psect is global

LOCAL Psect is not global

OVRLD Psect is to be overlapped by linker

PURE Psect is to be read-only


If a psect is global, the linker will merge it with any
other global psects of the same name from other modules.
Local psects will be treated as distinct from any other
psect from another module. Psects are global by default.

By default the linker concatenates code within a psect
from various modules. If a psect is specified as OVRLD, the
linker will overlap each module's contribution to that
psect. This is particularly useful when linking modules
which initialize e.g. interrupt vectors.

The PURE flag instructs the linker that the psect is to
be made read-only at run time. The usefulness of this flag
depends on the ability of the linker to enforce the require-
ment. CP/M fails miserably in this regard.

The ABS flag makes a psect absolute. The psect will be
loaded at zero. This is useful for statically initializing
interrupt vectors and jump tables. Examples:


PSECT text, global, pure
PSECT data, global
PSECT vectors, ovrld



==== GLOBAL ====

Global should be followed by one more symbols (comma
separated) which will be treated by the assembler as global
symbols, either internal or external depending on whether
they are defined within the current module or not. Example:


GLOBAL label1, putchar, _printf



==== ORG ====

An ORG pseudo-op sets the current psect to the default
(absolute) psect, and the location counter to its operand,
which must be an absolute expression. Example:

ORG 100H



==== MACRO ====

This pseudo-op defines a macro. It should be either
preceded or followed by the macro name, then optionally fol-
lowed by a comma-separated list of formal parameters. The
lines of code following the MACRO pseudo-op up to the next
ENDM pseudo-op will be stored as the body of the macro. The
macro name may subsequently be used in the opcode part of an
assembler statement, followed by actual parameters. The text
of the body of the macro will be substituted at that point,
with any use of the formal parameters substituted with the
corresponding actual parameter. For example:

print MACRO string
psect data
999: db string,'$'
psect text
ld de,999b
ld c,9
call 5
ENDM



When used, this macro will expand to the 3 instructions
in the body of the macro, with the actual parameters substi-
tuted for func and arg. Thus

print 'hello world'


expands to

psect data
999: db 'hello world','$'
psect text
ld de,999b
ld c,9
call 5



Macro arguments can be enclosed in angle brackets ('<'
and '>') to pass arbitrary text including delimiter charac-
ters like commas as a single argument. For example, suppose
you wanted to use the print macro defined above to print a
string which includes the carriage return and linefeed char-
acters. The macro invocation:

print 'hello world',13,10


would fail because 13 and 10 are treated as extra arguments
and ignored. In order to pass a string which includes commas
as a single argument, you could write:

print <'hello world',13,10>


which would cause the text 'hello world',13,10 to be passed
through as a single argument. This would expand to the fol-
lowing code:

psect data
999: db 'hello world',13,10,'$'
psect text
ld de,999b
ld c,9
call 5



ZAS supports two forms of macro declaration for compa-
tibility with older versions of ZAS and other Z80 assem-
blers. The macro name may be declared either in the label
field before the MACRO pseudo-op, or in the operand field
after the MACRO pseudo-op. Thus these two MACRO declara-
tions are equivalent:

bdos MACRO func,arg
ld de,arg
ld c,func
call 5
ENDM

and

MACRO bdos,func,arg
ld de,arg
ld c,func
call 5
ENDM



==== LOCAL ====

The LOCAL pseudo-op allows unique labels to be defined
for each expansion of a macro. Any symbols listed after the
LOCAL directive will have a unique assembler-generated sym-
bol substituted for them when the macro is expanded. For


example:

copy MACRO source,dest,count
LOCAL nocopy
push af
push bc
ld bc,source
ld a,b
or c
jr z,nocopy
push de
push hl
ld de,dest
ld hl,source
ldir
pop hl
pop de
nocopy: pop bc
pop af
ENDM


when expanded will include a unique assembler generated
label in place of nocopy. For example, copy
(recptr),buf,(recsize) will expand to:

push af
push bc
ld bc,(recsize)
ld a,b
or c
jr z,??0001
push de
push hl
ld de,buf
ld hl,(recptr)
ldir
pop hl
pop de
??0001: pop bc
pop af

if invoked a second time, the label nocopy would expand to
??0002.

==== REPT ====

The REPT pseudo-op defines a temporary macro which is
then expanded a number of times, as determined by its argu-
ment. For example:

REPT 3
ld (hl),0
inc hl
ENDM


will expand to



ld (hl),0
inc hl
ld (hl),0
inc hl
ld (hl),0
inc hl



=== IRP and IRPC ===

The IRP and IRPC directives are similar to REPT, how-
ever instead of repeating the block a fixed number of times
it is repeated once for each member of an argument list. In
the case of IRP the list is a conventional macro argument
list, in the case of IRPC it is successive characters from a
string. For example:

IRP string,<'hello world',13,10>,'arg2'
LOCAL str
psect data
str: db string,'$'
psect text
ld c,9
ld de,str
call 5
ENDM


would expand to

psect data
??0001: db 'hello world',13,10,'$'
psect text
ld c,9
ld de,??0001
call 5
psect data
??0002: db 'arg2','$'
psect text
ld c,9
ld de,??0002
call 5


Note the use of LOCAL labels and angle brackets in the same
manner as with conventional macros.

IRPC is best demonstrated using the following example:

IRPC char,ABC
ld c,2
ld e,'char'
call 5
ENDM


will expand to:

ld c,2
ld e,'A'
call 5
ld c,2
ld e,'B'
call 5
ld c,2
ld e,'C'
call 5



=== Extended Condition Codes ===

The assembler recognizes several additional condition
codes. These are:

_________________________________________________
| Code| Equivalent| Meaning |
| alt | m | Arithmetic less than |
| llt | c | Logical less than |
| age | p | Arithmetic greater or equal|
| lge | nc | Logical greater or equal |
| di | | Use after ld a,i for test-|
| ei | | ing state of interrupt|
| | | enable flag - enabled or|
|�|______�|�|_____________�|�|__d�_i�_s�_a�_b�_l�_e�_d�__r�_e�_s�_p�_e�_c�_t�_i�_v�_e�_l�_y�_.�_______�|�|


12.4. Assembler Directives

An assembler directive is a line in the source file
which produces no code, but rather which modifies the
behaviour of the assembler. Each directive is recognized by
the presence of an asterisk in the first column of the line,
followed immediately by a word, only the first character of
which is looked at. the line containing the directive itself
is never listed. The directives are:

*Title
Use the text following the directive as a title for the
listing.

*Heading
Use the text following the directive as a subtitle for
the listing; also causes an *Eject.

*List
May be followed by ON or OFF to turn listing on or off
respectively. Note that this directive may be used
inside a macro or include file to control listing of
that macro or include file. The previous listing state
will be restored on exit from the macro or include
file.


*Include
The file named following the directive will be included
in the assembly at that point.

*Eject
A new page will be started in the listing at that
point. A form feed character in the source will have
the same effect.

Some examples of the use of these directives:


*Title Widget Control Program
*Heading Initialization Phase

*Include widget.i



== Diagnostics ==

An error message will be written on the standard error
stream for each error encountered in the assembly. This mes-
sage identifies the file name and line number and describes
the error. In addition the line in the listing where the
error occurred will be flagged with a single character to
indicate the error. The characters and the corresponding
messages are:



A: Absolute expression required

B: Bad arg to *L
Bad arg to IM
Bad bit number
Bad character constant
Bad jump condition

D: Directive not recognized
Digit out of range

E: EOF inside conditional
Expression error

G: Garbage after operands
Garbage on end of line

I: Index offset too large

J: Jump target out of range

L: Lexical error

M: Multiply defined symbol

O: Operand error

P: Phase error
Psect may not be local and global

R: Relocation error

S: Size error
Syntax error

U: Undefined symbol
Undefined temporary label
Unterminated string


12.6. Z80/Z180/64180 Instruction Set

The remainder of this chapter is devoted to a complete
instruction set listing for the Z80, Z180, 64180 and NSC800
processors. The Z180 and 64180 will execute all Z80
instructions, although the timing is different.

Navigation menu