-

Z80 Assembler Reference Manual

提供: HI-TECH C for CP/M Fan WIKI(JP)
2017年8月17日 (木) 10:09時点におけるKumokosi (トーク | 投稿記録)による版 (Expressionsエクスプレッション)
移動先: 案内検索

HI-TECH Cコンパイラシステムに同梱のアセンブラは機能完全版の、ザイログニーモニックを解するリロケータブルマクロアセンブラです。このニーモニック及び、Z80アセンブラ言語はザイログ社発行の「Z80アセンブリ言語ハンドブック」で記述されており、このマニュアルにもリファレンスとして含まれています。 アセンブラはオペランドに特定のexpressionを許容し、またここで記述される疑似命令も同様です。 アセンブラはHitachi64180や Z180プロセッサ用に追加されたオプコードも許容します。

使用法

アセンブラはZASという名前で、次のように指定されます。

ZAS options files...

このファイルは一つ、もしくはそれ以上のアセンブル対象となるアセンブラソースファイルですが、注意すべきなのは、すべてのファイルが一つのファイルとしてアセンブルされることです。個別のファイルにはなりません。 個別のファイルにアセンブルするには、アセンブラがそれぞれのファイルに個別に指定されなければいけません。オプションは0個もしくはそれ以上んも次のオプションからなります。

-N
expressionの算術的なオーバーフローを無視します。-Nオプションは算術的オーバーフローを抑制します。アセンブラはオーバーフローの扱いにおいて「Z80アセンブリ言語ハンドブック」に従います。またある種のインスタンスにおいて、これはユーザーが意図していたものを実際に評価し、エラーとなります。このオプションはオーバーフローチェックのオプションを上書きするために使われます。
-J
分岐ジャンプを最適化しようとします。-Jオプションはアセンブラに対してジャンプと条件ジャンプを、可能な部分であれば相対分岐としてアセンブルするようにリクエストします。分岐の等価物を持つこれらの条件ジャンプのみが最適化されます。ジャンプはターゲットが分岐の範囲内にある分岐のみが最適化されます。これはアセンブラに対して入力されたコードをパスに追加する必要があるため?このオプションの使用はアセンブルの速度を低下させます。
-U
未定義のシンボルを外部関数として扱います。-Uオプションは未定義のシンボルに関するエラーメッセージを抑制します。このようなシンボルはどんな場合であっても、外部関数として扱われます。このオプションの使用は生成されたオブジェクトを変更しませんが、エラーメッセージの抑制をおこしません??
-Ofile
オブジェクトコードをファイル内に配置します。デフォルトオブジェクトファイル名は最初のソースファイル名から構築されます。ファイル名の中の拡張子やファイルの型(つまり、"."よりも右側)が切り取られ、拡張子.objが追加されます。そのため、以下のコマンド
ZAS file.as file2.z80
はfile1.objというオブジェクトファイルを生成します。-Oオプションの使用はこのデフォルトの便利さを上書きし、オブジェクトファイルに任意の名前をつけることを許容します。たとえば
ZAS -ox.obj file1.obj

x.objのオブジェクトコードの中にオブジェクトコードが配置されます。

-Llist

アセンブラのリスティングをlistファイルに置くか、listがnullの場合はリストファイルが-Lオプションで作成されます。

もし、ファイル名がこのオプションに与えられると、その名前でリストファイルが作成され、それ以外の場合、リスティングは標準出力(つまりコンソールへ)書き出されます。

CON:やLST:といったファイル名が使えます。

-Wwidth

このリスティングはプリンタを与えられたwidthの幅でフォーマットします。

¥-Wオプションはリスティングがどれくらいの幅にするか、指定するオプションです。
ZAS -Llst: -W80 x.as
これはlistデバイス80カラム用にリスティングを整形してアウトプットします。
-C
このオプションはZASに対し、クロスリファレンス情報を書くリクエストをします。
このファイルはxxx.crfと呼ばれ、

xxx は最初のソースファイル名の基本部分です。

これはCREFユーティリティを走らせる時に必要で、この情報が整形されたリスティングに変わります。

Expressionsエクスプレッション

エクスプレッションは「Z80アセンブリ言語ハンドブック」に記述されている内容で大部分が構成されます。 |- |-|| Subtraction減算 |- |.and.|| Bitwise ANDビット演算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 orXOR |- |/|| Divison除算 |- |<|| Signed less than符号あり小なり |- |=|| Equalityイコール |- |>|| Signed greater than符号あり大なり |- |^|| Bitwise orビット演算 |}

"."で始まるオペランドはスペースで区切る必要があります。label .and. 1 は有効ですがlabel.and.1は有効ではありません。

再配置性

zasは再配置可能なオブジェクトコードを生成します。つまりこれは、メモリのどこに配置すべきかをアセンブル時に指定しなくて良い、ということを意味します。

これはORG擬似命令を使うことで可能ですが、より好ましいアプローチはプログラムセクションあるいはpsectをつかうことです。

psectはプログラムのセクションに名前を付けたもので、この中のコードやデータさアセンブル時に定義されます。psectの全てのパーツは、別々のファイルで定義されていても、また同じファイル内で、別のpsectで分断されていたとしても、メモリに連続して読み込まれます。

例えば、次のコードはtextと名付けられたpsectに実行可能なインストラクションを。また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

2つのブロックのtext psectが、data psectによって分断されていますが、2つのtext psectブロックはリンカに呼び出される時に連続します。

"ld hl,anotherstring"というインストラクションは実行時に"putit:"というラベルに落ちます??

2つのpsectの実際のメモリ位置はリンカによって決められます。psectアドレスがどのように決められるかについては、リンカのマニュアルを参照してください。

psect内で定義されるラベルにははリロケータブルになり、これはアセンブル時には実際のメモリアドレスが定義されないということです。

ラベルがデフォルトの(名前のない)psectの場合、もしくは絶対定義(PSECT擬似命令の記述参照)した場合には適用されません。

絶対psect内で定義されたラベルはアセンブラによってアドレスが決められ、絶対指定になります。

HI-TECH Cのバージョン7もしくはそれ以降のバージョンと一緒に提供されるZASは、リロケータブルエクスプレッションが、エクスプレッション内で自由に結合します。古いバージョンのZASは、リロケータブルエクスプレッションが算術的に限られます??

擬似命令

擬似命令は、"Z80アセンブリ言語ハンドブック"の記述に依拠し、いくつかの追加があります。

DEFB, DB

この擬似命令はエクスプレッションのコンマ区切りリストの後に置かれます。

一続きのバイトロケーションにアセンブルされます。

どのエクスプレッションも-128から255の値を内包する必要があります。 DBはDBFBのシノニムとして使うことができます。

例:

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

DEFF

この擬似命令は浮動小数点数コンスタントを32bitのHI-TECH Cフォーマットの浮動小数点数コンスタントにアセンブルします。

pi: DEFF  3.14159

DEFW

エクスプレッションを値に制限のないワードにアセンブルすること以外はDEFBと似ています。

例:

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


DEFS

DEFSは初期化することなしにメモリロケーションをリザーブします。
このオペランドは絶対的なエクスプレッションで、リザーブされるされるバイト数を表現します。
このエクスプレッションは現在のロケーションカウンターに追加されます。
しかしながら、DEFSによってリザーブされたロケーションがプログラムの中間の場合、リンカによってゼロに初期化される可能性があります。

例:

DEFS  20h   ;メモリの32バイトをリザーブ

EQU

EquはEQUの左に、シンボルの値を

右にエクスプレッションを設定します。

既にていぎされているシンボルの値を設定するのは違反です。
例:
 SIZE      equ   46

DEFL

既に存在するシンボルを再定義できることを除いて、EQUと同じです。

例:

 SIZE      defl  48

DEFM

DEFMはシングルクォートで囲まれた、文字列の後に続かなければいけません。
これら文字のASCII コードは連続したメモリにアセンブルされます。

例:

DEFM  'A string of funny *@$ characters'

END

ソースファイルの終わり、もしくは擬似命令ENDがアセンブルの終了を意味します。
擬似命令ENDはオプション的に、プログラムの開始アドレスを定義するエクスプレッションに続いて現れることがあります。
これはCP/Mでは本当のところ、便利ではありません。ただ1つの開始アドレスだけがプログラムごとに定義されます。それ以上ある場合はリンカが文句をいいます。

例:

END   somelabel

COND, IF, ELSE, ENDC

条件的アセンブルはCOND擬似命令によって、提供されます。
CONDのオペランドは絶対的なエクスプレッションでなければいけません。
もし、この値が偽(ゼロ)の場合、CONDから続き、対応するENDC擬似命令の部分まではアセンブルされません。
COND/ENDCのペアはネストが可能です。
IFがCONDのシノニムとして使用可能です。
ELSE擬似命令をCOND/ENDCブロックの中に含むことができます。

例:

IF    CPM
call  5
ELSE
call  os_func
ENDC

ELSE

COND参照

ENDC

COND参照

ENDM

MACRO参照

PSECT

この擬似命令は再配置可能なプログラムセクションの定義を許可します。
この引数はオプション的にpsectフラッグの後に着く、psect nameです。
psect名はラベルと同じルールに従って構築されるシンボルですが、psectは、衝突することなくラベルと同じ名前を持つことができます。
psect名はPSECT擬似命令の後で、のみ認識されます。psectフラグは以下の通りです。
ABS
Psectは絶対値です。
GLOBAL
Psectはグローバルです。
LOCAL
Psectはグローバルではありません。
OVRLD
Psectはリンカによってオーバーラップ可能です
PURE
Psectはリードオンリーでなければいけません
Psectがもしグローバルな場合、リンカはこれを、他モジュールで同名の他のグローバルpsectとマージします。
ローカルのpsectは他のモジュールからの、他のpsectとは区別されます。Psectはデフォルトでグローバルです。
デフォルトでリンカはいろいろなモジュールからのpsect内で、コードを連結します。
psectがOVRLDとして指定されると、リンカがそれぞれのモジュールを、そのpsectにオーバーラップしていきます。
初期化する時や、ベクター割り込みする時など、モジュールをリンクをする特定の場合に便利です。
PUREフラグは、psectが実行時にのみリードオンリーになり得るとリンカに伝えます。
このフラグの有用性はリンカが要求を強制する能力に依存します。CP/Mは悲しいことに、ここに配慮されていません?
ABSフラグはpsectを絶対化します。
psectはゼロに読み込まれます。
これは静的にベクター割り込みを初期化し、テーブルにジャンプする時に有用です。

例:

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

GLOBAL

GLOBAL はもう1つのシンボルに続いて(カンマ区切りで)使われなければいけません。これはinternalでもexternalでも、現在のモジュールの内部で依存していてもいなくても、アセンブラにグローバルとして取り扱われます。
例:
GLOBAL      label1, putchar, _printf

ORG

擬似命令ORGは現在のpsectをデフォルト(絶対)psectに設定し、絶対表現としなければならないロケーションカウンタをオペランドとします。

例:

ORG   100H

MACRO

この擬似命令はマクロを定義します。マクロ名に前置する要素も後続する要素もあります。

カンマ区切りのフォーマルパラメータがオプション的に後続します。

MACRO擬似命令に後続し、次のENDMまでのコードの行がマクロ本体として格納されます。
マクロ名は後続するアセンブラステートメントのオプコード部分でも使われ、実際のパラメータが後続します。
マクロの本体は、その部分で、対応する実際のパラメータを持つフォーマルパラメータと置き換えられます??
例:
print     MACRO string
    psect data
999:      db    string,'$'
    psect text
    ld    de,999b
    ld    c,9
    call  5
    ENDM
使用されると、このマクロはマクロの本体で、実際のパラメータの代用である関数と引数の3つのインストラクションに展開されます??
従って、print hello world' は次のように展開されます。
    psect data
999:      db    'hello world','$'
    psect text
    ld    de,999b
    ld    c,9
    call  5
マクロの引数はかぎ括弧('<' と '>')で閉じてコンマなどのデリミタキャラクタを含む任意のテキストを渡すために使うことが可能です。
例えば、キャリッジリターンとラインフィードを含む文字列を先ほど定義したprintマクロで使いたいとしましょう。

その場合のマクロを以下のように発動させたとします。

print 'hello world',13,10
しかしこれは失敗します。なぜなら13と10が追加の引数として扱われて、無視されるからです。コンマを含む文字列を単体の引数として渡すためには、次のように書きます。
print <'hello world',13,10>
これで 'hello world',13,10というテキストを単体の引数として渡すことができるでしょう。これは次のようなコードに展開されます。
    psect data
999:      db    'hello world',13,10,'$'
    psect text
    ld    de,999b
    ld    c,9
    call  5
ZASは古いバージョンのZASや他のZ80アセンブラとの互換性のため、2種類のマクロ定義をサポートしています。

マクロ名はMACRO擬似命令の前のラベルフィールドでも、MACRO擬似命令の後のオペランドフィールドでも定義できます。

そのため、この2つのマクロ定義は等価です。
bdos      MACRO func,arg
ld    de,arg
ld    c,func
call  5
ENDM
MACRO bdos,func,arg
ld    de,arg
ld    c,func
call  5
ENDM

LOCAL

LOCAL擬似命令はマクロの拡張のため、ユニークなラベルを定義できます。
LOCALディレクティブの後にシンボルがリスト化されている場合、マクロが展開される時に、これらは代わりの

ユニークなアセンブラ生成シンボルとなります。

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
nocopyの位置に展開されたコードがユニークなアセンブラ生成ラベルを含む場合には、例えば、copy(recptr),buf,(recsize)は次のように展開されます。
    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
2回目に発動する際には、nocopyラベルは??0002に展開されます。

REPT

REPT擬似命令は引数によってていぎされただけ、複数回展開されるテンポラリマクロを定義します。

例:

REPT  3
ld    (hl),0
inc   hl
ENDM

これは次のように展開されます。

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

IRP と IRPC

IRPとIRPCディレクティブはREPTに似ていますが、ブロックを決まった回数繰り返すのではなく、引数リスト化にある回数それぞれを一回だけ実行します。

IRPの場合はリストはコンベンショナルマクロの引数リスト、IRPCの場合は文字列からの連続する文字です。

例:

    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

これは次のように展開されます。

    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


コンベンショナルマクロを使用する際と同様に、LOCALラベルとかぎ括弧の使用に注意してください。

IRPCを最もよく表す例は以下のものです。

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

これは次のように展開されます。

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

追加条件コード

このアセンブラはいくつかの追加条件コードを認識します。 これらは次の通りです。

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 ld a,iの後に使う
ei 割り込み可能フラグの
評価です。それぞれ、
可能、不可能。

アセンブラディレクティブ

アセンブラディレクティブはソースファイルにおける行で、これはコードを生成せず、むしろアセンブラの振る舞いを変えます。

どのディレクティブも行の初めのカラムにアスタリスクがつくのでわかります。 これは単語のすぐあとにつき、最初の文字のみを見ます。

ディレクティブ自体を含む行はリスト化されません。ディレクティブは以下の通りです

*Title
このディレクティブ後続する行をリスティングのタイトルとして使います。
*Heading
このディレクティブに続く行をリスティングのサブタイトルとして使います。*Ejectにも影響します。
*List
ONやOFFを後に伴い、リストをそれぞれオンオフします。このディレクティブはマクロの内部や、そのマクロやインクルードファイルをコントロールするインクルードファイルでも使われる可能性があります。
以前のリスティング状態はマクロやインクルードファイルから戻った時に回復されます。
*Include
ディレクティブに後続するファイル名が、この時点でアセンブラにインクルードされます。
*Eject
新しいページをこの時点で開始します。ソースのフォームフィールド文字も同じ効果を持ちます。
これらのディレクティブのいくつかの例を挙げます。
*Title Widget Control Program
*Heading Initialization Phase
*Include widget.i

診断

アセンブル中に遭遇したそれぞれのエラーに対してエラーメッセージが標準エラーストリームに書き出されます。 このメッセージはファイル名と行番号を特定し、エラーを記述します。

エラーの起きた行のリスティングに加えて、エラーを示す1文字のフラグが立ちます。

文字と対応するメッセージは次の通りです。


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 conditionalEOFが条件の中にあります
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

psectはローカルとグローバルにできません

R
Relocation errorリロケーションエラーです
S
Size errorサイズエラーです
Syntax error構文エラーです
U
Undefined symbol未定義のシンボルです
Undefined temporary label未定義のテンポラリラベルをです
Unterminated string閉じていない文字列です

Z80/Z180/64180 インストラクションセット

この章の残りの部分はZ80、Z180、64180、NSC800の完全なインストラクションセットのために割かれています。Z180と64180 は全てのZ80の命令が実行できますが、タイミングが異なります。