一度に取り扱うデータの単位は、4, 8, 16, 32, 64 bit などがあります。 今回の例では 8bit のものを示します(図8.2参照)。
アドレスバッファ (address buffer) からアドレスを与えると、 記憶装置はそのアドレスで指定された番地(記憶位置)から 8ビットのデータを取り出し、データバッファ (data buffer) に入れます。
アドレスバッファの容量を 16 bit とすると、最大で 64Kbyte (= 216)のデータを記憶することができます。 記憶装置にデータを書き込むときは、データバッファにデータを 与え、アドレスバッファからアドレスを与えます。
直接アドレス指定 (direct addressing) 命令では、メモリのアドレスを 1つ指定して、そのアドレス位置に記憶されているデータ(1byte)を操作 (たとえばAレジスタにコピー)します。
直接アドレス指定命令は3バイトで表現され、 第1バイトが命令の種類、第2,3バイトがアドレスを 表しています(図8.3参照)。
[例題] 50番地と51番地のデータをそれぞれ1000番地と1001番地へ移動する
プログラムを作りなさい。
[解答]
LDA 50 ← 50番地の内容をAレジスタにコピーします STA 1000 ← Aレジスタの内容を1000番地にコピーします LDA 51 ← 51番地の内容をAレジスタにコピーします STA 1001 ← Aレジスタの内容を1001番地にコピーします
LDA命令を実行するときの内部動作 (図8.4参照)
LDA命令は3バイト(命令の種類を表すのに1バイト、アドレスを表すのに2バイト)
の大きさで、たとえばメモリ中の 2000〜2002番地に格納されています。
プログラム・カウンタがこの2000番地を指した時に命令が実行されます。
命令は、各レジスタの間で適切なタイミングで適切なバスを通して データを転送することで実行されます。各レジスタの間にはゲート回路 が設けられていて、IRの内容を解読することによってこの転送用ゲート が開閉されます。 計算機はレジスタ間の情報の転送を制御することで動作します。
インテルの8bitマイクロプロセッサ。 比較的初期のもので、構造がシンプルで理解しやすいプロセッサです。
BC, DE, HL, WZ のレジスタ対をまとめて1つの 16ビットレジスタとして 扱うこともあります。 他のレジスタとしては、命令レジスタ(IR)、プログラムカウンタ (PC)、 スタックポインタ (SP) があります。
Tレジスタは演算するデータを一時的に記憶しておくレジスタで、 外部から命令で直接指定することはできません(W,Zレジスタも同様です)。
アドレスやデータを指定する方法としては、以下のものがあります。
i8080CPUの命令の抜粋を表に示す。 ( 命令全体に関しては 8080命令説明書 などを参照して下さい。)
表中で、 $r_1$, $r_2$, $r$ はレジスタを表す。 $M$は H,Lレジスタのペアで表される番地のメモリを表す。 $B_2$, $B_3$は命令コードに続く2バイト目、3バイト目のデータを表す。 ($X$)は矢印の右に現れたときは $X$ から内容をコピーすることを表わし、 矢印の左に現れたときは $X$ の内容を書き換えることを表す。 [$X$]は矢印の右に現れたときは $X$ が指すメモリ位置からデータをコピーすることを表わし、 矢印の左に現れたときは $X$ が指すメモリ位置の内容を書き換えることを表す。
ニーモニック (記号命令) | 命令コード | 命令長 (byte) | 動作 |
---|---|---|---|
MOV $r_1$, $r_2$ | 01DDDSSS | 1 | ($r_1$) $\leftarrow$ ($r_2$) |
MOV $r$, $M$ | 01DDD110 | 1 | ($r$) $\leftarrow$ [ (H)(L) ] |
MOV $M$, $r$ | 01110SSS | 1 | [ (H)(L) ] $\leftarrow$ ($r$) |
MVI $r$, $B_2$ | 00DDD110 | 2 | ($r$) $\leftarrow$ $B_2$ |
LDA $B_3$$B_2$ | 00111010 | 3 | (A) $\leftarrow$ [ $B_3 B_2$ ] |
STA $B_3$$B_2$ | 00110010 | 3 | [ $B_3 B_2$ ] $\leftarrow$ (A) |
LHLD $B_3$$B_2$ | 00101010 | 3 |
(L)$\leftarrow$ [ $B_3 B_2$ ] (H)$\leftarrow$ [ $B_3 B_2 +1$ ] |
SHLD $B_3$$B_2$ | 00100010 | 3 |
[ $B_3 B_2$ ] $\leftarrow$ (L) [ $B_3 B_2 +1$ ] $\leftarrow$ (H) |
ADD $r$ | 10000SSS | 1 | (A) $\leftarrow$ (A) $+$ ($r$) |
ADD $M$ | 10000110 | 1 | (A) $\leftarrow$ (A) $+$ [ (H)(L) ] |
ADI $B_2$ | 11000110 | 2 | (A) $\leftarrow$ (A) $+$ $B_2$ |
SUB $r$ | 10010SSS | 1 | (A) $\leftarrow$ (A) $-$ ($r$) |
SUB $M$ | 10010110 | 1 | (A) $\leftarrow$ (A) $-$ [ (H)(L) ] |
SUI $B_2$ | 11010110 | 2 | (A) $\leftarrow$ (A) $-$ $B_2$ |
CMP $r$ | 10111SSS | 1 | (A) $-$ ($r$) を計算してフラグに反映。Aレジスタは変更されない。 |
CMP $M$ | 10111110 | 1 | (A) $-$ [ (H)(L) ] を計算してフラグに反映。Aレジスタは変更されない。 |
CPI $B_2$ | 11111110 | 2 | (A) $-$ $B_2$ を計算してフラグに反映。Aレジスタは変更されない。 |
INR $r$ | 00DDD100 | 1 | ($r$) $\leftarrow$ ($r$) $+1$ |
DCR $r$ | 00DDD101 | 1 | ($r$) $\leftarrow$ ($r$) $-1$ |
INX $rp$ | 00RP0011 | 1 | ($rp$) $\leftarrow$ ($rp$) $+1$。$rp$={BC, DE, HL, SP}。 |
DCX $rp$ | 00RP1011 | 1 | ($rp$) $\leftarrow$ ($rp$) $-1$。$rp$={BC, DE, HL, SP}。 |
JMP $B_3 B_2$ | 11000011 | 3 | $B_3 B_2$ 番地にジャンプする。(PC) $\leftarrow$ $B_3 B_2$ |
JNZ $B_3 B_2$ | 11000010 | 3 | zeroフラグがセットされていなければ$B_3 B_2$ 番地にジャンプする。 |
JZ $B_3 B_2$ | 11001010 | 3 | zeroフラグがセットされていたら$B_3 B_2$ 番地にジャンプする。 |
PUSH $rp$ | 11RP0101 | 1 |
[ (SP)$-1$ ] $\leftarrow$ ($rp_1$) [ (SP)$-2$ ] $\leftarrow$ ($rp_2$) (SP) $\leftarrow$ (SP)$-2$, $rp$={BC,DE,HL,PSW} のとき($rp_1$,$rp_2$)={(B,C), (D,E), (H,L), (A, Flags)}。 |
POP $rp$ | 11RP0001 | 1 |
($rp_2$) $\leftarrow$ [ (SP) ] ($rp_1$) $\leftarrow$ [ (SP)$+1$ ] (SP) $\leftarrow$ (SP)$+2$ $rp$={BC,DE,HL,PSW} のとき($rp_1$,$rp_2$)={(B,C), (D,E), (H,L), (A, Flags)}。 |
CALL $B_3 B_2$ | 11001101 | 3 |
[ (SP)$-1$ ] $\leftarrow$ (PC${}_{high}$) [ (SP)$-2$ ] $\leftarrow$ (PC${}_{low}$) (SP) $\leftarrow$ (SP) $-2$ (PC) $\leftarrow$ $B_3 B_2$ |
RET | 11001001 | 1 |
(PC${}_{low}$) $\leftarrow$ [ (SP) ] (PC${}_{high}$) $\leftarrow$ [ (SP)$+1$ ] (SP) $\leftarrow$ (SP) $+2$ |
HLT | 01110110 | 1 | 割込みかリセットがかかるまでCPUの実行を停止する。 |
NOP | 00000000 | 1 | 何も実行しないで次の命令に進む。 |
|
|
[解答] MVI C, 10 ; 00001110 00001010 MOV B, C ; 01000001
[解答] MVI C, 10 ; 00001110 00001010 ADD C ; 10000001[例題]0x300番地の内容に 15を加えて、0x301番地に入れるプログラムを書きなさい。
[解答] LDA 300H ; 00111010 00000000 00000011 ADI 15 ; 11000110 00001111 STA 301H ; 00110010 00000001 00000011
[解答] MVI C, 0 ; 00001110 00000000 MVI B, 32 ; 00000110 00100000 LABEL1: MOV A, C ; 01111001 ←0x104番地 ADD B ; 10000000 MOV C, A ; 01001111 MOV A, B ; 01111000 ADI A, -1 ; 11000110 11111111 MOV B, A ; 01000111 JNZ LABEL1 ; 11000010 00000100 00000001 MOV A, C ; 01111001 STA 301H ; 00110010 00000001 00000011
マイクロプロセッサの命令は、命令のバイト数もいろいろで、 アドレス方式も多岐に渡ります。 これらの命令がどのように実行されるかを説明します。
マイクロプロセッサは記憶装置、入出力装置などと組合されて コンピュータを構成する(図8.8参照)。
マイクロプロセッサの制御バスには ~MEMR, ~MEMW, ~IOR, ~IOW の4本があり、 CPU ←→ 記憶装置、 CPU ←→ 入出力装置 の間の 読み出し(R) / 書き込み(W) を制御します(図8.5参照)。
クロック周波数を 2MHz とし、記憶装置の読み出し、書き込みに それぞれ3クロックが必要であるとします。 この3クロックの期間をサイクルと呼びます(図8.9参照)。
読み出しの場合: T1: アドレスバスにアドレスを与えます。 T2: ~MEMR に信号を与えます。 T3: データを得ます。 書き込みの場合: T1: アドレスバスにアドレスを与えます。 T2: ~MEMW に信号を与えつつ、データバスにデータを与えます。 T3: 々
いろいろな命令を実行するときの動作タイミングを示します。 8080では命令の実行に要する時間は命令毎に異なっていて、 それぞれの命令毎に製造会社から提供されているマニュアルに 記載されています。
表8.1に示される機械語のビットパターンを直接人間が書くことは通常なく、
アセンブリ言語では、表8.1のような記号命令を使い、命令や変数を 記憶するアドレスを記号(ラベル)で参照できます。
DB (define byte) DB 値(1バイト分) DW (define word) DW 値(2バイト分) DS (define storage) DS 記憶場所の大きさ