ソフトウエアの立場から見たCPUの基本イメージはつぎのようなものになる。
PC : プログラムカウンタ。IPインストラクションポインタともいう。
次に実行する命令のアドレスを保持する。通常上から(低位番地から)下へ伸びる。
SP : スタックポインタ
スタックのアドレスを保持する。通常下から(高位番地から)上に向かう。
A : アキュムレータ
ALUの演算結果が入る。
CCR : コンディションコードレジスタ (フラグともいう)
ALUの演算結果後のAの状態を反映する。
S: サイン、 Z: ゼロ、 P: パリティ、 C: キャリー (ビット)
以上はレジスタである。
Memoryは命令、データと場合によってはIOを保持する。
0000から(FFFF)の間をそのCPUの「メモリー空間」という。
()を付けたのは、この値はCPUによって違うからである。
この空間にはROM,RAM、IOが存在できる。
なにも実装されていない空間(アドレス)もある(ありうる)。
CPUの動作を規定する上での最も基礎的な言語はアセンブラである。 C言語などの高級言語も最終的にはアセンブラに翻訳されて実行される。
アセンブラの記述形式
ABC MOV A, 0xaa ; comment
ABC: ラベル(無いばあいのある)
MOV: オペレーションコード(命令)
A, 0xaa: オペランド
;comment: コメント
CPUの命令には
転送、演算、比較、分岐、サブルーチンコール
などがある。それぞれ、
MOV, ADD, CMP, JMP, CALL
などと表される。(これをニーモニックという)
転送命令 MOV
MOV A, 0xaa
この場合はオペランドが2つあって、Aを第一(オペランド)、0xaaを第二という。
また、Aはデスティネーション:転送先、0xaaはソース:転送元となる。
この動作は
A <- 0xaa
であり。Aレジスタに0xaaが入る。(Aの内容が0xaaになる)
なお、実際の動作はコピーであり、転送元が消えてしまうことはない。
別の転送命令
MOV A, (0x1234)
は0x1234番地の内容をAレジスタに入れることになる。
0xDAこの動作をするマシンコード、0x32,0x12はデータが 入っているアドレスである。この命令コードは、DA, 34, 12 の順でメモリーに入っている。このようにどの順序で多バイトデータが メモリーに配置されるかをビッグエンディアン、リトルエンディアンという。 インテル系CPUではこのように低位アドレスに 低位バイトがはいる。モトローラ系は反対になる。ネット上ではこのことがバイトオーダーとして問題になることがある。
この命令の実行後のCPUは次図のようになる。
CCRの'-'は変化しなかったことを示す。インテル系のCPUではこの場合のように 単純にデータをロードしただけではフラグビットが変化しないものがあるので 注意が必要である。
この命令は3バイトで構成されたので、3バイト命令という。
演算命令 ADD
ADD A, 0x83
これは加算命令で、つぎのような動作をする。
A <- A + 0x83 (Aは7Cとする)
この結果Aは0xFFとなる。 0xC1はこの動作を表すマシンコードである。
この結果フラグビットは更新される。
S = 1 : Aのbit7が1であるため。
Z = 0 : Aが0でないため。
P = 1 : Aのパリティが偶数であるため。
C = 0 : Aのオーバー(アンダー)フローが無かったため。
もし、もう一つ大きな0x84を足していたら1が立っていただろう。(その場合Aは0)
分岐命令 JMP
これは無条件分岐である。
JMP 0x0010
0xC3はJMP命令のマシンコード。 無条件分岐とはプログラムカウンタ(PC)の値を書き換えることになる。
比較命令 CMP
比較(または演算)命令の次には条件分岐命令が入ることになる。
CMP A, 0xC2
JC L1 ; A < 0xC2
JZ L2 ; A = 0xC2
; A > oxC2
....
....
JMP L4
L1 ....
JMP L4
L2 ....
JMP L4
L4 .....
サブルーチンコール CALL
スタックの仕組みを使って呼び出し元へもどる。
CALL SUB1 ; SUB1は1234番地 SUB1 CALL SUB2 ; SUB2は2345番地 RET SUB2 RET
SUB2の先頭でRET命令を実行する前
CALL命令で戻り番地をスタックに積み(プッシュするという)、 RET命令でスタックポインタの指し示すスタックから番地を取り出し(ポップする) プログラムカウンタにセットする。 割り込みでも同様の方法で割り込まれた場所に復帰する。
C言語では引数もスタックに積んで関数へ渡す。このことによりリエントラントな 関数が容易に実現できる。
データとスタックはRAMが使われるが、コードはROMでもRAM でもよい。ただし不揮発性である(電源を切っても消えない)ことが 必要である。汎用的なコンピュータ(パソコンなど)にはROM の概念がない。全部RAMである。(BIOSは除く)
スタック領域は下から上へ、データは上から下へ伸びてくるので、 領域がぶつかる可能性がある。スタックが壊されると元のルーチンへ 戻ることができなくなる。システムは意図した動きをしない。これを 暴走という。データが壊されても同様だが、障害は一部に留まる。 (暴走はしないだろう) パソコンなどでは上手にスタックを壊すことにより、任意のコードが 実行可能になることがある。ウイルスの手口として悪用されることが ある。