電子計算機工学 I
NAGASAKA Yasunori
2003/04/04
|
http://edu.isc.chubu.ac.jp/naga/index.html で公開中
1 はじめに
1.1 目標
1.2 コンピュータの分類
1.3 マイクロプロセッサの歴史
2 Z80アーキテクチャ
2.1 CPU の内部構成
2.1.1 各部の機能
2.1.2 レジスタの役割による分類
2.1.3 PC における命令の番地計算の特徴
2.2 スタック
2.2.1 概要
2.2.2 スタックの使用例
2.2.3 練習問題
2.3 プロセッサの動作原理
2.3.1 CPU の動作例
2.3.2 練習問題
3 インタフェース信号とタイミング
3.1 インタフェース信号
3.1.1 各インタフェース信号の機能
3.2 DMA
3.2.1 DMA を使わない、使えない場合
3.2.2 DMA を使った場合
3.3 CPU の動作タイミング
3.4 命令実行サイクルと制御信号の変化
3.4.1 M1 サイクル, フェッチサイクル
3.4.2 主記憶データの読み出し/書き込みサイクル
3.4.3 入出力装置のデータの読み出し/書き込みサイクル
3.4.4 バス要求及び確認サイクル
4 アドレス方式
4.1 固有アドレス指定形式
4.2 直接数値指定形式
4.3 拡張直接数値指定形式
4.4 レジスタアドレス指定形式
4.5 レジスタ間接アドレス指定形式
4.6 拡張アドレス指定形式
4.7 ページ 0 アドレス指定形式
4.8 相対アドレス指定形式
4.8.1 相対アドレスと絶対アドレスの違い
4.8.2 プログラムの再配置
4.9 インデックスアドレス指定形式
4.10 ビット指定形式
4.11 練習問題
5 命令の種類
5.1 8 ビットのデータ移動
5.2 16 ビットのデータ移動
5.3 交換、ブロック転送、検索
5.3.1 交換命令
5.3.2 ブロック転送命令
5.3.3 検索命令
5.4 8 ビット算術論理演算
5.5 汎用算術演算、CPU 制御
5.6 16 ビット算術演算
5.7 循環、桁移動
5.8 ビット操作、判定
5.9 飛び越し
5.9.1 絶対アドレス指定
5.9.2 相対アドレス指定
5.10 サブルーチン接続、戻り
5.11 入出力
5.12 練習問題
5.12.1
5.12.2
6 フラグと算術演算
6.1 ゼロフラグ Z
6.2 符号フラグ S
6.3 桁上げフラグ CY
6.4 パリティ / あふれフラグ P/V
6.5 練習問題
7 Z80 用アセンブリ言語
7.1 記述方法
7.1.1 プログラムの書き方
7.2 使用できる文字
7.3 定数の表現
7.4 ラベル記述のルール
7.5 予約語
7.6 オペランドとして書ける内容
7.7 疑似命令
7.8 アセンブリ言語によるプログラミングの例
7.8.1 DATA1 番地から MAX 個のデータを足して RESULT に記録する
7.8.2 DATA1 番地のデータを 4 倍して RESULT に記録する
7.8.3 (DATA1) と (DATA2) の大きい方を RESULT に記録する
7.8.4 DATA1 × DATA2 を求める
7.9 ハンドアセンブルの方法
7.10 練習問題
1 はじめに
1.1 目標
標準的な 8 ビットマイクロプロセッサである Z80 の内部構造、機械語、アセンブリ言語
の学習を通して、コンピュータの心臓部である CPU (Central Processing Unit, 中央処理装置)
の構造、動作原理、プログラミングを理解する。
1.2 コンピュータの分類
- スーパーコンピュータ : 数値計算を非常に高速に実行する。非常に高価である。
- 大型コンピュータ (汎用コンピュータ、メインフレーム) : 数値計算、
事務処理など幅広い用途で使用される。大規模なシステムで、
スーパーコンピュータに次いで高価である。
- ミニコンピュータ (オフィスコンピュータ) : 大型コンピュータと同様の用途で使用される。
規模は比較的小さく、安価で中小規模のシステムを構成する。
- ワークステーション : 小型だが高度な演算性能を備えたシステムで、
最初は科学技術計算や研究用途で使用された。現在は幅広く事務処理等にも使用される。
- パーソナルコンピュータ : 個人で利用する安価なコンピュータ。
ここ数年の性能向上の度合が著しい。
- マイクロコンピュータ : システムとしてのコンピュータではなく、
機械や電気機器等に組み込まれて制御用に使用される。
- マイクロプロセッサ : マイクロコンピュータと近い意味を表すが、
組み込み用途だけでなくワークステーションやパーソナルコンピュータの CPU
として使用されるものも表す。演算や他の装置の制御機能などの、
コンピュータの主要な機能を少数個の LSI にまとめている。
1.3 マイクロプロセッサの歴史
インテル、ザイログ、モトローラのプロセッサ
ビット数 |
インテル |
ザイログ |
モトローラ |
4 |
4004 |
- |
- |
8 |
8008 |
- |
- |
- |
8080 |
Z80 |
6800 |
- |
8085 |
- |
6809 |
16 |
8086 |
Z800 |
68000 |
- |
80186 |
- |
- |
- |
80286 |
- |
68010 |
32 |
80386 |
Z8000 |
68020 |
- |
i486 (80486) |
- |
68030 |
- |
Pentium (80586) |
- |
68040 |
- |
Pentium Pro (80686) |
- |
68060 |
- |
Pentium II, III |
- |
PowerPC |
- |
Pentium 4 |
- |
- |
現在のパーソナルコンピュータは安価だが、一昔前の大型コンピュータよりも
演算性能が高い。
4, 8 bit マイクロプロセッサは、コンピュータシステムとしては使われなくなったが、
制御用のマイクロコンピュータとして、
電気機器などに組み込まれて現在でも広く利用されている。
プロセッサの基本的な動作原理は 4 bit CPU でも、32 bit CPU でもほとんど同じである。
よって 8 bit CPU の Z80 についての知識でも、
最近の高性能な 32 bit CPU の機能の理解に役立つ。
4, 8, 16, 32, 64 bit プロセッサの違い
→ プロセッサ内部のレジスタのビット数の違い
→ 扱える数値 (整数) の大きさが異なる。
CPU のレジスタ長と直接扱える数値の範囲
ビット数 |
扱える数値の範囲 |
4 |
24 = 16 |
8 |
28 = 256 |
16 |
216 = 65536 |
32 |
232 = 4.295 × 109 |
64 |
264 = (232)2 |
2 Z80アーキテクチャ
2.1 CPU の内部構成

内部構成
2.1.1 各部の機能
- ALU : 2 個のレジスタから値を入力し、算術論理演算を行う
- CPU レジスタ : プロセッサ内部でデータを記憶しておくところ
- プログラムカウンタ : 次に実行する命令のアドレスを保持する
- 命令レジスタ : 実行対象の命令 (2 進数で表現される) を保持する
- システム制御 : プロセッサの動作を管理して、必要な信号を各部に送る。
制御信号を読み込んだり外部に出力する
- データバス(制御) : レジスタとメモリ、周辺装置との間でデータの送受信を
する時のデータの通り道
- アドレスバス(制御) : メモリ、周辺装置のどれをアクセスするか、番地を指定
する時のデータの通り道
- システム制御信号 : プロセッサと周辺回路との間で互いの状態を通知する信号
命令数の変化
プロセッサ |
命令数 |
8008 |
48 |
8080 |
+30 |
Z80 |
+80 |
未使用 |
90 |
2.1.2 レジスタの役割による分類

レジスタ
- A レジスタ : ALU への入力、出力を保持する。accumulator と呼ばれることもある。
- B--L レジスタ : 汎用レジスタ。演算対象のデータを保持する。16bit のデータを扱う時は、
BC, DE, HL が組になり、仮想的な 16bit レジスタとして使用できる。
- F レジスタ : フラグレジスタ。種々の演算の結果を 1 bit のフラグで保持する。
- I レジスタ : 割り込み処理ルーチンの先頭番地を表す。詳細は後期に
- R レジスタ : DRAM の記憶内容保持のためのリフレッシュ動作の番地管理
- IX, IY レジスタ : メモリアクセスの際の番地指定専用、インデックスレジスタ
- PC : プログラムカウンタ、次に実行する命令の番地を保持する
- SP : スタックポインタ、スタックの一番上のデータの番地を示す
(ヒント):リフレッシュとは : DRAM, Dynamic RAM はコンデンサに蓄えた電荷でデータを記録する
ため、一定時間アクセスがないと放電により内容が消えてしまう。そのため記憶データを
使わない時でも時々読み出して同じ内容を書き込む操作が必要となる。この操作を
リフレッシュと呼ぶ。

8bit 演算

16bit 演算
F レジスタの内容
F レジスタの各ビットの意味
記号 |
意味 |
説明 |
値 |
S |
符号 |
演算結果の正負 |
負:1, 正:0 |
Z |
ゼロ |
演算結果が「ゼロ」か |
ゼロ:1, 非ゼロ:0 |
H |
半桁上 |
2 進化 10 進数の桁上 |
有:1, 無:0 |
P |
パリティ |
1 の個数 |
偶数:1, 奇数:0 |
V |
オーバフロー |
桁あふれ |
有:1, 無:0 |
N |
BCD 減算 |
2 進化 10 進数の減算 |
行う:1, 行わない:0 |
CY |
桁上 |
演算結果の桁上 |
有:1, 無:0 |
2.1.3 PC における命令の番地計算の特徴

メモリ
Z80 の命令は 1 〜 4 Bytes の可変長である。
そのため PC は読み込んだ命令のバイト数を判断して自動的に +1 〜 +4 だけ変更される。
例としてメモリ内が以下のようになっていたとする。
3A 3A 2A 47 3A 80 25 4F
---------- -- ---------- --
LD A,(2A3A) LD B,A LD C,A
LD A,(2580)
---------- ---------- --
LD A,(472A)
命令を取り出す位置によって全く意味が異なる
メモリの内容が実行対象のプログラムか、計算対象のデータであるかは見ただ
けではわからない。実行を開始する番地に依存して決まる。
2.2 スタック
2.2.1 概要
スタックとは、レジスタを別の用途に使いたい時に、現在のレジスタの値を一
時的にメモリに退避するための仕組みである。
- スタックにレジスタの値を退避する時は、Z80 では 16 ビットを単位
として処理する。
- 通常の 8 ビット長のレジスタの場合は AF, BC, DE, HL のように
レジスタペアとして扱う。
- IX, IY, PC のような 16 ビット長のレジスタの場合は単独で扱う。
- スタックを操作する命令には PUSH と POP がある。PUSH でレジスタの値をス
タックに退避、POP で退避してあった値をレジスタに戻す。
スタックを使う時には、使い始める前に SP (スタックポインタ) を初期化す
る必要がある。SP はスタックの領域をどこまで使ったか管理するためのアド
レス (=最後に使った領域を指す) を保持する。
- PUSH を実行すると SP-1, SP-2 番地に値が書き込まれ、その後 SP=SP-2 となる。
- POP を実行すると SP, SP+1 番地からデータが読み出され、SP=SP+2 となる。
スタックの領域はアドレスの大きい方から使われ始めて、使用量が増えるにし
たがってアドレスの小さい方に増えていく。

スタック
アドレスの値の小さい領域は通常 ROM, OS, ユーザのプログラムが配置されるため、
スタックはアドレスの値の大きい領域に配置されることが多い。
2.2.2 スタックの使用例

スタックの内容の変化
- 最初の時点で A, B, C, D レジスタにはそれぞれ図中に示す値が入っている。
- PUSH AF を実行すると、A, F レジスタの値が SP の指す上の場所から
スタックに書き込まれる(図中(2))。この場合レジスタペアの先に書かれ
るレジスタ(この場合は A)がアドレスの大きい方に書き込まれる。F レジスタ
の値は (F) と表している。
- その後続けて PUSH BC, PUSH DE を実行すると図のように値が記録される。
SP はスタックが消費されるのにつれてアドレスの値の小さい方を指し示す
ように変更される。
- この時点で各レジスタの値はスタックに記録されているので、他の用途にレジ
スタを使用して値が変化してしまっても後から復活させることができる。
- レジスタの値を戻す時には PUSH を実行した順番と逆に
POP を実行する。POP DE を実行するとスタックの最後に使った
領域から値が取り出されて D, E レ
ジスタに値が代入される。SP は値を取り出した領域の前の領域を指すように
内容が変更される。
- その後続けて POP BC, POP AF を実行すると各レジスタに値が代入されて
スタックは元の状態に戻る。
2.2.3 練習問題
各レジスタの初期値が A=0, B=1, C=2, D=3, E= 4, F=5 となっている状態で、次のスタック
操作を行なった後に各レジスタの値がどうなるか答えなさい。
(1) PUSH AF
PUSH BC
PUSH DE
POP AF
POP BC
POP DE の一連の操作を ★ とする。★ を 2 回繰り返す。
(2) ★ を 3 回繰り返す。
(3) PUSH AF (4) PUSH AF
PUSH BC PUSH BC
PUSH DE POP DE
PUSH AF POP BC
POP DE POP AF
POP BC
POP AF
2.3 プロセッサの動作原理

CPU とメモリ
- PC に実行開始番地をセットする。
- AB に PC の内容を出力して番地を指定する。
- DB から指定した番地の内容を読み取り、IR にセットする。
これをフェッチと呼ぶ。 PC ← PC + 1
- システム制御部により IR の内容が解読される。これをデコード
と呼ぶ。1 バイト命令なら 6 へ進む。
- 2 バイト以上の命令については、(2),(3) を必要な回数繰り返す。読み込んだ
データは CPU 内部のバッファに保持する。
- 命令を実行する。
- 2 に戻る。
2.3.1 CPU の動作例
(2000) のデータと (2001) のデータを加算して (2002) に格納するプログラムが 1000 番地から配置されている場合
(* Z80 ではメモリへの入出力、算術論理演算はA レジスタでしか行えないという制約がある)

プログラムとデータの配置
命令実行時のデータの流れ
1000 → AB
IR ← DB (3A)
解読すると 3 バイト命令なので残り 2 バイトを読む
1001 → AB
バッファ ← DB (00)
1002 → AB
バッファ ← DB (20)
2000 → AB ; LD A, (2000)
A ← DB
1003 → AB
IR ← DB
B ← A ; LD B, A
1004 → AB
IR ← DB
同様に (1004), (1005) から 01, 20 を読む
2001 → AB ; LD A, (2001)
A ← DB
1007 → AB
IR ← DB
A ← A + B ; ADD A, B
1008 → AB
IR ← DB
同様に (1009), (100A) から 02, 20 を読む
2002 → AB ; LD (2002), A
A → DB
100B → AB
IR ← DB
終了 ; HALT
2.3.2 練習問題
次のプログラムを実行する時の、プログラムとデータのメモリ上の配置、実行
中のデータの流れを上記の例と同じ形式で示しなさい。プログラムはいずれも
1000 番地から配置されているものとする。
- (3000) のデータを (2000), (2001), (2002) に格納する。
- (3000), (3001), (3002), (3003) のデータの和を求める。
- (3000) のデータと (2000) のデータを交換する。
3 インタフェース信号とタイミング
3.1 インタフェース信号

Z80CPU の信号線
もともとは 40pin DIL : Dual Inline Package 形式のパッケージで提供され
ていた。現在は、周辺の SIO, PIO, DMA, CTC, その他の回路等を 1 chip に
集積した形で提供されることが多い。

パッケージの違い
- A0 (下位) 〜 A15 (上位) で 216=64KB のメモリが使用可能。
- 入出力装置の指定はアドレスバスの下位 8bit、
Refresh は下位 7bit で番地を指定する。
3.1.1 各インタフェース信号の機能
- BUSRQ : 外部機器が CPU を介さずに直接メモリをアクセス
する(DMAと呼ぶ) ための、バスの使用(解放)要求。
- BUSAK : BUSRQを承認したことを
表す。
- MREQ : メモリに対してアクセスを要求する。この時アドレス
バスには指定するアドレスを同時に出力する。RD,
WRで入出力の別を指定する。
- RD,WR : メモリ、周辺装置に対する
読み出し、書き込みを表す。
- RFSH : メモリの記憶内容が消えないようにリフレッシュ操作
を行うことを表す。
- IORQ : 周辺装置に対してアクセスを要求する。アドレスバス
の下位 8bit で指定する。同時にRD,WR
で入出力の別を指定する。
- M1 : 命令の取り出しサイクルを表す。命令コードが 2 Bytes の
ときは 2 回現れる。
- RESET : CPU をリセットする。
- WAIT : 低速なメモリ、周辺装置が CPU に処理を待ってもらう
時に使用する。
- HALT : CPU が停止している (NOP を実行している) 状態を
表す。割り込みか RESET を入力すると動作を再開する。
- NMI : Non Maskable Interupt, 無視できない割り込みを表す。
- INT : INTerupt, 通常の割り込みを表す。
3.2 DMA
DMA は Direct Memory Access の略で、周辺装置とメモリ間の大量のデータ転送が必要な場合、
CPU にやらせないでデータ転送専用の回路を使って行うことを表す。そのような回路は通常
データ転送を高速に、効率よく実行できるように設計してある。

DMA
3.2.1 DMA を使わない、使えない場合
データの転送を 1 バイトずつ CPU が行う。CPU では次のような手順になり効率が悪い。
- 繰り返し回数を設定する命令をメモリから読み込む。(2, 3 Bytes)
- 繰り返し回数を設定する。
- !!! 周辺装置からデータを読み込む命令をメモリから読み込む。(2, 3 Bytes)
- !!! 周辺装置からデータを読み込む。
- !!! メモリにデータを書き込む命令をメモリから読み込む。(3 Bytes)
- !!! メモリにデータを書き込む。
- !!! 繰り返しの処理を行う命令をメモリから読み込む。(2, 3 Bytes)
- !!! 繰り返しの処理を行う。
(!!! は実行される回数が多いことを表す。)

DMA を使わない場合のデータの流れ
3.2.2 DMA を使った場合
データの転送は DMA に任せる。DMA は大量のデータを効率よく転送する機能を備えている。
データ転送中は CPU はお休みして DB をアクセスしない。(BUSRQ,
BUSAK で設定)
- DMA にデータ転送に関する設定 (どの周辺装置から読み出すか、
メモリのどこに書き込むか、データ量等) を行う命令をメモリから読み込む。
- DMA にデータ転送に関する設定を行う。
- !!! DMA がデータを周辺装置から読み出す。
- !!! DMA がメモリにデータを書き込む。

DMA を使う場合のデータの流れ
(ヒント): データ転送中も CPU は休まずに別の仕事をさせる場合もある。このような方式を
チャネル制御といい、大型計算機などでは一般的に行なわれている。
3.3 CPU の動作タイミング
CPU における命令実行は 2 種類の時間の長さの表現を基準にして説明される。
- T サイクル, クロックサイクル : プロセッサの動作に関するもっとも細かい、短い時間の単位。
クロック波形の 1 周期の時間が相当する。例としてクロック周波数が 4 MHz
の場合、T サイクルはその逆数で 250 nsec となる。
4 × 106Hz → 1 / (4 × 106) sec =
1 / 4 usec = 250 nsec
- M サイクル, マシンサイクル : 命令の実行を機能的な観点から分けた場合の各段階を表す単位。
1 M サイクルは、複数(3〜6)の T サイクルからなる。

T サイクルと M サイクル
1 個の命令の実行には 1 〜 6 M サイクルが必要となる。必要な M サイクル数は命令によって
異なり、一般に命令語長が長い命令は M サイクル数が多くなる。
(ヒント): 同じ実行結果が得られる命令でも、命令毎に実行時間は多少の違いが
ある。プログラムの処理速度を高速にしたい場合は実行時間を考えて
命令を選択することもできる。
例 LD A, 0 T サイクル 7
XOR 0 T サイクル 4
上記の命令はどちらも A レジスタを 0 にするという点で結果は同じであるが、
実行時間はかなり異なる。処理速度を重視する場合は XOR を使うこともでき
るが、反面プログラムの内容がわかり難くなる。LD では A レジスタを 0 に
するという内容が直接理解できるが、XOR ではわからない。通常
はプログラムの読み易さを重視すべきであり、上記のような命令
の使い方はどうしても処理速度を改善したい時に限定すべきである。
3.4 命令実行サイクルと制御信号の変化
3.4.1 M1 サイクル, フェッチサイクル

M1 サイクルのタイムチャート
- PC を AB に出力する。M1 を出力する。
- 次に MREQ, RD を出力し、
メモリに読み出し要求を伝える。
- WAIT の状態を調べ、もしアクティブなら 1 クロック後に
再び WAIT を調べる。
WAIT がアクティブでなければ、メモリからは、
DB に AB から指定した番地の内容が出力される。
- 1/2 クロック後に CPU はその内容を取り込んで IR に記憶する。
その後 M1,
MREQ, RD を H に戻す。
- リフレッシュ対象の番地を AB にセットし、RFSH を
出力する。
- 少し後に MREQ を出力して、それに合わせてリフレッシュ
が行われる。この間に CPU 内部では IR の内容が解読され、
実行すべき動作が決まる。
3.4.2 主記憶データの読み出し/書き込みサイクル

メモリ READ サイクルのタイムチャート
- 読み出す対象の番地を AB に出力する。
- 1/2 クロック後に MREQ, RD を出力し、
メモリに読み出し要求を伝える。
- WAIT の状態を調べ、もしアクティブなら 1 クロック後に
再び WAIT を調べる。
WAIT がアクティブでなければ、メモリから
DB に AB から指定した番地の内容が出力される。
- 1 クロック後に CPU はその内容を取り込んでレジスタに記憶する。
その後 MREQ, RD を H に戻す。

メモリ WRITE サイクルのタイムチャート
- 書き込む対象の番地を AB に出力する。
- 1/2 クロック後に MREQ を出力し、
メモリにアクセス要求を伝える。
- WAIT の状態を調べ、もしアクティブなら 1 クロック後に
再び WAIT を調べる。
WAIT がアクティブでなければ、CPU は WR
を出力し、メモリはそれを認識した後に DB からデータを
取り込み AB から指定した番地にその内容を記録する。
- 1 クロック後に CPU は MREQ, RD を H に戻す。
さらにその 1/2 クロック後に DB の出力を止める。
3.4.3 入出力装置のデータの読み出し/書き込みサイクル

IO READ サイクルのタイムチャート
- 入力対象の装置の番地を AB に出力する。
- 1 クロック後に IORQ, RD を出力し、
装置に読み出し要求を伝える。
- タイミング調整の Wait サイクルが 1 個挿入される。Wait サイクル中のクロック波形の
立ち下がりで
WAIT の状態を調べ、もしアクティブなら 1 クロック後に
再び WAIT を調べる。
WAIT がアクティブでなければ、装置から
DB にデータが出力される。
- 1 クロック後に CPU はその内容を取り込んでレジスタに記憶する。
その後 IORQ, RD を H に戻す。

IO WRITE サイクルのタイムチャート
- 出力対象の装置の番地を AB に出力する。少し後に DB にデータを出力する。
- 1 クロック後に IORQ, WR を出力し、
装置に書き込み要求を伝える。
- タイミング調整の Wait サイクルが 1 個挿入される。Wait サイクル中のクロック波形の
立ち下がりで
WAIT の状態を調べ、もしアクティブなら 1 クロック後に
再び WAIT を調べる。
WAIT がアクティブでなければ、少し後に装置が DB の
データを取り込む。
- 一定時間後に CPU は IORQ, WR を H に戻す。
さらにその 1/2 クロック後に DB の出力を止める。
3.4.4 バス要求及び確認サイクル

バス要求サイクルのタイムチャート
- 命令実行時の最後の T サイクルの立ち上がりで、BUSRQ の
状態を調べる。
- もし BUSRQ がアクティブなら 1 クロック後に
BUSAK をアクティブにして、同時に DB, AB,
MREQ, IORQ,
RD, WR, RFSH
をハイインピーダンス状態にしてバスと信号線を解放する。
その後は各 T サイクルの立ち上がりで BUSRQ の状態を調べる。
- BUSRQ が H に戻されると、
- その次の T サイクルの立ち上がりで検出する。
同じ T サイクル中に BUSAK を H に戻す。
バスと信号線は少し後に通常の状態に戻る。
- 次の T サイクルから命令実行を再開する。
4 アドレス方式
処理対象のデータがある場所を指定する方法で、
これをアドレスと呼ぶ。
例として、特定のレジスタ、任意のレジスタ、メモリのどこか、
レジスタの指定するメモリの場所、数値自体などがある。
データの種類は 8bits, 16 bits に大別される。
ここでは以下の 10 種類に分類する。
アドレス指定方法の分類
固有アドレス指定形式 |
拡張アドレス指定形式 |
直接数値指定形式 |
ページ 0 アドレス指定形式 |
拡張直接数値指定形式 |
相対アドレス指定形式 |
レジスタアドレス指定形式 |
インデックスアドレス指定形式 |
レジスタ間接アドレス指定形式 |
ビット指定形式 |
4.1 固有アドレス指定形式
命令コードが固定されていて変化しない。命令毎に特定のレジスタが使用される。
例
命令 機械語 説明
-------+-------+-------+-------+-------+-------+-------+-------+
CPL 2F A レジスタの反転
4.2 直接数値指定形式
命令コードとともに数値そのものを指定する。
例
命令 機械語 説明
-------+-------+-------+-------+-------+-------+-------+-------+
ADD A, 10 C6 0A A ← A + 10
4.3 拡張直接数値指定形式
2 バイトの数値そのものを指定する。
例
命令 機械語 説明
-------+-------+-------+-------+-------+-------+-------+-------+
LD BC, 1000H 01 00 10 BC ← 1000H
4.4 レジスタアドレス指定形式
データの入っているレジスタを指定する。
よく使われるアドレス方式で様々な命令で利用される。
例
命令 機械語 説明
-------+-------+-------+-------+-------+-------+-------+-------+
AND B A0 A ← A and B
この指定形式の命令は 1 バイトで表現され、上位 5 bits が命令を表し、下
位 3 bits がレジスタを表す (10100???)。例として AND 演算の場合は、上位 5 bits が 10100 である。
レジスタアドレス指定形式におけるレジスタの指定
下位 3 bits の値 |
選択されるレジスタ |
000 |
B |
001 |
C |
010 |
D |
011 |
E |
100 |
H |
101 |
L |
110 |
レジスタ間接アドレス |
111 |
A |
4.5 レジスタ間接アドレス指定形式
データの入っているメモリの番地をレジスタペアによって指定する。メモリ中
の連続した領域をアクセスする場合は拡張アドレスよりもプログラムサイズが
小さい。また繰り返しの処理を利用すると、処理速度はやや遅くなるが更にメ
モリの使用量が少なくなる。
例
命令 機械語 説明
-------+-------+-------+-------+-------+-------+-------+-------+
LD A, (BC) 0A A ← (BC)

メモリの連続した領域
LD BC, 2000H LD A, (2000H)
LD A, (BC) LD A, (2001H)
INC BC LD A, (2002H)
LD A, (BC) LD A, (2003H)
INC BC LD A, (2004H)
LD A, (BC)
INC BC
LD A, (BC)
INC BC
LD A, (BC)
LD A, (BC) は 1 バイト命令で 7 クロック、INC BC は 1 バイト命令で 6 クロック、LD A, (lm) は
3 バイト命令で 13 クロックなので実行時間は同じであるが、プログラムサイズが 2/3 になる。
4.6 拡張アドレス指定形式
データの入っているメモリの番地そのものを指定する。
例
命令 機械語 説明
-------+-------+-------+-------+-------+-------+-------+-------+
LD A, (1000H) 3A 00 10 A ← (1000H)
4.7 ページ 0 アドレス指定形式
プロセッサの再起動時にメモリの先頭の特定の番地にジャンプする。
特殊な指定方式で一般の命令では使えない。
例
命令 機械語 説明
-------+-------+-------+-------+-------+-------+-------+-------+
RST 38H FF PC ← 0038H
この指定形式の命令は 1 バイトで表現され、上位 2 bits、下
位 3 bits が 1 となる (11???111)。その間の 3 bits で番地を指定する。
ページ 0 アドレス指定形式における番地の指定
番地指定 3 bits の値 |
選択される番地 |
000 |
0000H |
001 |
0008H |
010 |
0010H |
011 |
0018H |
100 |
0020H |
101 |
0028H |
110 |
0030H |
111 |
0038H |
4.8 相対アドレス指定形式
現在の PC の示す値から近い番地にジャンプする場合に使われる。
8 bits の数値による番地指定である。絶対アドレスとの違いを理解する必要がある。
例
命令 機械語 説明
-------+-------+-------+-------+-------+-------+-------+-------+
JR Z, 10H 28 10 if (Zflag == 1) PC ← PC + 10H
4.8.1 相対アドレスと絶対アドレスの違い
絶対アドレス指定 :
16 bits で番地を指定するので、メモリの全体を指定できるが、命令が長くなる。
プログラムの再配置はできない。
相対アドレス指定 :
8 bits で番地を指定するので、メモリの一部しか指定できないが、命令が短い。
プログラムの再配置が可能。

相対アドレスと絶対アドレスによる番地指定
4.8.2 プログラムの再配置
プログラムが再配置可能とは、プログラムがメモリに置かれる位置に依存しな
いで正しく動作できることを表す。一般にプログラム内で番地指定をする部分
がすべて相対アドレス指定形式であると、そのプログラムは再配置可能となる。
例
再配置が可能な場合
ORG 1000H ; ; 実行開始番地を 1000H に指定
SUB B ; 90 ; A ← A - B
JR NZ, L1 ; 20 01 ; L1 に相対ジャンプ
INC A ; 3C ; A ← A + 1
L1 LD C, A ; 4F ; C ← A
HALT ; 76 ; 終了
この場合はアドレス指定が相対アドレスなので再配置可能となり、
メモリのどこに置いても正しく動作する。プログラム中には実行開始番地 1000H に
依存した値は存在しない。
再配置が不可能な場合
ORG 1000H ; ; 実行開始番地を 1000H に指定
SUB B ; 90 ; A ← A - B
JP NZ, L1 ; C2 05 10 ; L1 に絶対ジャンプ
INC A ; 3C ; A ← A + 1
L1 LD C, A ; 4F ; C ← A
HALT ; 76 ; 終了
この場合はアドレス指定が絶対アドレスなので再配置はできず、
1000H 番地以外に置いた場合正しく動作しない。プログラム中には実行開始番地
1000H に依存した値1005H があるため、
プログラムをどこに置いてもこの命令を実行すると必ず 1005H にジャンプする。
4.9 インデックスアドレス指定形式
インデックスレジスタ IX, IY と偏位置でメモリ中の番地を指定する。
レジスタ間接アドレスの発展形。
例
命令 機械語 説明
-------+-------+-------+-------+-------+-------+-------+-------+
LD (IX + 10H), B DD 70 10 (IX + 10H) ← B
4.10 ビット指定形式
8 bit データ中の特定のビットを指定して操作を行う場合の指定法。
特殊な指定方式で一般の命令では使えない。
例
命令 機械語 説明
-------+-------+-------+-------+-------+-------+-------+-------+
SET 2, C CB D1 C の 2 bit目 ← 1
RES 3, A CB 9F A の 3 bit目 ← 0
BIT 4, D CB 62 D の 4 bit目を調べて F をセット
4.11 練習問題
次の命令に含まれるアドレス指定方式を挙げなさい。
- LD A, B
- LD A, 10
- LD A, (1000H)
- LD A, (HL)
- LD HL, 1000H
- LD HL, (1000H)
- LD A, (IX + 10)
- JP NZ, 1000H
- JR NZ, 1000H
- NEG
5 命令の種類
命令を機能別に分類すると以下のようになる。
- 8 ビットのデータ移動
- 16 ビットのデータ移動
- 交換、ブロック転送、検索
- 8 ビット算術論理演算
- 汎用算術演算、CPU 制御
- 16 ビット算術演算
- 循環、桁移動
- ビット操作、判定
- 飛び越し
- サブルーチン接続、戻り
- 入出力
この中で使用頻度が高く重要なのは、1, 2, 4, 6, 9, 10 である。
次に重要なのが 5, 7 である。
5.1 8 ビットのデータ移動
一般形 LD *, * ; * はレジスタ、数値、メモリ中のデータなど
例 LD A, 23 ; A ← 23
LD B, H ; B ← H
LD C, (HL) ; C ← (HL)
LD (IX + 30H), D ; (IX + 30H) ← D
LD (1000H), A ; (1000H) ← A
5.2 16 ビットのデータ移動
一般形 LD *, * ; * はレジスタ(ペア)、数値、メモリ中のデータなど
例 LD BC, 100 ; BC ← 100
LD DE, (0010H) ; DE ← (0010H)
LD SP, FF00H ; SP ← FF00H
LD (1000H), HL ; (1000H) ← HL
5.3 交換、ブロック転送、検索
5.3.1 交換命令
例 EX DE, HL ; DE と HL の内容を入れ換える
EX AF, AF' ; AF について表と裏レジスタを入れ換える
EXX ; BC, DE, HL について表と裏を入れ換える
5.3.2 ブロック転送命令
LDI, LDD, LDIR, LDDR がある。これらの命令を使う時には、前もって BC に
転送バイト数、DE に送り先の先頭番地、HL にもとデータの先頭番地をセット
しておく。LDI は DE, HL が + され、LDD は - される。

LDI と LDD の違い
転送後、BC != 0 なら P/V フラグ = 1 となり、次のデータを転送するか判定
する際に使用される。プログラムは次のような形式になる。
LOOP LDI
JP PE, LOOP ; BC が 0 でなければ転送を続ける
なぜ LDI, LDD の 2 種類があるか ? → 転送領域が重なっていてもいいように。

転送領域が重なっている場合
もし転送領域が重なっている場合は、重なっている領域から転送を始める必要がある。
LDIR, LDDR は BC = 0 になったら転送を終了する。
5.3.3 検索命令
CPI, CPD, CPIR, CPDR がある。BC, DE, HL の設定は LDI 等と同じ。A レジスタと同じ値が
メモリ中で見つかると Z フラグが 1 になる。CPIR, CPDR では同じ値が見つかるか、指定した
バイト数検索した時に終了する。
5.4 8 ビット算術論理演算
一般形 ADD A, * ; A ← A + *
AND * ; A ← A and *
ADD, ADC, SBC は 16 ビット算術演算に同じ命令があるので、区別するために
A レジスタの指定が必要
例 ADD A, 10 ; A ← A + 10
ADC A, B ; A ← A + B + CY
SBC A, C ; A ← A - C - CY
SUB 5 ; A ← A - 5
AND B ; A ← A and B
OR C ; A ← A or C
XOR 10 ; A ← A xor 10
CP 5 ; A - 5 の結果によりフラグを設定する
INC B ; B ← B + 1
DEC D ; D ← D - 1
5.5 汎用算術演算、CPU 制御
例 CPL ; A ← A の 0/1 反転の結果
NEG ; A ← A の 2 の補数
SCF ; CY ← 1 、キャリフラグを 1 にする
CCF ; CY ← CY の 0/1 反転の結果
NOP ; 何もしない
DI ; IFF ← 1 、割り込みを許可しない
EI ; IFF ← 0 、割り込みを許可する
IM0 (IM1, IM2) ; 割り込みモードを 0 (1,2) にする
DAA ; A を BCD 数に変換する
5.6 16 ビット算術演算
例 INC BC ; BC ← BC + 1
DEC DE ; DE ← DE - 1
ADD HL, BC ; HL ← HL + BC
ADC HL, BC ; HL ← HL + BC + CY
SBC HL, BC ; HL ← HL - BC - CY
5.7 循環、桁移動
A レジスタの循環(回転)
例 RLA (RRA) ; A と CY を合わせて左(右)回転
RLCA (RRCA) ; A を左(右)回転、押し出されたビットは CY に

A レジスタの循環(回転)
2 進化 10 進数の循環(回転)
例 RLD (RRD) ; A と (HL) で 4 ビットずつ左(右)回転、BCD 数用

2 進化 10 進数の循環(回転)
レジスタの循環(回転)
例 RL (RR) B ; B と CY を合わせて左(右)回転
RLC (RRC) C ; C を左(右)回転、押し出されたビットは CY に

レジスタの循環(回転)
レジスタの桁移動(シフト)
例 SLA C ; C を左に算術シフト、押し出されたビットは CY に
SRA B ; B を右に算術シフト、押し出されたビットは CY に
SRL D ; D を右に論理シフト、押し出されたビットは CY に

レジスタの桁移動(シフト)
5.8 ビット操作、判定
例 BIT 2, C ; C の 2 ビット目を判定し、Z フラグをセットする
SET 3, B ; B の 3 ビット目を 1 にする
RES 4, D ; D の 4 ビット目を 0 にする
5.9 飛び越し
5.9.1 絶対アドレス指定
例 JP 1000H ; PC ← 1000H, 1000 番地に無条件ジャンプ
JP NZ, 1000H ; if (0 == Zflag) PC ← 1000H
条件付ジャンプの条件は次のものがある。
NZ : ノンゼロ Z : ゼロ NC : 桁上げ無 C : 桁上げ有
PO : 奇数 PE : 偶数 P : 正数 M : 負数
5.9.2 相対アドレス指定
例 JR 1000H ; 相対番地指定により 1000 番地にジャンプ
JR NZ, 1000H ; if (0 == Zflag) 1000 番地に
条件付ジャンプの条件は NZ, Z, NC, C となる。
DJNZ 1000H ; B ← B - 1, if (0 != B) PC ← 1000H
5.10 サブルーチン接続、戻り
例 CALL 1000H ; スタック ← PC, PC ← 1000H
CALL Z, 1000H ; if (1 == Zflag)
; スタック ← PC, PC ← 1000H
RET ; PC ← スタック
RET NC ; if (0 == CYflag) PC ← スタック
指定できる条件は条件付ジャンプと同じ 8 種類である。
RETI ; 割り込み処理ルーチンから戻る
RETN ; NMI 処理ルーチンから戻る
RST 38H ; スタック ← PC, PC ← 38H, リスタート
5.11 入出力
例 IN A, (0F0H) ; 0F0H で表される機器からデータを読み込む
IN B, (C) ; C で表される機器からデータを読み込む
OUT (0F0H), A ; 0F0H で表される機器にデータを出力する
OUT (C), B ; C で表される機器にデータを出力する
5.12 練習問題
5.12.1
次の機能を実現する命令を書きなさい。1 命令で実現できない場合は複数の命令を
組み合わせて実現しなさい。
- A ← 10
- A ← C
- A ← (1000H)
- A ← (BC)
- A ← (HL)
- A ← (IX + 10)
- C ← 10
- C ← A
- C ← (1000H)
- C ← (BC)
- C ← (HL)
- C ← (IX + 10)
- (2000H) ← 10
- (2000H) ← C
- (2000H) ← (1000H)
- (2000H) ← (BC)
- (2000H) ← (HL)
- (2000H) ← (IX + 10)
- (BC) ← 10
- (BC) ← C
- (BC) ← (1000H)
- (BC) ← (DE)
- (BC) ← (HL)
- (BC) ← (IX + 10)
- (HL) ← 10
- (HL) ← C
- (HL) ← (1000H)
- (HL) ← (DE)
- (HL) ← (IX + 10)
- BC ← 1000H
- BC ← DE
- BC ← (1000H),(1001H)
- (2000H) ← 1000H
- (2000H) ← DE
- (2000H) ← (1000H),(1001H)
- A ← B + C
- A ← B - C - CY
- A ← A AND 3
- A ← A XOR 1
- B ← B - 1
- A ← A の 0/1 反転
- A ← A の 2 の補数
- HL ← BC + DE
- A を右に算術シフト
- A を右に論理シフト
- A を左に算術シフト
- 1000H にジャンプ
- Z なら 1000H にジャンプ
- NC なら 1000H にジャンプ
- 1000H に相対ジャンプ
5.12.2
A レジスタが 11010010B, CY フラグが 1 のとき、次の操作を行なった後の A, CY の値
を示しなさい。
- RLA
- RRCA
- SRA A
- SLA A
- SRL A
6 フラグと算術演算
Z80CPU は F レジスタに 6 種の flag (Z, S, CY, P/V, H, N)を持つ。
この中で、Z, S, CY, P/V の 4 個は条件付ジャンプなどで利用される。
H, N は BCD 数の演算に関する flag であるが使用する機会は少ない。
一般的には flag に影響を与える命令の直後に条件判断を行う命令を実行する。
しかし flag に影響を与えない命令なら途中に実行してもよい。
例 ADD A, 10 ; flag がセットされる
; flag に影響なければ命令を実行してよい
JP NZ, LOOP ; ここで Zflag を参照している
6.1 ゼロフラグ Z
内容 :
命令の実行結果が 0 なら 1 に、0 以外なら 0 になる。
- 転送したデータが 0 のとき
- 演算結果が 0 のとき
- 指定したビットが 0 のとき
などに 1 になる。
利用される場合 :
- 比較した二つの数が等しいかどうか
- ビット判定におけるゼロ判定
- 算術演算、論理演算の実行結果のゼロ判定
- 命令の実行結果のゼロ判定
例 CP 10 ; A レジスタが 10 かどうか
JP NZ, L1 ; もしゼロでなければ L1 に飛ぶ
6.2 符号フラグ S
内容 :
命令の実行結果が負数なら 1、正数なら 0 になる。
演算、桁移動、比較命令などに影響を受ける。
利用される場合 :
- 二つの演算数の大小判定
- 算術演算、論理演算の実行結果の正負の判定
- 命令の実行結果の正負の判定
例 CP 10 ; A レジスタが 10 より大きいか
JP P, L1 ; 10 <= A なら L1 に飛ぶ
6.3 桁上げフラグ CY
内容 :
加減算で桁上がり、桁借りがあれば 1、なければ 0 になる。
算術演算、桁移動命令にのみ影響を受ける。論理演算では常にゼロになる。
利用される場合 :
- 二つの演算数の大小判定
- 桁移動の結果はみ出したビットの判定
- 多重精度算術演算を実現する時
- 符号無数の算術演算で表現可能範囲を超えていないか
例 CP 10 ; A レジスタが 10 より大きいか
JP NC, L1 ; 10 <= A なら L1 に飛ぶ
6.4 パリティ / あふれフラグ P/V
内容 :
演算結果のビットパターンで 1 の個数が偶数なら 1、奇数なら 0 になる。
算術演算の結果あふれが発生したら 1、発生していなければ 0 になる。
論理演算、桁移動命令ではパリティを表し、算術演算ではあふれを表す。
利用される場合 :
- 論理演算の結果で 1 の個数の判定
- 桁移動の結果で 1 の個数の判定
- 符号付数の算術演算で表現可能範囲を超えていないか
例 AND 0FH ; A レジスタの下位 4 ビットの 1 の個数を数える
JP PE, L1 ; 1 の個数が偶数なら L1 に飛ぶ
ADD A, 100 ; A レジスタ に 100 を加える
JP PE, L1 ; 符号付数としてあふれていたら L1 に飛ぶ
6.5 練習問題
次の条件判断を実現する命令列を示しなさい。条件に合わなければ L2 にジャンプする
ようにしなさい。
例 A が 0 なら L1 にジャンプする。
CP 0
JP Z, L1
JP L2
- A と B を比較して A < B なら L1 にジャンプする。
- A と B を比較して A <= B なら L1 にジャンプする。
- A と B を比較して A == B なら L1 にジャンプする。
- A と B を比較して A != B なら L1 にジャンプする。
- A と B を比較して B < A なら L1 にジャンプする。
- A と B を比較して B <= A なら L1 にジャンプする。
- 符号付数として A + B を計算した時、あふれがあれば L1 にジャンプする。
- 符号無数として A + B を計算した時、あふれがあれば L1 にジャンプする。
- A の上位 6 桁の 1 の個数が奇数なら L1 にジャンプする。
- A を 1 ビット左にシフトした時、はみ出したビットが 1 なら L1 にジャンプする。
7 Z80 用アセンブリ言語
7.1 記述方法
Z80 用アセンブリ言語の 1 行は以下の 4 つのフィールドで構成される。
ラベル(:)
オペコード
オペランド
; コメント
例
LOOP
LD
A, 30
; A レジスタに 30 を代入する
- ラベルは必要に応じて書くことができる
- オペコードは命令を表す
- オペランドは命令に対してレジスタやデータを指定する
- コメントは ; 以後に書くことができる、省略可能
- オペコードのみの命令の場合、オペランドは書かない
- 行頭に ; を書いた場合、その行はすべてコメントになる
7.1.1 プログラムの書き方
ORG 1000H
LD A, 10 ; LD のサンプル
LD B, 10
ADD A, B
LD (2000H), A
HALT
END
7.2 使用できる文字
A -- Z, 0 -- 9, +, -, (, ), ","
; コメントの始まり
: ラベルとオペコードの区切り, 書かない処理系も存在する
' 文字定数を表す
空白, TAB オペコードとオペランドの区切り
CR 行の終り
7.3 定数の表現
表現可能な定数の種類
形式 |
記号 |
例 |
10 進定数 |
0 -- 9 |
123D |
16 進定数 |
0 -- 9, A -- F |
3AH, 0FA00H |
8 進定数 |
0 -- 7 |
123O |
2 進定数 |
0, 1 |
01011110B |
文字定数 |
引用符で囲む |
'ABCD' |
- 数値の直後の D, H, O, B が各々の形式を表す
- 10 進定数の D は省略可能
7.4 ラベル記述のルール
ラベル : プログラム中で番地の数値を直接記述する代わりに記号で番地を表したもの。
数値への変換はアセンブラが自動的に行う。
- 6 文字以内の英数字、7 文字目以後は無視される
- 先頭の文字はアルファベット
- 予約語と同じではいけない
ラベルを使わない書き方
ORG 1000H
LD A, 10 ; 1000H
LD B, 10 ; 1002H
ADD A, B ; 1004H
CP 100
JR M, 1004H ; 1004H を自分で書く必要がある
HALT
END
ラベルを使った書き方
ORG 1000H
LD A, 10
LD B, 10
LOOP ADD A, B
CP 100
JR M, LOOP ; 番地を直接書かなくてもよい
HALT
END
7.5 予約語
予約語 : プログラムを書く時にラベル等に使ってはいけない単語
A, B, C, D, E, F, H, L, AF, BC, DE, HL, IX, IY, SP
C, NC, Z, NZ, M, P, PE, PO
命令語は予約語にされる場合とされない場合がある。(処理系依存)
7.6 オペランドとして書ける内容
レジスタ名 LD A, B
ADD HL, BC
フラグの状態 JR NZ, LOOP
数値定数 LD A, 10H
文字定数 LD A, 'B'
命令(定数)に付けたラベル (DATA EQU 100)
ADD A, DATA
リファレンスカウンタの値 JP $ - 5
算術式 LD A, DATA + 10
LD A, 30 + 10
数値定数 LD (0FF12H), BC
命令(定数)に付けたラベル LD BC, (DATA)
算術式 LD BC, (DATA + 10)
(リファレンスカウンタ : その時点の PC の値)
7.7 疑似命令
機械語には変換されない(対応しない)が、アセンブリ言語で効率的にプログラ
ムが記述できるように用意されている命令で以下の種類がある。
ORG n
END
n1 EQU n2
(Label) DEFB n ; DB とも書く
(Label) DEFW n ; DW とも書く
(Label) DEFS n ; DS とも書く
(Label) TXT string ; DEFM, DM とも書く
ORG : プログラムの開始番地を指定する
例
ORG 1000H
END : プログラムの終りを表す
EQU : 記号を数値に対応させる ($:PC も指定可能)
例
MAX EQU 100
DEFB : 1 バイトの領域を確保し、値を n にする
例
DEFB 10 ; ('A' という書き方が可能な場合もある)
DEFW : 1 ワード(16 ビット)の領域を確保し、値を n にする
例
DEFW 10 ; ('AB' という書き方が可能な場合もある)
DEFS : n バイトの領域を確保する。初期化はしない。
例
DEFS 10
TXT : 指定された文字列の長さ分の領域を確保し、文字列を書き込む
例
TXT 'ABCD' ; ($ABCD$ という書き方もある)
7.8 アセンブリ言語によるプログラミングの例
7.8.1 DATA1 番地から MAX 個のデータを足して RESULT に記録する
MAX EQU 5 ; データの個数
ORG 1000H ; 1000H 番地からスタート
START XOR A ; 答を入れる A をゼロクリア
LD IX, DATA1 + MAX - 1 ; IX にデータの最後の番地
LD B, MAX ; 個数のカウンタをセットする
LOOP ADD A, (IX) ; データの最後から足していく
DEC IX ; アドレスを 1 前にずらす
DEC B ; 1 回足したので個数を 1 減らす
JP NZ, LOOP ; ゼロでなければ繰り返し
LD (RESULT), A ; 答の記録
HALT ; ストップ
DATA1 DEFB 3 : MAX 個のデータ
DEFB 7
DEFB 5
DEFB 1
DEFB 2
RESULT DEFS 1 ; 答を入れる場所
END
7.8.2 DATA1 番地のデータを 4 倍して RESULT に記録する
ORG 1000H ; 1000H 番地からスタート
START LD A, (DATA1) ; A に (DATA1) をセット
SLA A ; 2 倍
SLA A ; 2 倍
LD (RESULT), A ; 答の記録
HALT ; ストップ
DATA1 DEFB 3 : もとのデータ
RESULT DEFS 1 ; 答を入れる場所
END
7.8.3 (DATA1) と (DATA2) の大きい方を RESULT に記録する
ORG 1000H ; 1000H 番地からスタート
START LD A, (DATA1) ; A に (DATA1) をセット
LD B, A
LD A, (DATA2) ; A に (DATA2) をセット
CP B ; A, B の比較
JP NC, L1 ; A >= B なら CY は立たず、L1 へ
LD A, B : A < B なら A ← B
L1 LD (RESULT), A ; 答の記録
HALT ; ストップ
DATA1 DEFB 3 : もとのデータ
DATA2 DEFB 5 :
RESULT DEFS 1 ; 答を入れる場所
END
7.8.4 DATA1 × DATA2 を求める
ORG 1000H
START LD A, (DATA1)
LD C, A
LD A, (DATA2)
LD B, A ; B は繰り返し回数とする
LD A, 0 ; 答を入れる A をゼロクリア
INC B ; DEC B でフラグを立てるため
JR L2
L1 ADD A, C ; C を足していく
L2 DEC B ; 繰り返し回数を 1 減らす
JR NZ, L1 ; B != 0 なら繰り返し
LD (RESULT), A ; 答を記録
HALT
DATA1 DEFB 3
DATA2 DEFB 5
RESULT DEFS 1 ; 結果は C+C+C+...+C となる
END
7.9 ハンドアセンブルの方法
- 各命令のバイト数を調べる
- アドレスを割り当てる
- 命令語を探して書く
(1) (2) (3)
START LD A, (DATA1) ; 3 1000 3A 0B 10
SLA A ; 2 1003 CB 27
SLA A ; 2 1005 CB 27
LD (RESULT), A ; 3 1007 32 0C 10
HALT ; 1 100A 76
DATA1 DEFB 3 : 1 100B 03
RESULT DEFS 1 ; 1 100C ??
END
7.10 練習問題
次の機能を実現するプログラムを Z80CPU のアセンブリ言語で作成しなさい。
(????) はメモリの ???? 番地のデータを表す。== は値が等しいこと、
!= は等しくないことを表す。
- A + B + C - D を (DATA1) に入れる
- (DATA1) + 100 を (DATA2) に入れる
- (DATA1) + (DATA2), (DATA1) - (DATA2) を (DATA3), (DATA4) に入れる
- (DATA1) * 3 を (DATA2) に入れる
- (DATA1) * 5 を (DATA2) に入れる (シフト命令を使うこと)
- (DATA1), (DATA2) の小さい方を (DATA3) に入れる
- (DATA1), (DATA2), (DATA3) の最小の値を (DATA4) に入れる
- (DATA1) == (DATA2) なら 0 を、(DATA1) != (DATA2) なら 0 以外を (DATA3) に入れる
- (DATA1) == 3 なら +1 して、(DATA1) != 3 なら -1 して (DATA2) に入れる
- (DATA1) が奇数なら 1 を、偶数なら 0 を (DATA2) に入れる
プログラムの例「(DATA1) と (DATA2) の大きい方を RESULT に記録する」をハンドアセンブルして
機械語のプログラムを示しなさい。