-

Difference between revisions of "Z80 Assembler Reference Manual"

From HI-TECH C for CP/M Fan WIKI(EN)
Jump to: navigation, search
(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...")
 
Line 2: Line 2:
  
 
The assembler incorporated in the  HI-TECH  C  compiler
 
The assembler incorporated in the  HI-TECH  C  compiler
system is a full-featured relocating macro assembler accept-
+
system is a full-featured relocating macro assembler accepting Zilog mnemonics. These mnemonics and the syntax  of  the
ing Zilog mnemonics. These mnemonics and the syntax  of  the
 
 
Z80  assembly  language  are  described in the "Z80 Assembly
 
Z80  assembly  language  are  described in the "Z80 Assembly
 
Language Handbook" published by Zilog and  are  included  at
 
Language Handbook" published by Zilog and  are  included  at
the  end of this manual as a reference. The assembler imple-
+
the  end of this manual as a reference. The assembler implements certain extensions to the operands allowed,  and  certain additional  pseudo-ops, which are described here.  The
ments certain extensions to the operands allowed,  and  cer-
+
assembler also accepts the additional opcodes for the  Hitachi 64180 and Z180 processors.
tain additional  pseudo-ops, which are described here.  The
 
assembler also accepts the additional opcodes for the  Hita-
 
chi 64180 and Z180 processors.
 
  
 
== Usage ==
 
== Usage ==
Line 25: Line 21:
 
options are zero or more options from the following list:
 
options are zero or more options from the following list:
  
-N   Ignore arithmetic  overflow  in  expressions.  The  -N
+
;-N
option suppresses the normal check for arithmetic over-
+
:Ignore arithmetic  overflow  in  expressions.  The  -N option suppresses the normal check for arithmetic overflow. 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 checking.
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
+
;-J
will request the assembler to attempt to assemble jumps
+
: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 possible.  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.
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
+
;-U
will suppress error messages relating to undefined sym-
+
:Treat undefined symbols as  external.  The  -U  option will suppress error messages relating to undefined symbols. 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.
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
+
;-O<strong>file</strong>
Place the object code in _�f_�i_�l_�e.  The default object file
+
:Place the object code in <strong>file</strong>.  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
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
+
ZAS file1.as file2.z80
  
will produce an object file called file1.obj.  The  use
+
: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:
of the -O option will override this default convention,
 
allowing the object file to be arbitrarily  named.  For
 
example:
 
  
ZAS -ox.obj file1.obj
+
ZAS -ox.obj file1.obj
  
will place the object code in x.obj.
+
:will place the object code in x.obj.
  
-L_�l_�i_�s_�t
+
;-L<strong>list</strong>
Place an assembly listing in the file _�l_�i_�s_�t, or on stan-
+
:Place an assembly listing in the file <strong>list</strong>, or on standard output if <strong>list</strong> 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  output (i.e.  the  console). List file names such as CON: and LST: are acceptable.
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
+
;-W<strong>width</strong>
The listing is to be formatted for a printer  of  given
+
:The listing is to be formatted for a printer  of  given <strong>width</strong> The  -W  option specifies the width to which the listing is to be formatted. E.g.
_�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
+
ZAS -Llst: -W80 x.as
  
will output  a  listing  formatted  for  an  80  column
+
:will output  a  listing  formatted  for  an  80  column printer to the list device.
printer to the list device.
 
  
-C   This options requests ZAS to  produce  cross  reference
+
;-C
information  in a file. The file will be called _�x_�x_�x.crf
+
:This options requests ZAS to  produce  cross  reference information  in a file. The file will be called <strong>xxx</strong>.crf where <strong>xxx</strong> 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.
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
+
== The Assembly Language ==
  
As mentioned above, the assembly language  accepted  by
+
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.
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 ===
 
=== Symbols ===
  
 
The symbols (labels) accepted by the assembler  may  be
 
The symbols (labels) accepted by the assembler  may  be
of any length, and all characters are significant. The char-
+
of any length, and all characters are significant. The characters used to form a symbol may be chosen  from  the  upper
acters used to form a symbol may be chosen  from  the  upper
 
 
and  lower case alphabetics, the digits 0-9, and the special
 
and  lower case alphabetics, the digits 0-9, and the special
  
Line 116: Line 70:
 
distinct symbols.
 
distinct symbols.
  
An_identifier
+
An_identifier
an_identifier
+
an_identifier
an_identifier1
+
an_identifier1
$$$
+
$$$
?$_123455
+
?$_123455
 
 
  
 
Note that the symbol $  is  special  (representing  the
 
Note that the symbol $  is  special  (representing  the
Line 143: Line 96:
 
such labels.
 
such labels.
  
entry_point:  ;This is referenced from far away
+
entry_point:  ;This is referenced from far away
ld  b,10
+
ld  b,10
1:  dec  c
+
1:  dec  c
jr  nz,2f ;if zero, branch forward to 2:
+
jr  nz,2f ;if zero, branch forward to 2:
ld  c,8
+
ld  c,8
djnz 1b    ;decrement and branch back to 1:
+
djnz 1b    ;decrement and branch back to 1:
jr  1f    ;this does not branch to the
+
jr  1f    ;this does not branch to the
;same label as the djnz
+
;same label as the djnz
2:  call fred  ;get here from the jr nz,2f
+
2:  call fred  ;get here from the jr nz,2f
1:  ret        ;get here from the jr 1f
+
1:  ret        ;get here from the jr 1f
  
  
Line 170: Line 123:
 
set:
 
set:
  
 
+
{|
Character  Radix  Name
+
|+
 
+
!Character||   Radix||   Name
B          2      binary
+
|-
O          8      octal
+
!B||           2||       binary
Q          8      octal
+
|-
o          8      octal
+
!O||           8||       octal
q          8      octal
+
|-
H          16      hexadecimal
+
!Q||           8||       octal
h          16      hexadecimal
+
|-
 
+
!o||           8||       octal
 +
|-
 +
!q||           8||       octal
 +
|-
 +
!H||           16||     hexadecimal
 +
|-
 +
!h||           16||     hexadecimal
 +
|}
  
 
Hexadecimal constants may also be specified in C style,
 
Hexadecimal constants may also be specified in C style,
Line 203: Line 163:
 
sion.  The  value  of the opcode in this context will be the
 
sion.  The  value  of the opcode in this context will be the
 
byte that the opcode would have assembled to if used in  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-
+
normal  way. If the opcode is a 2-byte opcode (CB or ED prefix byte) only the second byte of the opcode will  be  used.
fix byte) only the second byte of the opcode will  be  used.
 
 
This  is  particularly  useful when setting up jump vectors.
 
This  is  particularly  useful when setting up jump vectors.
 
For example:
 
For example:
  
ld  a,jp        ;a jump instruction
+
ld  a,jp        ;a jump instruction
ld  (0),a        ;0 is jump to warm boot
+
ld  (0),a        ;0 is jump to warm boot
ld  hl,boot      ;done here
+
ld  hl,boot      ;done here
ld  (1),hl
+
ld  (1),hl
  
  
Line 223: Line 182:
 
The following operators may be used in expressions:
 
The following operators may be used in expressions:
  
Operator  Meaning
+
{|
 
+
|+
&          Bitwise AND
+
!Operator||   Meaning
*          Multiplication
+
|-
+          Addition
+
!&||         Bitwise AND
-          Subtraction
+
|-
 
+
!*||         Multiplication
 
+
|-
 
+
!+||         Addition
 
+
|-
 
+
!-||         Subtraction
 
+
.and.||     Bitwise AND
HI-TECH C USER'S MANUAL                              Page 39
+
|-
 
+
!.eq.||       Equality test
.and.      Bitwise AND
+
|-
.eq.      Equality test
+
!.gt.||       Signed greater than
.gt.      Signed greater than
+
|-
.high.    Hi byte of operand
+
!.high.||     Hi byte of operand
.low.      Low byte of operand
+
|-
.lt.      Signed less than
+
!.low.||     Low byte of operand
.mod.      Modulus
+
|-
.not.      Bitwise complement
+
!.lt.||       Signed less than
.or.      Bitwise or
+
|-
.shl.      Shift left
+
!.mod.||     Modulus
.shr.      Shift right
+
|-
.ult.      Unsigned less than
+
!.not.||     Bitwise complement
.ugt.      Unsigned greater than
+
|-
.xor.      Exclusive or
+
!.or.||       Bitwise or
/          Divison
+
|-
<          Signed less than
+
!.shl.||     Shift left
=          Equality
+
|-
>          Signed greater than
+
!.shr.||     Shift right
^          Bitwise or
+
|-
 +
!.ult.||     Unsigned less than
 +
|-
 +
!.ugt.||     Unsigned greater than
 +
|-
 +
!.xor.||     Exclusive or
 +
|-
 +
!/||         Divison
 +
|-
 +
!<||         Signed less than
 +
|-
 +
!=||         Equality
 +
|-
 +
!>||         Signed greater than
 +
|-
 +
!^||         Bitwise or
 +
|}
  
  
Line 278: Line 253:
  
  
psect text, global
+
psect text, global
 
+
alabel:
+
alabel:
ld    hl,astring
+
ld    hl,astring
call  putit
+
call  putit
ld    hl,anotherstring
+
ld    hl,anotherstring
 
+
psect data, global
+
psect data, global
astring:
+
astring:
defm  'A string of chars'
+
defm  'A string of chars'
defb  0
+
defb  0
anotherstring:
+
anotherstring:
defm  'Another string'
+
defm  'Another string'
defb  0
+
defb  0
 
+
psect text
+
psect text
 
+
putit:
+
putit:
ld    a,(hl)
+
ld    a,(hl)
or    a
+
or    a
ret  z
+
ret  z
call  outchar
+
call  outchar
inc  hl
+
inc  hl
jr    putit
+
jr    putit
  
  
Line 341: Line 316:
 
DEFB.  Example:
 
DEFB.  Example:
  
DEFB  10, 20, 'a', 0FFH
+
DEFB  10, 20, 'a', 0FFH
DB    'hello world',13,10,0
+
DB    'hello world',13,10,0
  
  
Line 352: Line 327:
 
ple:
 
ple:
  
pi: DEFF  3.14159
+
pi: DEFF  3.14159
  
  
Line 359: Line 334:
  
 
This operates in a similar fashion to DEFB, except that
 
This operates in a similar fashion to DEFB, except that
it  assembles expressions into words, without the value res-
+
it  assembles expressions into words, without the value restriction.  Example:
triction.  Example:
 
  
DEFW  -1, 3664H, 'A', 3777Q
+
DEFW  -1, 3664H, 'A', 3777Q
  
  
Line 376: Line 350:
 
program.  Example:
 
program.  Example:
  
DEFS  20h  ;reserve 32 bytes of memory
+
DEFS  20h  ;reserve 32 bytes of memory
  
  
Line 386: Line 360:
 
of a symbol which is already defined.  Example:
 
of a symbol which is already defined.  Example:
  
SIZE      equ  46
+
SIZE      equ  46
  
  
Line 396: Line 370:
  
  
SIZE      defl  48
+
SIZE      defl  48
  
  
Line 407: Line 381:
 
Example:
 
Example:
  
DEFM  'A string of funny *@$ characters'
+
DEFM  'A string of funny *@$ characters'
  
  
Line 421: Line 395:
 
ple:
 
ple:
  
END  somelabel
+
END  somelabel
  
  
Line 435: Line 409:
 
a COND/ENDC block, for example:
 
a COND/ENDC block, for example:
  
IF    CPM
+
IF    CPM
call  5
+
call  5
ELSE
+
ELSE
call  os_func
+
call  os_func
ENDC
+
ENDC
  
  
Line 466: Line 440:
 
pseudo-op.  The psect flags are as follows:
 
pseudo-op.  The psect flags are as follows:
  
ABS       Psect is absolute
+
;ABS
 +
:Psect is absolute
  
GLOBAL   Psect is global
+
;GLOBAL
 +
:Psect is global
  
LOCAL           Psect is not global
+
;LOCAL
 +
:Psect is not global
  
OVRLD     Psect is to be overlapped by linker
+
;OVRLD
 +
:Psect is to be overlapped by linker
  
PURE           Psect is to be read-only
+
;PURE
 +
:Psect is to be read-only
  
  
Line 490: Line 469:
 
The PURE flag instructs the linker that the psect is to
 
The PURE flag instructs the linker that the psect is to
 
be  made  read-only at run time. The usefulness of this flag
 
be  made  read-only at run time. The usefulness of this flag
depends on the ability of the linker to enforce the require-
+
depends on the ability of the linker to enforce the requirement. CP/M fails miserably in this regard.
ment. CP/M fails miserably in this regard.
 
  
 
The ABS flag makes a psect absolute. The psect will  be
 
The ABS flag makes a psect absolute. The psect will  be
Line 498: Line 476:
  
  
PSECT    text, global, pure
+
PSECT    text, global, pure
PSECT    data, global
+
PSECT    data, global
PSECT    vectors, ovrld
+
PSECT    vectors, ovrld
  
  
Line 512: Line 490:
  
  
GLOBAL      label1, putchar, _printf
+
GLOBAL      label1, putchar, _printf
  
  
Line 522: Line 500:
 
which must be an absolute expression.  Example:
 
which must be an absolute expression.  Example:
  
ORG  100H
+
ORG  100H
  
  
Line 539: Line 517:
 
corresponding actual parameter. For example:
 
corresponding actual parameter. For example:
  
print    MACRO string
+
print    MACRO string
psect data
+
psect data
999:      db    string,'$'
+
999:      db    string,'$'
psect text
+
psect text
ld    de,999b
+
ld    de,999b
ld    c,9
+
ld    c,9
call  5
+
call  5
ENDM
+
ENDM
  
  
  
 
When used, this macro will expand to the 3 instructions
 
When used, this macro will expand to the 3 instructions
in the body of the macro, with the actual parameters substi-
+
in the body of the macro, with the actual parameters substituted for func and arg. Thus
tuted for func and arg. Thus
 
  
 
print 'hello world'
 
print 'hello world'
Line 559: Line 536:
 
expands to
 
expands to
  
psect data
+
psect data
999:      db    'hello world','$'
+
999:      db    'hello world','$'
psect text
+
psect text
ld    de,999b
+
ld    de,999b
ld    c,9
+
ld    c,9
call  5
+
call  5
  
  
  
 
Macro arguments can be enclosed in angle brackets  ('<'
 
Macro arguments can be enclosed in angle brackets  ('<'
and  '>') to pass arbitrary text including delimiter charac-
+
and  '>') to pass arbitrary text including delimiter characters like commas as a single argument.  For example, suppose
ters like commas as a single argument.  For example, suppose
 
 
you  wanted  to use the print macro defined above to print a
 
you  wanted  to use the print macro defined above to print a
string which includes the carriage return and linefeed char-
+
string which includes the carriage return and linefeed characters.  The macro invocation:
acters.  The macro invocation:
 
  
print 'hello world',13,10
+
print 'hello world',13,10
  
  
Line 582: Line 557:
 
as a single argument, you could write:
 
as a single argument, you could write:
  
print <'hello world',13,10>
+
print <'hello world',13,10>
  
  
 
which would cause the text 'hello world',13,10 to be  passed
 
which would cause the text 'hello world',13,10 to be  passed
through as a single argument.  This would expand to the fol-
+
through as a single argument.  This would expand to the following code:
lowing code:
 
  
psect data
+
psect data
999:      db    'hello world',13,10,'$'
+
999:      db    'hello world',13,10,'$'
psect text
+
psect text
ld    de,999b
+
ld    de,999b
ld    c,9
+
ld    c,9
call  5
+
call  5
  
  
  
ZAS supports two forms of macro declaration for  compa-
+
ZAS supports two forms of macro declaration for  compatibility with  older  versions  of ZAS and other Z80 assemblers.  The macro name may be declared either in  the  label
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
 
field  before  the  MACRO pseudo-op, or in the operand field
after the MACRO pseudo-op.  Thus these  two  MACRO  declara-
+
after the MACRO pseudo-op.  Thus these  two  MACRO  declarations are equivalent:
tions are equivalent:
 
  
bdos      MACRO func,arg
+
bdos      MACRO func,arg
ld    de,arg
+
ld    de,arg
ld    c,func
+
ld    c,func
call  5
+
call  5
ENDM
+
ENDM
  
 
and
 
and
  
MACRO bdos,func,arg
+
MACRO bdos,func,arg
ld    de,arg
+
ld    de,arg
ld    c,func
+
ld    c,func
call  5
+
call  5
ENDM
+
ENDM
  
  
Line 625: Line 596:
 
The LOCAL pseudo-op allows unique labels to be  defined
 
The LOCAL pseudo-op allows unique labels to be  defined
 
for each expansion of a macro.  Any symbols listed after the
 
for each expansion of a macro.  Any symbols listed after the
LOCAL directive will have a unique assembler-generated  sym-
+
LOCAL directive will have a unique assembler-generated  symbol substituted  for  them when the macro is expanded.  For
bol substituted  for  them when the macro is expanded.  For
 
  
  
 
example:
 
example:
  
copy      MACRO source,dest,count
+
copy      MACRO source,dest,count
LOCAL nocopy
+
LOCAL nocopy
push  af
+
push  af
push  bc
+
push  bc
ld    bc,source
+
ld    bc,source
ld    a,b
+
ld    a,b
or    c
+
or    c
jr    z,nocopy
+
jr    z,nocopy
push  de
+
push  de
push  hl
+
push  hl
ld    de,dest
+
ld    de,dest
ld    hl,source
+
ld    hl,source
ldir
+
ldir
pop  hl
+
pop  hl
pop  de
+
pop  de
nocopy:  pop  bc
+
nocopy:  pop  bc
pop  af
+
pop  af
ENDM
+
ENDM
  
  
Line 655: Line 625:
 
(recptr),buf,(recsize) will expand to:
 
(recptr),buf,(recsize) will expand to:
  
push  af
+
push  af
push  bc
+
push  bc
ld    bc,(recsize)
+
ld    bc,(recsize)
ld    a,b
+
ld    a,b
or    c
+
or    c
jr    z,??0001
+
jr    z,??0001
push  de
+
push  de
push  hl
+
push  hl
ld    de,buf
+
ld    de,buf
ld    hl,(recptr)
+
ld    hl,(recptr)
ldir
+
ldir
pop  hl
+
pop  hl
pop  de
+
pop  de
??0001:  pop  bc
+
??0001:  pop  bc
pop  af
+
pop  af
  
 
if invoked a second time, the label nocopy would  expand  to
 
if invoked a second time, the label nocopy would  expand  to
Line 680: Line 650:
 
ment.  For example:
 
ment.  For example:
  
REPT  3
+
REPT  3
ld    (hl),0
+
ld    (hl),0
inc  hl
+
inc  hl
ENDM
+
ENDM
  
  
Line 690: Line 660:
  
  
ld    (hl),0
+
ld    (hl),0
inc  hl
+
inc  hl
ld    (hl),0
+
ld    (hl),0
inc  hl
+
inc  hl
ld    (hl),0
+
ld    (hl),0
inc  hl
+
inc  hl
  
  
Line 701: Line 671:
 
=== IRP and IRPC ===
 
=== IRP and IRPC ===
  
The IRP and IRPC directives are similar to  REPT,  how-
+
The IRP and IRPC directives are similar to  REPT,  however instead of repeating the block a fixed number of times
ever instead of repeating the block a fixed number of times
 
 
it is repeated once for each member of an argument list.  In
 
it is repeated once for each member of an argument list.  In
 
the  case  of  IRP the list is a conventional macro argument
 
the  case  of  IRP the list is a conventional macro argument
Line 708: Line 677:
 
string.  For example:
 
string.  For example:
  
IRP  string,<'hello world',13,10>,'arg2'
+
IRP  string,<'hello world',13,10>,'arg2'
LOCAL str
+
LOCAL str
psect data
+
psect data
str:      db    string,'$'
+
str:      db    string,'$'
psect text
+
psect text
ld    c,9
+
ld    c,9
ld    de,str
+
ld    de,str
call  5
+
call  5
ENDM
+
ENDM
  
  
 
would expand to
 
would expand to
  
psect data
+
psect data
??0001:  db    'hello world',13,10,'$'
+
??0001:  db    'hello world',13,10,'$'
psect text
+
psect text
ld    c,9
+
ld    c,9
ld    de,??0001
+
ld    de,??0001
call  5
+
call  5
psect data
+
psect data
??0002:  db    'arg2','$'
+
??0002:  db    'arg2','$'
psect text
+
psect text
ld    c,9
+
ld    c,9
ld    de,??0002
+
ld    de,??0002
call  5
+
call  5
  
  
Line 740: Line 709:
 
IRPC is best demonstrated using the following example:
 
IRPC is best demonstrated using the following example:
  
IRPC  char,ABC
+
IRPC  char,ABC
ld    c,2
+
ld    c,2
ld    e,'char'
+
ld    e,'char'
call  5
+
call  5
ENDM
+
ENDM
  
  
 
will expand to:
 
will expand to:
  
ld    c,2
+
ld    c,2
ld    e,'A'
+
ld    e,'A'
call  5
+
call  5
ld    c,2
+
ld    c,2
ld    e,'B'
+
ld    e,'B'
call  5
+
call  5
ld    c,2
+
ld    c,2
ld    e,'C'
+
ld    e,'C'
call  5
+
call  5
  
  
Line 766: Line 735:
 
codes. These are:
 
codes. These are:
  
_________________________________________________
+
{|
| Code|  Equivalent|  Meaning                    |
+
|+
| alt |  m        |  Arithmetic less than      |
+
Code||  Equivalent||  Meaning                    |
| llt |  c        |  Logical less than          |
+
|-
| age |  p        |  Arithmetic greater or equal|
+
alt ||  m        ||  Arithmetic less than      |
| lge |  nc        |  Logical greater or equal  |
+
|-
| di  |            |  Use after ld a,i for  test-|
+
llt ||  c        ||  Logical less than          |
| ei  |            |  ing  state  of  interrupt|
+
|-
|    |            |  enable flag  -  enabled  or|
+
age ||  p        ||  Arithmetic greater or equal|
||______�||_____________�|�|__d�_i�_s�_a�_b�_l�_e�_d�__r�_e�_s�_p�_e�_c�_t�_i�_v�_e�_l�_y�_.�_______�|�|
+
|-
 
+
lge ||  nc        ||  Logical greater or equal  |
 +
|-
 +
di  ||            ||  Use after ld a,i for  test-|
 +
|-
 +
ei  ||            ||  ing  state  of  interrupt|
 +
|-
 +
     ||            ||  enable flag  -  enabled  or|
 +
|-
 +
    ||           || disabled respectively.
 +
|}
  
12.4. Assembler Directives
+
== Assembler Directives ==
  
An assembler directive is a line  in  the  source  file
+
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:
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
+
;<nowiki>*Title</nowiki>
Use the text following the directive as a title for the
+
:Use the text following the directive as a title for the listing.
listing.
 
  
*Heading
+
;<nowiki>*Heading</nowiki>
Use the text following the directive as a subtitle  for
+
:Use the text following the directive as a subtitle  for the listing; also causes an *Eject.
the listing; also causes an *Eject.
 
  
*List
+
;<nowiki>*List</nowiki>
May be followed by ON or OFF to turn listing on or  off
+
: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.
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
+
;<nowiki>*Include</nowiki>
The file named following the directive will be included
+
:The file named following the directive will be included in the assembly at that point.
in the assembly at that point.
 
  
*Eject
+
;<nowiki>*Eject</nowiki>
A new page will be  started  in  the  listing  at  that
+
:A new page will be  started  in  the  listing  at  that point.  A  form  feed character in the source will have the same effect.
point.  A  form  feed character in the source will have
 
the same effect.
 
  
 
Some examples of the use of these directives:
 
Some examples of the use of these directives:
  
  
*Title Widget Control Program
+
*Title Widget Control Program
*Heading Initialization Phase
+
*Heading Initialization Phase
 
+
*Include widget.i
+
*Include widget.i
  
  
Line 827: Line 789:
  
 
An error message will be written on the standard  error
 
An error message will be written on the standard  error
stream for each error encountered in the assembly. This mes-
+
stream for each error encountered in the assembly. This message identifies the file name and line number and  describes
sage identifies the file name and line number and  describes
 
 
the  error.  In  addition  the line in the listing where the
 
the  error.  In  addition  the line in the listing where the
 
error occurred will be flagged with a  single  character  to
 
error occurred will be flagged with a  single  character  to
Line 836: Line 797:
  
  
A:   Absolute expression required
+
;A:
 +
:Absolute expression required
  
B:   Bad arg to *L
+
;B:
Bad arg to IM
+
:Bad arg to *L
Bad bit number
+
:Bad arg to IM
Bad character constant
+
:Bad bit number
Bad jump condition
+
:Bad character constant
 +
:Bad jump condition
  
D:   Directive not recognized
+
;D:
Digit out of range
+
:Directive not recognized
 +
:Digit out of range
  
E:   EOF inside conditional
+
;E:
Expression error
+
:EOF inside conditional
 +
:Expression error
  
G:   Garbage after operands
+
;G:
Garbage on end of line
+
:Garbage after operands
 +
:Garbage on end of line
  
I:   Index offset too large
+
;I:
 +
:Index offset too large
  
J:   Jump target out of range
+
;J:
 +
:Jump target out of range
  
L:   Lexical error
+
;L:
 +
:Lexical error
  
M:   Multiply defined symbol
+
;M:
 +
:Multiply defined symbol
  
O:   Operand error
+
;O:
 +
:Operand error
  
P:   Phase error
+
;P:
Psect may not be local and global
+
:Phase error
 +
:Psect may not be local and global
  
R:   Relocation error
+
;R:
 +
:Relocation error
  
S:   Size error
+
;S:
Syntax error
+
:Size error
 +
:Syntax error
  
U:   Undefined symbol
+
;U:
Undefined temporary label
+
:Undefined symbol
Unterminated string
+
:Undefined temporary label
 +
:Unterminated string
  
  
12.6. Z80/Z180/64180 Instruction Set
+
== Z80/Z180/64180 Instruction Set==
  
 
The remainder of this chapter is devoted to a  complete
 
The remainder of this chapter is devoted to a  complete

Revision as of 20:00, 30 July 2017

Introduction

The assembler incorporated in the HI-TECH C compiler system is a full-featured relocating macro assembler accepting 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 implements certain extensions to the operands allowed, and certain additional pseudo-ops, which are described here. The assembler also accepts the additional opcodes for the Hitachi 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 overflow. 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 checking.
-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 possible. 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 symbols. 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.


-Ofile
Place the object code in file. 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.
-Llist
Place an assembly listing in the file list, or on standard output if list 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 output (i.e. the console). List file names such as CON: and LST: are acceptable.
-Wwidth
The listing is to be formatted for a printer of given width 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 xxx.crf where xxx 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 characters 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 prefix 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

.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 restriction. 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 requirement. 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 substituted 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 characters 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 characters. 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 following 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 compatibility with older versions of ZAS and other Z80 assemblers. 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 declarations 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 symbol 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, however 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:

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|
Code|| Equivalent|| Meaning |
disabled respectively.

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 message 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


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.