CPUと機械語

メモリの考え方

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

データの格納状況
番地(アドレス) データ
110100000000000001011110
110100000000000100100011
110100000000001001010110
110100000000001111110011
110100000000010000111110
110100000000010111111110
110100000000011011010011
110100000000011101110001
110100000000100011001101
110100000000100101110010
110100000000101001100001

2009年現在PCのメモリは2GB(=2000000KB)あたりが普通になっているのでもちろん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個の記号で
番地 データ
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 72 61 3E FF D3 71 FB 
D010 13 13 13 13 D9 0E 02 06 08 D9 0E 02 D5 E1 06 08 
D020 CB 06 1F 23 23 10 F9 CD 3E D4 0D 20 F1 D9 10 E9 
D030 D9 13 D9 0D 20 E1 D9 C9 00

この場合、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
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 EXX
D02D 06 1F LD B,1F
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
D045 00 NOP

ニーモニック

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

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

LD load データの転送
INC increase 1増やす
OUT out put 出力
JR jump relative 相対ジャンプ
RET return 戻る
NOP no operation なにもしない

z80のレジスタ

CPU内部にあり、データを加算したり一時保存したりする場所。z80の場合は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の主流をなしています。

聖愛中学高等学校
http://www.seiai.ed.jp/
May. 2009