目次

メモリ上の機械語

メモリの考え方

保存する場所に番地(アドレス)をつけ、そこに1バイトずつデータを保存する。番地は普通、通し番号だが1バイトでは0番地から255番地までの256しか表現できない。2バイトあれば256×256で65536まで表現できる。これが64KBのメモリである。1980年あたりではこの大きさのメモリを扱うCPUが主流であった。次の表は、この64KBのメモリのうち、53248番地からのメモリにデータが入っている様子をイメージしたものである。

データの格納状況
番地(アドレス)
(2バイトの場合)
データ
(1バイト)
110100000000000001011110
110100000000000100100011
110100000000001001010110
110100000000001111110011
110100000000010000111110
110100000000010111111110
110100000000011011010011
110100000000011101110001
110100000000100011001101
110100000000100101110010
110100000000101001100001

2013年現在PCのメモリは4GB(=4000000KB)あたりが普通になっているのでもちろん2バイトでは足りない。

コンピュータはこれでいいのだが、人間はさすがに1と0が詰まっていると読みにくい。そこで4ビットごとに区切ってみる。

4ビットで区切る
番地(アドレス) データ
1101 0000 0000 00000101 1110
1101 0000 0000 00010010 0011
1101 0000 0000 00100101 0110
1101 0000 0000 00111111 0011
1101 0000 0000 01000011 1110
1101 0000 0000 01011111 1110
1101 0000 0000 01101101 0011
1101 0000 0000 01110111 0001
1101 0000 0000 10001100 1101
1101 0000 0000 10010111 0010
1101 0000 0000 10100110 0001
パターンを記号化
パターン 記号
00000
00011
00102
00113
01004
01015
01106
01117
10008
10019
1010A
1011B
1100C
1101D
1110E
1111F

区切ったものは16種類のパターンになるので、0,1,2,…,E,F の16個の記号で表してみる。(要するに16進表現)

16個の記号で
番地(アドレス)
(2バイトの場合)
データ
(1バイト)
D0005E
D00123
D00256
D003F3
D0043E
D005FE
D006D3
D00771
D008CD
D00972
D00A61

かなり見やすくなった。たとえば00111110のパターンを探すのは大変だが、3Eを探すのはそう面倒ではない。

細長くなって場所を取るので、以下のように1行に16個ずつ書くこともよくある。たとえば、

00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
D000 5E 23 56 F3 3E FE D3 71 CD 61 72 3E FF D3 71 FB
D010 00 00 00 00 00 00 00 00 00 00 00 00 13 13 13 13
D020 D9 0E 02 06 08 D9 0E 02 D5 E1 06 08 CB 06 1F 23
D030 23 10 F9 CD D4 3E 0D 20 F1 D9 10 E9 D9 13 D9 0D
D040 20 E1 D9 C9

この場合、D000行の04列目は、番地はD004、データは3Eとよむ。

訂正をしています下記の訂正箇所をご覧ください。

機械語のプログラム

実は上記のメモリに格納されていたのは機械語のプログラムである。

メモリに入れるのはプログラムの実行で作成されるデータばかりでなくプログラムそのものもメモリに配置する場合が多い(そうしない方法もある)。

この例ではCPUはD000から実行するようにセットされ(これもプログラムによってセットされるのだが)、まず5Eという命令を実行する。

後はその命令に書かれているとおり作業を進めていく。普通は次の番地の命令に進むが、場合によってはいくつかの命令を飛び越したり、戻ったりもする。

この例では最後付近のD043C9D000から作業を始めさせたプログラムにもどる。

訂正をしています下記の訂正箇所をご覧ください。

機械語のプログラムの例

番地 命令 ニーモニック
D000 5E LD E,(HL)
D001 23 INC HL
D002 56 LD D,(HL)
D003 F3 DI
D004 3E FE LD A,FE
D006 D3 71 OUT (71),A
D008 CD 7261 CALL 7261
D00B 3E FF LD A,FF
D00D D3 71 OUT (71),A
D00F FB EI
D010 00 NOP
... .. ..
D01B 00 NOP
D01C 13 INC DE
D01D 13 INC DE
D01E 13 INC DE
D01F 13 INC DE
D020 D9 EXX
D021 0E 02 LD C,02
D023 06 08 LD B,08
D025 D9 EXX
D026 0E 02 LD C,02
D028 D5 PUSH DE
D029 E1 POP HL
D02A 06 08 LD B,08
D02C CB 06 RLC (HL)
D02E 1F RRA
D02F 23 INC HL
D030 23 INC HL
D031 10 F9 DJNZ D02C
D033 CD 3ED4 CALL 3ED4
D036 0D DEC C
D037 20 F1 JR NZ,D02A
D039 D9 EXX
D03A 10 E9 DJNZ D025
D03C D9 EXX
D03D 13 INC DE
D03E D9 EXX
D03F 0D DEC C
D040 20 E1 JR NZ,D023
D042 D9 EXX
D043 C9 RET

ニーモニック

CPUは命令と書いてあるパターンで作業するが、人間にはこれはきついので、それぞれどのような命令かを短く書いたものがニーモニックと呼ばれるものである。これならば少し楽になる。

ニーモニックはプログラミング言語ではありません。単にわかりやすい記号にしたものです。

LD load データの転送
INC increase 1増やす
OUT out put 出力
JR jump relative 相対ジャンプ
RET return 戻る
NOP no operation なにもしない
CALL call 他のアドレスにあるプログラムを呼び出して実行する

z80のレジスタ

CPU内部にあり、データを加算したり一時保存したりする場所。z80の場合はAF,BC,DE,HLがもう一セットあり、切り替えることができました。上で出てくる EXX命令は、AFをそのままに、BC,DE,HL を一度に別のセットに切り替えるものです。

7   0 7   0
A F
B C
D E
H L
IX
IY
PC
SP

このレジスタの数と機能もCPUによりまちまちです。

CPUによって異なる機械語

上記の例は、z80というCPUのものです。

命令の意味するところも、ニーモニックの書き方もそれぞれ違います。

このプログラムの時代はz80の所属する86系と68系という2つの大きな流れがありました。それぞれの国に生まれた人は他国のCPUのプログラムはわからないというのが普通でした。

z80の元になったのは8080というインテル社のCPUで、これはその後、8086, 80186, 80286, 80386, i486, Pentium と製品が続き現在のPC用CPUの主流をなしています。

訂正箇所

初めてこのページを見る方には、読む必要の無いものです。以前と違うじゃないかという方へのお詫びです。

1行に16個ずつ書いたメモリへの格納状況の表
(1) 以前は12個の00が抜けてその部分以降アドレスがずれてしまい、D043のC9などとの説明に合いませんでした。

(2) CALL NNMM の目的地のアドレスは上位バイトと下位バイトが バイトの並びと ニーモニックで逆になります。格納状況をプログラムリストから作った時に直していませんでした。正しく書き直しました。

機械語のプログラムの例
(1) こちらも00のNOPが抜けていました。しかし、NOPは何もしない命令ですし、アドレスごと抜けていたのでアドレスのずれはなく、プログラムの内容には関わらない間違いでした。

(2) D02Cの RLC (HL) は EXX と誤記していました。Z80の拡張命令で8080用のディスアセンブラが解釈できなかったものを手作業で直して間違いが生じました。CB 06 1F の並びは正しかったのですがニーモニックが間違っていました。

このページのニーモニックの記法について

次の並びは間違いではありません

D008	CD 7261		CALL 7261  ;CD 61 72 に対して
D033 	CD 3ED4 	CALL 3ED4  ;CD D4 3E に対して

この記法はNECのPC-8801のモニタについていた逆アセンブラの表記に合わせたものです。

7261は漢字ROMからフォントデータを読み出すルーチン、3ED4は1バイトをプリンタに出力するルーチンの開始アドレスです。

この逆アセンブラのニーモニックは8080用のものでした。LDはMOV、INCはINXなどと表記されました。Z80の拡張であるEXXやRLC (HL)は、???と表記されていました。

このプログラムはPC-8801を所有していた時に自作したもの(1983)ですが、機械語のプログラムの例として教材化した時に???では説明のしようがないのでZ80の表記に全面的に書き換えたのです。教材化の時にはすでに実機がなく紙の出力から起こしたためにいろいろ間違いを発生させました。ニーモニックの雰囲気を味わえれば問題ないのですが、思い入れのあるプログラムだったので、いまさらですが訂正させていただきました。