はじめに

Z80 は 1980 年頃によく使われた 8bit CPU です。 搭載されていたパソコンでは、NEC の PC-8001/PC-8801 シリーズが有名です。

当時のほとんどのパソコンには BASIC 言語が内蔵されていましたが動作が遅く、 コンパイル言語はほとんど普及していなかったため、 もっと処理速度が必要なゲームなどを作るときには Z80 アセンブリ(当時は「マシン語」という言葉がよく使われていました) で頑張って記述していました。

今回「Z80 で円周率を計算」を書いていて、初めは「Z80 に関する詳しいことはググってください」で済ませようかと思ったのですが、 ある程度の知識を前提にしないと解説しにくいので書くことにしました。




基本事項


レジスタ

Z80 には比較的多くのレジスタ(register)があります。 レジスタというのは、メモリ空間とは別の一時記憶です。 図示すると以下のようになります。



F(フラグ)レジスタは、 命令実行の結果によって変化するフラグ(1bit)の集合体です。 各条件が成立すると 1 になります(「立つ」と表現します)。 ただし命令によっては変化しなかったり、条件が異なったりするので、 以下の説明は参考程度にしてください。

ほとんどの場合、Z フラグと C フラグで事足りると思います。 この 2 つは特にどの命令で変化するかに注目しておいてください。




転送命令

ここからは各命令の解説です。まずは一番よく出てくる LD 命令で、次の形式になっています。


命令 動作
LD dest,src dest←src

LD は LoaD の略で、データを右から左へ転送します。 CPU によっては、メモリが転送元か転送先かによって load と store に分かれていたりしますが、Z80 では全て LD です。

なお、「LD」の部分を「オペコード(op code)」、 「dest,src」の部分を「オペランド(operand)」と言います。

LD 命令では、一部の特殊な命令(LD A,ILD A,R)を除いて、フラグが一切変化しません。 大事なことなのでよく覚えておいてください。


命令 動作
LD r,r' r←r'

r(と r')は 8bit レジスタ B,C,D,E,H,L,A のいずれかを指します。 今後この表記はよく出てくるので覚えておいてください。

これらの 8bit レジスタ間では全ての組み合わせがありますが、 メモリアクセスに関するものは組み合わせが限られています。


命令 動作
LD r,n r←n
LD r,(HL) r←(HL)
LD A,(BC)
LD A,(DE)
A←(BC)
A←(DE)
LD A,(nn) A←(nn)
LD (HL),r (HL)←r
LD (BC),A
LD (DE),A
(BC)←A
(DE)←A
LD (nn),A (nn)←A
LD (HL),n (HL)←n

n は任意の 8bit 値、nn は任意の 16bit 値です。

オペランドの各要素が括弧で囲まれている場合は、 基本的にメモリアクセスを意味します(IN, OUT, JP 命令は例外)。

(HL) に関するものは、(IX+d)(IY+d) に置き換えたものもあります。


命令 動作
LD r,(IX+d)
LD r,(IY+d)
r←(IX+d)
r←(IY+d)
LD (IX+d),r
LD (IY+d),r
(IX+d)←r
(IY+d)←r
LD (IX+d),n
LD (IY+d),n
(IX+d)←n
(IY+d)←n

d は符号付き 8bit 値で、-80H~+7FH の範囲を指定できます。 インデックスレジスタはこのようにオフセット付きでメモリアクセスできますが、 動作速度はかなり遅いので、 速度の要求されるプログラムではあまり活躍しません。


LD rr,nn
LD IX,nn
LD IY,nn
rr←nn
IX←nn
IY←nn
LD rr,(nn)
LD IX,(nn)
LD IY,(nn)
rrL←(nn), rrH←(nn+1)
IXL←(nn), IXH←(nn+1)
IYL←(nn), IYH←(nn+1)
LD (nn),rr
LD (nn),IX
LD (nn),IY
(nn)←rrL, (nn+1)←rrH
(nn)←IXL, (nn+1)←IXH
(nn)←IYL, (nn+1)←IYH

rr は 16bit レジスタ BC,DE,HL,SP のいずれかを指します。

16bit メモリアクセスについてですが、Z80 では 16bit データは「下位 8bit, 上位 8bit」の順になることに注意してください。 これを「リトルエンディアン(little endian)」と言います。

CPU によっては「上位 8bit, 下位 8bit」の順のものもあり、こちらは「ビッグエンディアン(big endian)」 と言います。

残りの LD 命令は以下の通りです。16bit レジスタ間の LD 命令は他にはありません。


LD SP,HL
LD SP,IX
LD SP,IY
SP←HL
SP←IX
SP←IY
LD A,I A←I
LD I,A I←A
LD A,R A←R
LD R,A R←A



交換命令

交換命令には EX 命令(EXchange)と EXX 命令があります。 いずれもフラグは変化しません。


命令 clk 動作
EX DE,HL 4 DE←→HL
EX AF,AF' 4 AF←→AF'
EXX 4 BC←→BC', DE←→DE', HL←→HL'

16bit レジスタでは HL が演算やメモリアクセスの中心なので、EX DE,HL で挟んで DE レジスタも活用することがよくあります。

EX AF,AF'EXX は表レジスタと裏レジスタを交換します。裏レジスタを操作する命令はこの 2 つだけです。

ここでは特別に clk 数も記載しましたが、いずれも 4clk と最低限で済み、高速化によく使われます。

ちなみに裏レジスタは、 本来は割り込み処理でレジスタをすばやく退避するためのものだと思われます。 メイン処理で使う場合にはそのことを考慮する必要があります。


命令 動作
EX (SP),HL
EX (SP),IX
EX (SP),IY
(SP)←→第 2 オペランドの下位 8bit,
(SP+1)←→第 2 オペランドの上位 8bit

これらはスタックトップと 16bit レジスタを交換します。




算術演算命令

Z80 の算術演算命令は、主に加減算命令です。乗除算はありません。

まずは 1 足す INC(INCrement)命令です。


命令 フラグ変化
S Z H P N C
動作
INC r * * * V 0 - r←r+1
INC (HL)
INC (IX+d)
INC (IY+d)
* * * V 0 - (HL)←(HL)+1
(IX+d)←(IX+d)+1
(IY+d)←(IY+d)+1
INC rr
INC IX
INC IY
- - - - - - rr←rr+1
IX←IX+1
IY←IY+1

8bit 演算では C フラグ以外のフラグが変化しますが、16bit 演算では変化しないことに注意してください。

DEC(DECrement)は 1 引く命令で、N フラグが 1 になる以外は INC と同様です。

次に加算命令 ADD です。


命令 フラグ変化
S Z H P N C
動作
ADD A,r * * * V 0 * A←A+r
ADD A,n * * * V 0 * A←A+n
ADD A,(HL)
ADD A,(IX+d)
ADD A,(IY+d)
* * * V 0 * A←A+(HL)
A←A+(IX+d)
A←A+(IY+d)
ADD HL,rr
ADD IX,ii
ADD IY,ii
- - ? - 0 * HL←HL+rr
IX←IX+ii
IY←IY+ii

ii は第 1 オペランドが IX なら BC,DE,IX,SP、IY なら BC,DE,IY,SP のいずれかを指します。

8bit 演算ではフラグが一通り変化しますが、16bit 演算ではあまり変化しないことに注意してください。

加算命令には ADC(ADd with Carry flag)という、C フラグも一緒に足す命令もあります。


命令 フラグ変化
S Z H P N C
動作
ADC A,r * * * V 0 * A←A+r+Cflag
ADC A,n * * * V 0 * A←A+n+Cflag
ADC A,(HL)
ADC A,(IX+d)
ADC A,(IY+d)
* * * V 0 * A←A+(HL)+Cflag
A←A+(IX+d)+Cflag
A←A+(IY+d)+Cflag
ADC HL,rr * * ? V 0 * HL←HL+rr+Cflag

16bit 演算には ADD と違ってインデックスレジスタに関するものはありません。 また、フラグは全て変化します。

ADD、ADC と同様に、減算には SUB(SUBtract)、SBC(SuBtract with Carry flag)命令があります。


命令 フラグ変化
S Z H P N C
動作
SUB r * * * V 1 * A←A-r
SUB n * * * V 1 * A←A-n
SUB (HL)
SUB (IX+d)
SUB (IY+d)
* * * V 1 * A←A-(HL)
A←A-(IX+d)
A←A-(IY+d)
SBC A,r * * * V 1 * A←A-r-Cflag
SBC A,n * * * V 1 * A←A-n-Cflag
SBC A,(HL)
SBC A,(IX+d)
SBC A,(IY+d)
* * * V 1 * A←A-(HL)-Cflag
A←A-(IX+d)-Cflag
A←A-(IY+d)-Cflag
SBC HL,rr * * ? V 1 * HL←HL-rr-Cflag

SUB 命令にオペランドが 1 つしか無いのは、ADD と違って SUB は A レジスタとの演算しか無く、「A,」が省略されているためです。つまり SUB HL,rr などの 16bit 演算命令はありません。C フラグを 0 にしてから SBC 命令を実行するか、8bit 命令を組み合わせることで代用します。

SUB 命令は A レジスタに結果が残りますが、残らずにフラグ変化だけする CP(ComPare)という命令があります。値の比較のために使用します。


命令 フラグ変化
S Z H P N C
動作
CP r * * * V 1 * A-r
CP n * * * V 1 * A-n
CP (HL)
CP (IX+d)
CP (IY+d)
* * * V 1 * A-(HL)
A-(IX+d)
A-(IY+d)

その他の算術命令には、以下のものがあります。


命令 フラグ変化
S Z H P N C
動作
CPL - - 1 - 1 - A←not A
NEG * * * V 1 * A←0-A

CPL(ComPLement)命令は A レジスタの全ビットを反転します(1 の補数)。

NEG(Negate)命令は A レジスタの符号を反転します(2 の補数)。ちなみに CPLINC A でも計算結果は同じですが、フラグ変化が違います。

最後にもう一つ、加減算に関する特殊な命令があるので、 ここで解説しておきます。


命令 clk 動作
DAA 4 A←packed BCD 補正した A

8bit 加減算命令(のうちフラグが全て変化するもの)の実行直後に DAA(Decimal Adjust Accumulator)命令を実行すると、演算が packed BCD(BCD=Binary Coded Decimal、上位 4bit と下位 4bit で 10 進数 2 桁と見なす)で行われたものとして A レジスタとフラグを補正します。

最初にこの命令を知ったときには「えっ、たった 4clk でそんなことできるの?」と驚きました。うまくできてますね。




論理演算命令

論理演算命令には AND、OR、XOR(eXclusive OR)の 3 種類があります(論理演算についての説明は省略します)。 いずれも A レジスタとの演算しか無いため、オペランドは省略して 1 つだけになっています。


命令 動作
AND r A←A and r
AND n A←A and n
AND (HL)
AND (IX+d)
AND (IY+d)
A←A and (HL)
A←A and (IX+d)
A←A and (IY+d)

OR、XOR についても同様です。フラグ変化についてですが、


命令 フラグ変化
S Z H P N C
AND * * 1 P 0 0
OR * * 0 P 0 0
XOR * * 0 P 0 0

となっており、いずれも C フラグが 0 になります。Z80 には他に C フラグを直接 0 にする命令が無いので、これらの命令が利用されます(ちなみに 2 命令なら SCFCCF という方法はあります)。

特に AND AOR A は A レジスタを壊さずに 0 かどうかや正負の判定もできますし、XOR A は A レジスタを 0 にするためによく使われます。




退避命令

退避命令は 16bit レジスタの値をスタックに退避/復帰する命令です。 PUSH は退避、POP は復帰です。


命令 動作
PUSH qq
PUSH IX
PUSH IY
(SP-1)←qqH, (SP-2)←qqL,SP←SP-2
(SP-1)←IXH, (SP-2)←IXL,SP←SP-2
(SP-1)←IYH, (SP-2)←IYL,SP←SP-2
POP qq
POP IX
POP IY
qqL←(SP), qqH←(SP+1), SP←SP+2
IXL←(SP), IXH←(SP+1), SP←SP+2
IYL←(SP), IYH←(SP+1), SP←SP+2

qq は BC,DE,HL,AF のいずれかです。 いずれもフラグは基本的に変化しませんが、POP AF は F レジスタに戻すため、その値がフラグに反映されます。




分岐命令

分岐命令はプログラムの流れを変える命令です。 いずれもフラグは変化しません。

まずは JP(JumP)命令です。


命令 clk 動作
JP nn 10 PC←nn
JP cc,nn 10 if (cc) PC←nn

無条件にジャンプするものと、 フラグの状態によってジャンプするかどうかが変わるものがあります。 いずれも実行時間は同じ 10clk です。 cc については以下の通りです。


cc 成立条件
NZ Z=0(Non Zero)
Z Z=1(Zero)
NC Cflag=0(Non Carry)
C Cflag=1(Carry)
PO P/V=0(Parity Odd)
PE P/V=1(Parity Even)
P S=0(Plus)
M S=1(Minus)

直接アドレスを指定する以外に、 レジスタの指すアドレスにジャンプする命令もあります。 オペランドになぜか括弧が付いているのですが、 メモリからアドレスを読み出すわけではないので注意してください。


命令 clk 動作
JP (HL) 4 PC←HL
JP (IX)
JP (IY)
8 PC←IX
PC←IY

次に相対ジャンプ命令です。


命令 clk 動作
JR e 12 PC←PC+e
JR cc,e 12/7 if (cc) PC←PC+e
分岐時 12clk/非分岐時 7clk
DJNZ e 13/8 B←B-1, if (B≠0) PC←PC+e
分岐時 13clk/非分岐時 8clk

JR(Jump Relative)命令は、次の命令アドレスを基準にして -80H~+7FH の範囲にジャンプできます。JP と同様にフラグの状態によるジャンプもありますが、cc には NZ,Z,NC,C しか使えません。また、分岐時には JP より遅いことにも注意してください。

DJNZ(Decrement and Jump if Non Zero)は、DEC BJR NZ,e をまとめたような命令です(ただしフラグは変化しません)。 実行時間も少し短くて、ループ処理に便利です。

次にサブルーチン呼び出しのための命令です。


命令 clk 動作
CALL nn 17 (SP-1)←PCH, (SP-2)←PCL,
SP←SP-2, PC←nn
CALL cc,nn 17/10 if (cc) (SP-1)←PCH, (SP-2)←PCL,
SP←SP-2, PC←nn
分岐時 17clk/非分岐時 10clk
RET 10 PCL←(SP), PCH←(SP+1), SP←SP+2
RET cc 11/5 if (cc) PCL←(SP), PCH←(SP+1), SP←SP+2
分岐時 11clk/非分岐時 5clk

CALL 命令はスタックに PC を退避してからジャンプし、RET(RETurn)命令はスタックから PC に戻します。いずれも JP 命令と同様に、フラグの状態によるものもあります。

他に RETI、RETN という割り込み処理用の命令もありますが、解説は省略します。

もう一つ、RST(ReSTart)という命令があります。


命令 clk 動作
RST p 11 (SP-1)←PCH, (SP-2)←PCL, SP←SP-2,
PCL←p, PCH←0

CALL 命令の一種なのですが、アドレスが「0000H~0038H のうち 8 の倍数」と限定されています。命令が 1Byte で済むので、 頻繁に使用するサブルーチンを配置することでプログラムサイズを節約できます (もちろん、そのあたりに配置できるなら、ですが)。




ローテート/シフト命令

ローテート/シフト命令は、 レジスタやメモリの値をビット単位でずらす命令です。 ずらし方によっていろいろな命令があります。


命令 動作
RLC r Cflag←r7..0←r7
RLC (HL)
RLC (IX+d)
RLC (IY+d)
Cflag←(HL)7..0←(HL)7
Cflag←(IX+d)7..0←(IX+d)7
Cflag←(IY+d)7..0←(IY+d)7
RRC r r0→r7..0→Cflag
RRC (HL)
RRC (IX+d)
RRC (IY+d)
(HL)0→(HL)7..0→Cflag
(IX+d)0→(IX+d)7..0→Cflag
(IY+d)0→(IY+d)7..0→Cflag

ちょっと動作がわかりにくいかもしれませんが、RLC(Rotate Left Circular)命令と RRC(Rotate Right Circular)命令は、8bit 値をグルッと回した上で、飛び出たビットを C フラグに反映させます。


命令 動作
RL r Cflag←r7..0←Cflag
RL (HL)
RL (IX+d)
RL (IY+d)
Cflag←(HL)7..0←Cflag
Cflag←(IX+d)7..0←Cflag
Cflag←(IY+d)7..0←Cflag
RR r Cflag→r7..0→Cflag
RR (HL)
RR (IX+d)
RR (IY+d)
Cflag→(HL)7..0→Cflag
Cflag→(IX+d)7..0→Cflag
Cflag→(IY+d)7..0→Cflag

一方、RL(Rotate Left)命令と RR(Rotate Right)命令は、C フラグも含めてグルッと回します (今でもどっちがどっちだったか迷うことがあります)。

これらの命令には、A レジスタ専用命令もあります。


命令 動作
RLCA Cflag←A7..0←A7
RRCA A0→A7..0→Cflag
RLA Cflag←A7..0←Cflag
RRA Cflag→A7..0→Cflag

こちらは「A」の前にスペースが入らないことに注意してください。 1Byte 命令で 4clk と速いですが、フラグ変化が違います(Z,S,P/V フラグは変化しません)。

次にシフト命令です。3 種類あります。


命令 動作
SLA r Cflag←r7..0←0
SLA (HL)
SLA (IX+d)
SLA (IY+d)
Cflag←(HL)7..0←0
Cflag←(IX+d)7..0←0
Cflag←(IY+d)7..0←0
SRA r r7..0→Cflag
SRA (HL)
SRA (IX+d)
SRA (IY+d)
(HL)7..0→Cflag
(IX+d)7..0→Cflag
(IY+d)7..0→Cflag
SRL r 0→r7..0→Cflag
SRL (HL)
SRL (IX+d)
SRL (IY+d)
0→(HL)7..0→Cflag
0→(IX+d)7..0→Cflag
0→(IY+d)7..0→Cflag

SLA(Shift Left Arithmetical)と SRA(Shift Right Arithmetical)は「算術シフト」と言い、符号付きの値を 2 倍もしくは 1/2 にします(したがって SRA では bit7 は変化しません)。

一方 SRL(Shift Right Logical)は「論理シフト」と言い、符号無しの値を 1/2 にします。 こちらに左シフトが用意されていないのは、 算術シフトと結果が同じになるからです。

他に、ちょっと変わったローテート命令があります。


命令 動作
RLD A3..0←(HL)7..4←(HL)3..0←A3..0
RRD A3..0→(HL)7..4→(HL)3..0→A3..0

RLD(Rotate Left Decimal)命令と RRD(Rotate Right Decimal)命令は、A レジスタの下位 4bit と HL が指すメモリを、1bit ではなく 4bit 単位で回します。Decimal は packed BCD のことを指し、ようするに 10 進数 1 桁ずらすための命令です。




ビット操作命令

レジスタやメモリの 8bit のうち 1bit だけを対象にした命令があります。


命令 動作
RES b,r rb←0
RES b,(HL)
RES b,(IX+d)
RES b,(IY+d)
(HL)b←0
(IX+d)b←0
(IY+d)b←0
SET b,r rb←1
SET b,(HL)
SET b,(IX+d)
SET b,(IY+d)
(HL)b←1
(IX+d)b←1
(IY+d)b←1

b はビット位置(0~7、最下位が 0)です。RES(RESet)は 0 に、SET は 1 にします。いずれもフラグは変化しません。


命令 動作
BIT b,r Z←not rb
BIT b,(HL)
BIT b,(IX+d)
BIT b,(IY+d)
Z←not (HL)b
Z←not (IX+d)b
Z←not (IY+d)b

BIT 命令はビットの状態を Z フラグに反映させます。Z フラグは結果が 0 のときに立つ(1 になる)ので、ビットの値とは逆になることに注意してください。




ブロック転送命令

データをまとめて転送したいときに便利なのがブロック転送命令です。 LDIR(Load and Increment Repeat)命令と LDDR(Load and Decrement Repeat)命令があります。


命令 動作
LDIR (DE)←(HL), DE←DE+1, HL←HL+1, BC←BC-1,
BC=0 になるまで繰り返し
LDDR (DE)←(HL), DE←DE-1, HL←HL-1, BC←BC-1,
BC=0 になるまで繰り返し

HL が指すアドレスから DE が指すアドレスに BC バイト転送します。 HL と DE には、LDIR ではデータの先頭、LDDR ではデータの末尾を指定しておきます。

それぞれに、1Byte だけ転送する命令もあります。


命令 動作
LDI (DE)←(HL), DE←DE+1, HL←HL+1, BC←BC-1
LDD (DE)←(HL), DE←DE-1, HL←HL-1, BC←BC-1

これらの命令では、BC レジスタが 0 になったかどうかが P/V フラグに反映されます。BC=0 で P/V=0、他は P/V=1 になります。




ブロックサーチ命令

ブロック転送命令と似たものに、ブロックサーチ命令があります。 こちらはデータから特定の 8bit 値を探すために使われます。 CPIR(Compare and Increment Repeat)命令と CPDR(Compare and Decrement Repeat)命令、それとそれぞれの 1Byte 版があります。


命令 動作
CPIR A-(HL), HL←HL+1, BC←BC-1,
A=(HL) か BC=0 になるまで繰り返し
CPDR A-(HL), HL←HL-1, BC←BC-1,
A=(HL) か BC=0 になるまで繰り返し
CPI A-(HL), HL←HL+1, BC←BC-1
CPD A-(HL), HL←HL-1, BC←BC-1

CPIR と CPDR は A レジスタと HL が指すデータを比較していき、一致するか BC バイト比較したら終了します。HL には、CPIR ではデータの先頭、CPDR ではデータの末尾を指定しておきます。

いずれの命令も、一致したかどうかは Z フラグで判定できます。 また、BC=0 で P/V=0、他は P/V=1 になります。




I/O 操作命令

Z80 にはメモリ空間とは別に、アドレス 8bit/データ 8bit の I/O 空間というものがあり、専用命令でアクセスします。


命令 動作
IN A,(n) A←I/O port(n)
IN r,(C) r←I/O port(C)
OUT (n),A I/O port(n)←A
OUT (C),r I/O port(C)←r

また、ブロック転送命令と同様に I/O 空間に繰り返しアクセスする命令がありますが、詳しい解説は省略します。


命令 動作
INIR (HL)←I/O port(C), B←B-1, HL←HL+1,
B=0 になるまで繰り返し
INDR (HL)←I/O port(C), B←B-1, HL←HL-1,
B=0 になるまで繰り返し
INI (HL)←I/O port(C), B←B-1, HL←HL+1
IND (HL)←I/O port(C), B←B-1, HL←HL-1
OTIR B←B-1, I/O port(C)←(HL), HL←HL+1,
B=0 になるまで繰り返し
OTDR B←B-1, I/O port(C)←(HL), HL←HL-1,
B=0 になるまで繰り返し
OTI B←B-1, I/O port(C)←(HL), HL←HL+1
OTD B←B-1, I/O port(C)←(HL), HL←HL-1



その他の命令

命令 動作
SCF Cflag←1
CCF Cflag←not Cflag

C フラグを操作する命令です。SCF(Set Carry Flag)は 1 にし、CCF(Complement Carry Flag)は 0/1 を反転します。直接 0 にする方法は「論理演算命令」を参照してください。


命令 clk 動作
NOP 4 何もしない

NOP(No OPeration)命令は何もしません。何もしないとは言っても 4clk かかるので、少し待ちたいとき(I/O ポートへの出力など)に使われたりします。 ちなみに命令コードは 00H ですが、たいていの CPU では 00H 以外に割り当てられています。


命令 動作
DI IFF1←0, IFF2←0(割り込み禁止)
EI IFF1←1, IFF2←1(割り込み許可)
IM m 割り込みモード←m
HALT 実行停止(割り込み/リセット待ち)

DI(Disable Interrupt)は割り込み禁止、EI(Enable Interrupt)は割り込み許可状態にします。

IM(Interrupt Mode)命令は割り込みモード(0~2) を切り替えます。詳しいことは省略します。

HALT 命令は割り込みかリセットがかかるまで停止します(実際には NOP を実行し続けます)。




最適化について

Z80 は命令セットや挙動に偏りが多いため、 さまざまな高速化の余地があります。ここからは主に高速化のテクニックを、 プログラムサイズについても気にしながら紹介していきます。

なお、高速化には各命令の clk 数を知っておく必要がありますが、 メモリアクセスは 1Byte につき 3clk ということを知っていると、多少は覚えやすくなると思います (ちなみに命令の読み込みもメモリアクセスです)。

あと、参考リンクをいくつか挙げておきます。



基本的な技
ゼロチェック

レジスタの値が 0 かどうかを調べたいことはよくあります。「0 なら Z フラグを立てる(1 にする)」方法をいくつか紹介します。

まず A レジスタなら CP 0 が思い付くかもしれませんが、これは 2Byte 7clk です。

しかし AND A/OR A なら 1Byte 4clk で済みます。

その他の 8bit レジスタの場合、たとえば B レジスタなら、

	LD A,B
	AND A	; または OR A

で調べられます。これは A レジスタや C フラグを壊してしまいますが、

	INC B
	DEC B

なら壊さずに済みます。 どちらも 2Byte 8clk です。

16bit レジスタの場合は BC/DE/HL に限定されますが、たとえば BC レジスタなら、

	LD A,B
	OR C

で調べられます。ちなみに 16bit レジスタの INC/DEC ではフラグが変化しないので注意してください。

C フラグを 0 にする

AND/OR/XOR いずれかで 0 になりますAND A/OR A/XOR A を使用することが多いでしょう。

もし Z フラグや S フラグを変化させたくないのであれば、2 命令になってしまいますが、

	SCF
	CCF

という方法があります。

A レジスタを 0 にする

LD A,0 は 2Byte 7clk ですが、XOR ASUB A なら 1Byte 4clk です。

ただし LD A,0 がフラグ変化しないのに対して、XOR ASUB A も全てのフラグが変化します。特に C フラグは 0 になります。状況に応じて使い分けましょう。

分岐命令の選択

絶対アドレス指定の JP は全て 10clk です。条件付きの分岐時/非分岐時も全て同じです。

JP と比べると、相対アドレス指定の JR は分岐時は遅く、非分岐時は速いです。表にすると、


命令 分岐時 clk 非分岐時 clk 命令バイト数
JP nn
JP cc,nn
10 10 3
JR e
JR cc,e
12 7 2

となります。 一長一短あるので、状況に応じて使い分けましょう。

16bit 符号反転

A レジスタの符号反転は NEG でできますが、16bit レジスタの場合は、

	XOR A
	SUB C
	LD C,A
	SBC A,A
	SUB B
	LD B,A

と 0 から引くことで符号反転できます。 6Byte 24clk です。

そして条件がかなり限定されますが、

	XOR A
	LD H,A
	LD L,A
	SBC HL,BC

なら 5Byte 27clk になります。

16bit 加減算

HL レジスタに関する加減算命令ですが、ADD HL,rr は 11clkADC HL,rrSBC HL,rr は 15clk です。つまり定数を引くだけなら、SBC で引くよりも、符号を逆にした値を ADD で足すほうが速く、先に C フラグをクリアしておく必要も無くなります。

ただし計算後のフラグ変化が異なることには注意してください。

データ転送

ブロック転送命令 LDIR/LDDR は最後の 1Byte 以外は 21clk で最後だけ 16clk です。

しかし 1Byte だけ転送する LDI/LDD は 16clk です。つまり LDI/LDD を並べると、1Byte につき 5clk ずつ節約できます。

もちろんプログラムサイズが増えるので、 ある程度並べてループするのがいいでしょう。

領域クリア

広い範囲を 0 クリアしたいなど、メモリを同じ値で埋めたいときは、

	LD HL,START
	LD DE,START+1
	LD BC,SIZE-1
	LD (HL),0
	LDIR

などと LDIR を使用するのが簡単です。 プログラムサイズも小さいので、 よほどの速度が要求されない限りはこれでいいでしょう。 転送サイズは 1 引くのを忘れずに。




やや危ない技
領域クリア

先ほどの方法とは違って条件付きになりますが、

	DI
	LD (SP_TMP),SP
	LD SP,START+SIZE
	LD DE,0
	PUSH DE
	PUSH DE
	PUSH DE
	  :
	LD SP,(SP_TMP)
	EI

などと PUSH を並べる方法があります。仮に LD (HL),AINC HL を並べても 1Byte につき 13clk ですが、PUSH は 2Byte につき 11clk(IX/IY は 15clk)と、かなり速いです。

しかしこの方法は SP レジスタを使うため、処理中に割り込みがかかると破綻します。 そのため DI 命令で通常の割り込みを禁止にしていますが、それでも NMI(Non Maskable Interrupt)が発生する可能性がある場合には使えません。

ちなみに類似の技として、POP をメモリ読み込みに使用するというものがあります。POP は 2Byte につき 10clk(IX/IY は 14clk)と高速です。割り込みがかかると破綻するのも同様です。

自己書き換え

プログラムを書き換える技です。たとえばこんな処理があるとします。

COUNTUP:
	LD A,(COUNT)
	INC A
	LD (COUNT),A
	RET

COUNT:
	DS 1	; 1Byteの領域を確保

この処理は次のように置き換えることができます。

COUNTUP:
	LD A,0	; 3E 00
	INC A
	LD (COUNTUP+1),A
	RET

こうするとワークエリアやプログラムサイズが節約できる上に、 少し速くなります。

欠点はプログラムが読みにくくなることと、ROM 上にプログラムがある場合は使えないことです。 使いどころには気を付けましょう。

他にはたとえばこんな技もあります。

	LD (ADD_IX_A+2),A
ADD_IX_A:
	LD (IX+0),1	; DD 36 00 01

これで LD (IX+A),1 に相当する処理(A は符号付きと見なす)が、他のレジスタを使わずにできます。

命令の途中にジャンプ

たとえば、

	OR A
	JR NZ,L1
	LD A,12H
	JR L2
L1:
	LD A,34H
L2:

これは「A レジスタが 0 なら 12H、それ以外なら 34H に変える」という処理で 9Byte ですが、もし BC レジスタを壊していいなら、

	OR A
	JR NZ,L1+1
	LD A,12H
L1:
	LD BC,343EH	; 3E 34  LD A,34H

と書けて 8Byte に減っています。 処理速度も遅くはなっていません(前者の JR L2JP L2 に変えても同じクロック数)。

いろんなバリエーションがあるのですが、いずれも非常に見づらく、逆アセンブルするとますます見づらい (分岐先アドレスが中途半端な上に、上記の例での LD A,34H が出てこないため)という大きな欠点があります。 よほどのことが無い限り、使うのはおすすめしません。




16bit ループの技

ループ回数が 16bit の場合、

	; BC=ループ回数
L1:
	  :
	DEC BC
	LD A,B		; Aレジスタを破壊
	OR C		; Cフラグも破壊
	JR NZ,L1
	RET

でループできますが、これだと A レジスタを破壊するだけでなく、壊したくないこともある C フラグまで破壊されてしまいます。もし仮に、

L1:
	  :
	DEC C
	JR NZ,L1
	DEC B
	JR NZ,L1

のように書けるなら、どちらも破壊せずに済む上に、 速度も(ループ回数が多い場合は)速くなります。しかしこれでは、たとえば BC=1 のときには DEC B で 0FFH になり、またループしてしまいます。

そこで前処理で「C レジスタが 0 でなければ B レジスタに 1 足す」としておくと、 正しい回数ループできるようになります。さらに B レジスタなら DJNZ が使えるので、内側のループで使用できるように B レジスタと C レジスタを入れ替えておきます。

	; BC=ループ回数
	LD A,C
	OR A
	JR Z,L1
	INC B
L1:
	LD C,B
	LD B,A
L2:
	  :
	DJNZ L2
	DEC C
	JR NZ,L2

または次のようにも書けます。

	; BC=ループ回数
	DEC BC
	INC C
	INC B
	LD A,C
	LD C,B
	LD B,A
L1:
	  :
	DJNZ L1
	DEC C
	JR NZ,L1

こちらのほうが速くてプログラムサイズも小さく、C フラグは変化しません。前者は C フラグが(OR A で)0 になるので、場合によってはそちらを使う選択肢もあります。

以上、ちょっとややこしいですが、これで A レジスタや C フラグを壊さずに、かつ高速にループすることができます。




命令一覧その 1

オペランド

フラグ変化

コード内表記

命令一覧
命令 clk フラグ変化
S Z H P N C
動作 コード
ADC A,r 4 * * * V 0 * A←A+r+Cflag 10001rrr
ADC A,n 7 * * * V 0 * A←A+n+Cflag 11001110 n
ADC A,(HL) 7 * * * V 0 * A←A+(HL)+Cflag 10001110
ADC A,(xx+d) 19 * * * V 0 * A←A+(xx+d)+Cflag 11x11101 10001110 d
ADC HL,rr 15 * * ? V 0 * HL←HL+rr+Cflag 11101101 01rr1010
ADD A,r 4 * * * V 0 * A←A+r 10000rrr
ADD A,n 7 * * * V 0 * A←A+n 11000110 n
ADD A,(HL) 7 * * * V 0 * A←A+(HL) 10000110
ADD A,(xx+d) 19 * * * V 0 * A←A+(xx+d) 11x11101 10000110 d
ADD HL,rr 11 - - ? - 0 * HL←HL+rr 00rr1001
ADD xx,ii 15 - - ? - 0 * xx←xx+ii 11x11101 00ii1001
AND r 4 * * 1 P 0 0 A←A and r 10100rrr
AND n 7 * * 1 P 0 0 A←A and n 11100110 n
AND (HL) 7 * * 1 P 0 0 A←A and (HL) 10100110
AND (xx+d) 19 * * 1 P 0 0 A←A and (xx+d) 11x11101 10100110 d
BIT b,r 8 ? * 1 ? 0 - Z←not rb 11001011 01bbbrrr
BIT b,(HL) 12 ? * 1 ? 0 - Z←not (HL)b 11001011 01bbb110
BIT b,(xx+d) 20 ? * 1 ? 0 - Z←not (xx+d)b 11x11101 11001011 d 01bbb110
CALL nn 17 - - - - - - (SP-1)←PCH, (SP-2)←PCL,
SP←SP-2, PC←nn
11001101 nnL nnH
CALL cc,nn 17/10
- - - - - - if (cc) (SP-1)←PCH, (SP-2)←PCL,
SP←SP-2, PC←nn
※分岐時 17clk/非分岐時 10clk
11ccc100 nnL nnH
CCF 4 - - ? - 0 * Cflag←not Cflag 00111111
CP r 4 * * * V 1 * A-r 10111rrr
CP n 7 * * * V 1 * A-n 11111110 n
CP (HL) 7 * * * V 1 * A-(HL) 10111110
CP (xx+d) 19 * * * V 1 * A-(xx+d) 11x11101 10111110 d
CPD 16 * * * * 1 -
A-(HL), HL←HL-1, BC←BC-1
※BC=0 で P/V←0/他は 1
11101101 10101001
CPDR 21/16
1
* * * * 1 -
2
A-(HL), HL←HL-1, BC←BC-1,
A=(HL) か BC=0 になるまで繰り返し
1 終了時 16clk/他は 21clk
2 BC=0 で P/V←0/他は 1
11101101 10111001
CPI 16 * * * * 1 -
A-(HL), HL←HL+1, BC←BC-1
※BC=0 で P/V←0/他は 1
11101101 10100001
CPIR 21/16
1
* * * * 1 -
2
A-(HL), HL←HL+1, BC←BC-1,
A=(HL) か BC=0 になるまで繰り返し
1 終了時 16clk/他は 21clk
2 BC=0 で P/V←0/他は 1
11101101 10110001
CPL 4 - - 1 - 1 - A←not A 00101111
DAA 4 * * * P - * A←packed BCD 補正した A 00100111
DEC r 4 * * * V 1 - r←r-1 00rrr101
DEC (HL) 11 * * * V 1 - (HL)←(HL)-1 00110101
DEC (xx+d) 23 * * * V 1 - (xx+d)←(xx+d)-1 11x11101 00110101 d
DEC rr 6 - - - - - - rr←rr-1 00rr1011
DEC xx 10 - - - - - - xx←xx-1 11x11101 00101011
DI 4 - - - - - - IFF1←0, IFF2←0(割り込み禁止) 11110011
DJNZ e 13/8
- - - - - - B←B-1, if (B≠0) PC←PC+e
※分岐時 13clk/非分岐時 8clk
00010000 e
EI 4 - - - - - - IFF1←1, IFF2←1(割り込み許可) 11111011
EX AF,AF' 4 - - - - - -
AF←→AF'
※交換後の F がフラグに反映
00001000
EX DE,HL 4 - - - - - - DE←→HL 11101011
EXX 4 - - - - - - BC←→BC', DE←→DE', HL←→HL' 11011001
EX (SP),HL 19 - - - - - - (SP)←→L, (SP+1)←→H 11100011
EX (SP),xx 23 - - - - - - (SP)←→xxL, (SP+1)←→xxH 11x11101 11100011
HALT 4 - - - - - - 実行停止(割り込み/リセット待ち) 01110110
IM 0
IM 1
IM 2
8 - - - - - - 割り込みモード←0
割り込みモード←1
割り込みモード←2
11101101 01000110
11101101 01010110
11101101 01011110
IN A,(n)
11 - - - - - - A←I/O port(n) 11011011 n
IN r,(C)
12 * * 0 P 0 - r←I/O port(C) 11101101 01rrr000
INC r 4 * * * V 0 - r←r+1 00rrr100
INC (HL) 11 * * * V 0 - (HL)←(HL)+1 00110100
INC (xx+d) 23 * * * V 0 - (xx+d)←(xx+d)+1 11x11101 00110100 d
INC rr 6 - - - - - - rr←rr+1 00rr0011
INC xx 10 - - - - - - xx←xx+1 11x11101 00100011
IND
16 ? * ? ? ? ?
(HL)←I/O port(C), B←B-1, HL←HL-1
※B=0 で Z←1/他は 0
11101101 10101010
INDR
21/16
? 1 ? ? ? ? (HL)←I/O port(C), B←B-1, HL←HL-1,
B=0 になるまで繰り返し
※終了時 16clk/他は 21clk
11101101 10111010
INI
16 ? * ? ? ? ?
(HL)←I/O port(C), B←B-1, HL←HL+1
※B=0 で Z←1/他は 0
11101101 10100010
INIR
21/16
? 1 ? ? ? ? (HL)←I/O port(C), B←B-1, HL←HL+1,
B=0 になるまで繰り返し
※終了時 16clk/他は 21clk
11101101 10110010
JP nn 10 - - - - - - PC←nn 11000011 nnL nnH
JP cc,nn 10 - - - - - - if (cc) PC←nn 11ccc010 nnL nnH
JP (HL) 4 - - - - - - PC←HL 11101001
JP (xx) 8 - - - - - - PC←xx 11x11101 11101001
JR e 10 - - - - - - PC←PC+e 00011000 e
JR cc,e 12/7
- - - - - - if (cc) PC←PC+e
※分岐時 12clk/非分岐時 7clk
001cc000 e
LD r,r' 4 - - - - - - r←r' 01rrrr'r'r'
LD r,n 7 - - - - - - r←n 00rrr110 n
LD A,(BC)
LD A,(DE)
7 - - - - - - A←(BC)
A←(DE)
00001010
00011010
LD A,(nn) 13 - - - - - - A←(nn) 00111010 nnL nnH
LD r,(HL) 7 - - - - - - r←(HL) 01rrr110
LD r,(xx+d) 19 - - - - - - r←(xx+d) 11x11101 01rrr110 d
LD (BC),A
LD (DE),A
7 - - - - - - (BC)←A
(DE)←A
00000010
00010010
LD (nn),A 13 - - - - - - (nn)←A 00110010 nnL nnH
LD (HL),r 7 - - - - - - (HL)←r 01110rrr
LD (xx+d),r 19 - - - - - - (xx+d)←r 11x11101 01110rrr d
LD (HL),n 10 - - - - - - (HL)←n 00110110 n
LD (xx+d),n 19 - - - - - - (xx+d)←n 11x11101 00110110 d n
LD A,I 9 * * 0 * 0 - A←I, P/V←IFF2 11101101 01010111
LD I,A 9 - - - - - - I←A 11101101 01000111
LD A,R 9 * * 0 * 0 - A←R, P/V←IFF2 11101101 01011111
LD R,A 9 - - - - - - R←A 11101101 01001111
LD rr,nn 10 - - - - - - rr←nn 00rr0001 nnL nnH
LD xx,nn 14 - - - - - - xx←nn 11x11101 00100001 nnL nnH
LD HL,(nn) 16 - - - - - - L←(nn), H←(nn+1) 00101010 nnL nnH
LD xx,(nn) 20 - - - - - - xxL←(nn), xxH←(nn+1) 11x11101 00101010 nnL nnH
LD BC,(nn)
LD DE,(nn)
LD SP,(nn)
20 - - - - - - C←(nn), B←(nn+1)
E←(nn), D←(nn+1)
SPL←(nn), SPH←(nn+1)
11101101 01001011 nnL nnH
11101101 01011011 nnL nnH
11101101 01111011 nnL nnH
LD (nn),HL 16 - - - - - - (nn)←L, (nn+1)←H 00100010 nnL nnH
LD (nn),xx 20 - - - - - - (nn)←xxL, (nn+1)←xxH 11x11101 00100010 nnL nnH
LD (nn),BC
LD (nn),DE
LD (nn),SP
20 - - - - - - (nn)←C, (nn+1)←B
(nn)←E, (nn+1)←D
(nn)←SPL, (nn+1)←SPH
11101101 01000011 nnL nnH
11101101 01010011 nnL nnH
11101101 01110011 nnL nnH
LD SP,HL 6 - - - - - - SP←HL 11111001
LD SP,xx 10 - - - - - - SP←xx 11x11101 11111001
LDD 16 - - 0 * 0 -
(DE)←(HL), DE←DE-1, HL←HL-1,
BC←BC-1
※BC=0 で P/V←0/他は 1
11101101 10101000
LDDR 21/16
- - 0 0 0 - (DE)←(HL), DE←DE-1, HL←HL-1,
BC←BC-1, BC=0 になるまで繰り返し
※終了時 16clk/他は 21clk
11101101 10111000
LDI 16 - - 0 * 0 -
(DE)←(HL), DE←DE+1, HL←HL+1,
BC←BC-1
※BC=0 で P/V←0/他は 1
11101101 10100000
LDIR 21/16
- - 0 0 0 - (DE)←(HL), DE←DE+1, HL←HL+1,
BC←BC-1, BC=0 になるまで繰り返し
※終了時 16clk/他は 21clk
11101101 10110000
NEG 8 * * * V 1 * A←0-A 11101101 01000100
NOP 4 - - - - - - 何もしない 00000000
OR r 4 * * 0 P 0 0 A←A or r 10110rrr
OR n 7 * * 0 P 0 0 A←A or n 11110110 n
OR (HL) 7 * * 0 P 0 0 A←A or (HL) 10110110
OR (xx+d) 19 * * 0 P 0 0 A←A or (xx+d) 11x11101 10110110 d
OTDR
21/16
? 1 ? ? ? ? B←B-1, I/O port(C)←(HL), HL←HL-1
B=0 になるまで繰り返し
※終了時 16clk/他は 21clk
11101101 10111011
OTIR
21/16
? 1 ? ? ? ? B←B-1, I/O port(C)←(HL), HL←HL+1
B=0 になるまで繰り返し
※終了時 16clk/他は 21clk
11101101 10110011
OUT (n),A
11 - - - - - - I/O port(n)←A 11010011 n
OUT (C),r
12 - - - - - - I/O port(C)←r 11101101 01rrr001
OUTD
16 ? * ? ? ? ?
B←B-1, I/O port(C)←(HL), HL←HL-1
※B=0 で Z←1/他は 0
11101101 10101011
OUTI
16 ? * ? ? ? ?
B←B-1, I/O port(C)←(HL), HL←HL+1
※B=0 で Z←1/他は 0
11101101 10100011
POP qq 10 - - - - - -
qqL←(SP), qqH←(SP+1), SP←SP+2
※POP AF は F がフラグに反映
11qq0001
POP xx 14 - - - - - - xxL←(SP), xxH←(SP+1), SP←SP+2 11x11101 11100001
PUSH qq 11 - - - - - - (SP-1)←qqH, (SP-2)←qqL, SP←SP-2 11qq0101
PUSH xx 15 - - - - - - (SP-1)←xxH, (SP-2)←xxL, SP←SP-2 11x11101 11100101
RES b,r 8 - - - - - - rb←0 11001011 10bbbrrr
RES b,(HL) 15 - - - - - - (HL)b←0 11001011 10bbb110
RES b,(xx+d) 23 - - - - - - (xx+d)b←0 11x11101 11001011 d 10bbb110
RET 10 - - - - - - PCL←(SP), PCH←(SP+1), SP←SP+2 11001001
RET cc 11/5
- - - - - - if (cc) PCL←(SP), PCH←(SP+1),
SP←SP+2
分岐時 11clk/非分岐時 5clk
11ccc000
RETI 14 - - - - - - PCL←(SP), PCH←(SP+1), SP←SP+2
割り込み処理からのリターン
11101101 01001101
RETN 14 - - - - - - PCL←(SP), PCH←(SP+1), SP←SP+2,
IFF1←IFF2
NMI 処理からのリターン
11101101 01000101
RL r 8 * * 0 P 0 * Cflag←r7..0←Cflag 11001011 00010rrr
RL (HL) 15 * * 0 P 0 * Cflag←(HL)7..0←Cflag 11001011 00010110
RL (xx+d) 23 * * 0 P 0 * Cflag←(xx+d)7..0←Cflag 11x11101 11001011 d 00010110
RLA 4 - - 0 - 0 * Cflag←A7..0←Cflag 00010111
RLC r 8 * * 0 P 0 * Cflag←r7..0←r7 11001011 00000rrr
RLC (HL) 15 * * 0 P 0 * Cflag←(HL)7..0←(HL)7 11001011 00000110
RLC (xx+d) 23 * * 0 P 0 * Cflag←(xx+d)7..0←(xx+d)7 11x11101 11001011 d 00000110
RLCA 4 - - 0 - 0 * Cflag←A7..0←A7 00000111
RLD 18 * * 0 P 0 - A3..0←(HL)7..4←(HL)3..0←A3..0 11101101 01101111
RR r 8 * * 0 P 0 * Cflag→r7..0→Cflag 11001011 00011rrr
RR (HL) 15 * * 0 P 0 * Cflag→(HL)7..0→Cflag 11001011 00011110
RR (xx+d) 23 * * 0 P 0 * Cflag→(xx+d)7..0→Cflag 11x11101 11001011 d 00011110
RRA 4 - - 0 - 0 * Cflag→A7..0→Cflag 00011111
RRC r 8 * * 0 P 0 * r0→r7..0→Cflag 11001011 00001rrr
RRC (HL) 15 * * 0 P 0 * (HL)0→(HL)7..0→Cflag 11001011 00001110
RRC (xx+d) 23 * * 0 P 0 * (xx+d)0→(xx+d)7..0→Cflag 11x11101 11001011 d 00001110
RRCA 4 - - 0 - 0 * A0→A7..0→Cflag 00001111
RRD 18 * * 0 P 0 - A3..0→(HL)7..4→(HL)3..0→A3..0 11101101 01100111
RST p 11 - - - - - - (SP-1)←PCH, (SP-2)←PCL, SP←SP-2,
PCL←p, PCH←0
11ppp111
SBC A,r 4 * * * V 1 * A←A-r-Cflag 10011rrr
SBC A,n 7 * * * V 1 * A←A-n-Cflag 11011110 n
SBC A,(HL) 7 * * * V 1 * A←A-(HL)-Cflag 10011110
SBC A,(xx+d) 19 * * * V 1 * A←A-(xx+d)-Cflag 11x11101 10011110 d
SBC HL,rr 15 * * ? V 1 * HL←HL-rr-Cflag 11101101 01rr0010
SCF 4 - - 0 - 0 1 Cflag←1 00110111
SET b,r 8 - - - - - - rb←1 11001011 11bbbrrr
SET b,(HL) 15 - - - - - - (HL)b←1 11001011 11bbb110
SET b,(xx+d) 23 - - - - - - (xx+d)b←1 11x11101 11001011 d 11bbb110
SLA r 8 * * 0 P 0 * Cflag←r7..0←0 11001011 00100rrr
SLA (HL) 15 * * 0 P 0 * Cflag←(HL)7..0←0 11001011 00100110
SLA (xx+d) 23 * * 0 P 0 * Cflag←(xx+d)7..0←0 11x11101 11001011 d 00100110
SRA r 8 * * 0 P 0 * r7..0→Cflag 11001011 00101rrr
SRA (HL) 15 * * 0 P 0 * (HL)7..0→Cflag 11001011 00101110
SRA (xx+d) 23 * * 0 P 0 * (xx+d)7..0→Cflag 11x11101 11001011 d 00101110
SRL r 8 * * 0 P 0 * 0→r7..0→Cflag 11001011 00111rrr
SRL (HL) 15 * * 0 P 0 * 0→(HL)7..0→Cflag 11001011 00111110
SRL (xx+d) 23 * * 0 P 0 * 0→(xx+d)7..0→Cflag 11x11101 11001011 d 00111110
SUB r 4 * * * V 1 * A←A-r 10010rrr
SUB n 7 * * * V 1 * A←A-n 11010110 n
SUB (HL) 7 * * * V 1 * A←A-(HL) 10010110
SUB (xx+d) 19 * * * V 1 * A←A-(xx+d) 11x11101 10010110 d
XOR r 4 * * 0 P 0 0 A←A xor r 10101rrr
XOR n 7 * * 0 P 0 0 A←A xor n 11101110 n
XOR (HL) 7 * * 0 P 0 0 A←A xor (HL) 10101110
XOR (xx+d) 19 * * 0 P 0 0 A←A xor (xx+d) 11x11101 10101110 d



命令一覧その 2

基本
00 NOP 20 JR NZ,e 40 LD B,B 60 LD H,B 80 ADD A,B A0 AND B C0 RET NZ E0 RET PO
01 LD BC,nn 21 LD HL,nn 41 LD B,C 61 LD H,C 81 ADD A,C A1 AND C C1 POP BC E1 POP HL
02 LD (BC),A 22 LD (nn),HL 42 LD B,D 62 LD H,D 82 ADD A,D A2 AND D C2 JP NZ,nn E2 JP PO,nn
03 INC BC 23 INC HL 43 LD B,E 63 LD H,E 83 ADD A,E A3 AND E C3 JP nn E3 EX (SP),HL
04 INC B 24 INC H 44 LD B,H 64 LD H,H 84 ADD A,H A4 AND H C4 CALL NZ,nn E4 CALL PO,nn
05 DEC B 25 DEC H 45 LD B,L 65 LD H,L 85 ADD A,L A5 AND L C5 PUSH BC E5 PUSH HL
06 LD B,n 26 LD H,n 46 LD B,(HL) 66 LD H,(HL) 86 ADD A,(HL) A6 AND (HL) C6 ADD A,n E6 AND n
07 RLCA 27 DAA 47 LD B,A 67 LD H,A 87 ADD A,A A7 AND A C7 RST 00H E7 RST 20H
08 EX AF,AF' 28 JR Z,e 48 LD C,B 68 LD L,B 88 ADC A,B A8 XOR B C8 RET Z E8 RET PE
09 ADD HL,BC 29 ADD HL,HL 49 LD C,C 69 LD L,C 89 ADC A,C A9 XOR C C9 RET E9 JP (HL)
0A LD A,(BC) 2A LD HL,(nn) 4A LD C,D 6A LD L,D 8A ADC A,D AA XOR D CA JP Z,nn EA JP PE,nn
0B DEC BC 2B DEC HL 4B LD C,E 6B LD L,E 8B ADC A,E AB XOR E CB 別表 EB EX DE,HL
0C INC C 2C INC L 4C LD C,H 6C LD L,H 8C ADC A,H AC XOR H CC CALL Z,nn EC CALL PE,nn
0D DEC C 2D DEC L 4D LD C,L 6D LD L,L 8D ADC A,L AD XOR L CD CALL nn ED 別表
0E LD C,n 2E LD L,n 4E LD C,(HL) 6E LD L,(HL) 8E ADC A,(HL) AE XOR (HL) CE ADC A,n EE XOR n
0F RRCA 2F CPL 4F LD C,A 6F LD L,A 8F ADC A,A AF XOR A CF RST 08H EF RST 28H
10 DJNZ e 30 JR NC,e 50 LD D,B 70 LD (HL),B 90 SUB B B0 OR B D0 RET NC F0 RET P
11 LD DE,nn 31 LD SP,nn 51 LD D,C 71 LD (HL),C 91 SUB C B1 OR C D1 POP DE F1 POP AF
12 LD (DE),A 32 LD (nn),A 52 LD D,D 72 LD (HL),D 92 SUB D B2 OR D D2 JP NC,nn F2 JP P,nn
13 INC DE 33 INC SP 53 LD D,E 73 LD (HL),E 93 SUB E B3 OR E D3 OUT (n),A F3 DI
14 INC D 34 INC (HL) 54 LD D,H 74 LD (HL),H 94 SUB H B4 OR H D4 CALL NC,nn F4 CALL P,nn
15 DEC D 35 DEC (HL) 55 LD D,L 75 LD (HL),L 95 SUB L B5 OR L D5 PUSH DE F5 PUSH AF
16 LD D,n 36 LD (HL),n 56 LD D,(HL) 76 HALT 96 SUB (HL) B6 OR (HL) D6 SUB n F6 OR n
17 RLA 37 SCF 57 LD D,A 77 LD (HL),A 97 SUB A B7 OR A D7 RST 10H F7 RST 30H
18 JR e 38 JR C,e 58 LD E,B 78 LD A,B 98 SBC A,B B8 CP B D8 RET C F8 RET M
19 ADD HL,DE 39 ADD HL,SP 59 LD E,C 79 LD A,C 99 SBC A,C B9 CP C D9 EXX F9 LD SP,HL
1A LD A,(DE) 3A LD A,(nn) 5A LD E,D 7A LD A,D 9A SBC A,D BA CP D DA JP C,nn FA JP M,nn
1B DEC DE 3B DEC SP 5B LD E,E 7B LD A,E 9B SBC A,E BB CP E DB IN A,(n) FB EI
1C INC E 3C INC A 5C LD E,H 7C LD A,H 9C SBC A,H BC CP H DC CALL C,nn FC CALL M,nn
1D DEC E 3D DEC A 5D LD E,L 7D LD A,L 9D SBC A,L BD CP L DD 別表(IX) FD 別表(IY)
1E LD E,n 3E LD A,n 5E LD E,(HL) 7E LD A,(HL) 9E SBC A,(HL) BE CP (HL) DE SBC A,n FE CP n
1F RRA 3F CCF 5F LD E,A 7F LD A,A 9F SBC A,A BF CP A DF RST 18H FF RST 38H

CB xx
00 RLC B 20 SLA B 40 BIT 0,B 60 BIT 4,B 80 RES 0,B A0 RES 4,B C0 SET 0,B E0 SET 4,B
01 RLC C 21 SLA C 41 BIT 0,C 61 BIT 4,C 81 RES 0,C A1 RES 4,C C1 SET 0,C E1 SET 4,C
02 RLC D 22 SLA D 42 BIT 0,D 62 BIT 4,D 82 RES 0,D A2 RES 4,D C2 SET 0,D E2 SET 4,D
03 RLC E 23 SLA E 43 BIT 0,E 63 BIT 4,E 83 RES 0,E A3 RES 4,E C3 SET 0,E E3 SET 4,E
04 RLC H 24 SLA H 44 BIT 0,H 64 BIT 4,H 84 RES 0,H A4 RES 4,H C4 SET 0,H E4 SET 4,H
05 RLC L 25 SLA L 45 BIT 0,L 65 BIT 4,L 85 RES 0,L A5 RES 4,L C5 SET 0,L E5 SET 4,L
06 RLC (HL) 26 SLA (HL) 46 BIT 0,(HL) 66 BIT 4,(HL) 86 RES 0,(HL) A6 RES 4,(HL) C6 SET 0,(HL) E6 SET 4,(HL)
07 RLC A 27 SLA A 47 BIT 0,A 67 BIT 4,A 87 RES 0,A A7 RES 4,A C7 SET 0,A E7 SET 4,A
08 RRC B 28 SRA B 48 BIT 1,B 68 BIT 5,B 88 RES 1,B A8 RES 5,B C8 SET 1,B E8 SET 5,B
09 RRC C 29 SRA C 49 BIT 1,C 69 BIT 5,C 89 RES 1,C A9 RES 5,C C9 SET 1,C E9 SET 5,C
0A RRC D 2A SRA D 4A BIT 1,D 6A BIT 5,D 8A RES 1,D AA RES 5,D CA SET 1,D EA SET 5,D
0B RRC E 2B SRA E 4B BIT 1,E 6B BIT 5,E 8B RES 1,E AB RES 5,E CB SET 1,E EB SET 5,E
0C RRC H 2C SRA H 4C BIT 1,H 6C BIT 5,H 8C RES 1,H AC RES 5,H CC SET 1,H EC SET 5,H
0D RRC L 2D SRA L 4D BIT 1,L 6D BIT 5,L 8D RES 1,L AD RES 5,L CD SET 1,L ED SET 5,L
0E RRC (HL) 2E SRA (HL) 4E BIT 1,(HL) 6E BIT 5,(HL) 8E RES 1,(HL) AE RES 5,(HL) CE SET 1,(HL) EE SET 5,(HL)
0F RRC A 2F SRA A 4F BIT 1,A 6F BIT 5,A 8F RES 1,A AF RES 5,A CF SET 1,A EF SET 5,A
10 RL B 30 - 50 BIT 2,B 70 BIT 6,B 90 RES 2,B B0 RES 6,B D0 SET 2,B F0 SET 6,B
11 RL C 31 - 51 BIT 2,C 71 BIT 6,C 91 RES 2,C B1 RES 6,C D1 SET 2,C F1 SET 6,C
12 RL D 32 - 52 BIT 2,D 72 BIT 6,D 92 RES 2,D B2 RES 6,D D2 SET 2,D F2 SET 6,D
13 RL E 33 - 53 BIT 2,E 73 BIT 6,E 93 RES 2,E B3 RES 6,E D3 SET 2,E F3 SET 6,E
14 RL H 34 - 54 BIT 2,H 74 BIT 6,H 94 RES 2,H B4 RES 6,H D4 SET 2,H F4 SET 6,H
15 RL L 35 - 55 BIT 2,L 75 BIT 6,L 95 RES 2,L B5 RES 6,L D5 SET 2,L F5 SET 6,L
16 RL (HL) 36 - 56 BIT 2,(HL) 76 BIT 6,(HL) 96 RES 2,(HL) B6 RES 6,(HL) D6 SET 2,(HL) F6 SET 6,(HL)
17 RL A 37 - 57 BIT 2,A 77 BIT 6,A 97 RES 2,A B7 RES 6,A D7 SET 2,A F7 SET 6,A
18 RR B 38 SRL B 58 BIT 3,B 78 BIT 7,B 98 RES 3,B B8 RES 7,B D8 SET 3,B F8 SET 7,B
19 RR C 39 SRL C 59 BIT 3,C 79 BIT 7,C 99 RES 3,C B9 RES 7,C D9 SET 3,C F9 SET 7,C
1A RR D 3A SRL D 5A BIT 3,D 7A BIT 7,D 9A RES 3,D BA RES 7,D DA SET 3,D FA SET 7,D
1B RR E 3B SRL E 5B BIT 3,E 7B BIT 7,E 9B RES 3,E BB RES 7,E DB SET 3,E FB SET 7,E
1C RR H 3C SRL H 5C BIT 3,H 7C BIT 7,H 9C RES 3,H BC RES 7,H DC SET 3,H FC SET 7,H
1D RR L 3D SRL L 5D BIT 3,L 7D BIT 7,L 9D RES 3,L BD RES 7,L DD SET 3,L FD SET 7,L
1E RR (HL) 3E SRL (HL) 5E BIT 3,(HL) 7E BIT 7,(HL) 9E RES 3,(HL) BE RES 7,(HL) DE SET 3,(HL) FE SET 7,(HL)
1F RR A 3F SRL A 5F BIT 3,A 7F BIT 7,A 9F RES 3,A BF RES 7,A DF SET 3,A FF SET 7,A

DD xx(IX)
FD xx(IX→IY)
01 - 11 - 21 LD IX,nn 31 -
02 - 12 - 22 LD (nn),IX 32 -
03 - 13 - 23 INC IX 33 -
04 - 14 - 24 - 34 INC (IX+d)
05 - 15 - 25 - 35 DEC (IX+d)
06 - 16 - 26 - 36 LD (IX+d),n
09 ADD IX,BC 19 ADD IX,DE 29 ADD IX,IX 39 ADD IX,SP
0A - 1A - 2A LD IX,(nn) 3A -
0B - 1B - 2B DEC IX 3B -
40 - 50 - 60 - 70 LD (IX+d),B
41 - 51 - 61 - 71 LD (IX+d),C
42 - 52 - 62 - 72 LD (IX+d),D
43 - 53 - 63 - 73 LD (IX+d),E
44 - 54 - 64 - 74 LD (IX+d),H
45 - 55 - 65 - 75 LD (IX+d),L
46 LD B,(IX+d) 56 LD D,(IX+d) 66 LD H,(IX+d) 76 -
47 - 57 - 67 - 77 LD (IX+d),A
4E LD C,(IX+d) 5E LD E,(IX+d) 6E LD L,(IX+d) 7E LD A,(IX+d)
86 ADD A,(IX+d) 96 SUB (IX+d) A6 AND (IX+d) B6 OR (IX+d)
8E ADC A,(IX+d) 9E SBC A,(IX+d) AE XOR (IX+d) BE CP (IX+d)
CB xx
06 RLC (IX+d) 46 BIT 0,(IX+d) 86 RES 0,(IX+d) C6 SET 0,(IX+d)
0E RRC (IX+d) 4E BIT 1,(IX+d) 8E RES 1,(IX+d) CE SET 1,(IX+d)
16 RL (IX+d) 56 BIT 2,(IX+d) 96 RES 2,(IX+d) D6 SET 2,(IX+d)
1E RR (IX+d) 5E BIT 3,(IX+d) 9E RES 3,(IX+d) DE SET 3,(IX+d)
26 SLA (IX+d) 66 BIT 4,(IX+d) A6 RES 4,(IX+d) E6 SET 4,(IX+d)
2E SRA (IX+d) 6E BIT 5,(IX+d) AE RES 5,(IX+d) EE SET 5,(IX+d)
36 - 76 BIT 6,(IX+d) B6 RES 6,(IX+d) F6 SET 6,(IX+d)
3E SRL (IX+d) 7E BIT 7,(IX+d) BE RES 7,(IX+d) FE SET 7,(IX+d)
E1 POP IX
E3 EX (SP),IX
E5 PUSH IX
E9 JP (IX)
F9 LD SP,IX

ED xx
40 IN B,(C) 50 IN D,(C) 60 IN H,(C) 70 - A0 LDI B0 LDIR
41 OUT (C),B 51 OUT (C),D 61 OUT (C),H 71 - A1 CPI B1 CPIR
42 SBC HL,BC 52 SBC HL,DE 62 SBC HL,HL 72 SBC HL,SP A2 INI B2 INIR
43 LD (nn),BC 53 LD (nn),DE 63 - 73 LD (nn),SP A3 OUTI B3 OTIR
44 NEG 54 - 64 - 74 - A4 - B4 -
45 RETN 55 - 65 - 75 - A5 - B5 -
46 IM 0 56 IM 1 66 - 76 - A6 - B6 -
47 LD I,A 57 LD A,I 67 RRD 77 - A7 - B7 -
48 IN C,(C) 58 IN E,(C) 68 IN L,(C) 78 IN A,(C) A8 LDD B8 LDDR
49 OUT (C),C 59 OUT (C),E 69 OUT (C),L 79 OUT (C),A A9 CPD B9 CPDR
4A ADC HL,BC 5A ADC HL,DE 6A ADC HL,HL 7A ADC HL,SP AA IND BA INDR
4B LD BC,(nn) 5B LD DE,(nn) 6B - 7B LD SP,(nn) AB OUTD BB OTDR
4C - 5C - 6C - 7C - AC - BC -
4D RETI 5D - 6D - 7D - AD - BD -
4E - 5E IM 2 6E - 7E - AE - BE -
4F LD R,A 5F LD A,R 6F RLD 7F - AF - BF -

inserted by FC2 system