個々のDeM命令コードを説明するために「命令コード表」を使います。この表の見方を説明します。
DeM命令の構造
DeMは命令の最小単位が1バイトである「バイトマシン」です。DeMは10進数のみ扱うように作られているため1バイトでは00~99までの100種類のバリエーションしか持てません。そこで、さまざまな命令構成に対応するため、命令によっては複数の追加のバイトを後ろにつなげて1つの命令となるようにしています。これを「可変長命令」と呼びます。
命令は「〇〇に対して△△を□□せよ」という意味です。命令によっては「〇〇に」の部分や「△△を」部分が暗黙の了解になっていたりして単に「□□せよ」だけになっているものもあります。「□□せよ」の部分を「命令コード」とか「オペコード」と呼びます。対して「〇〇に」や「△△を」の部分を「オペランド」と呼びます。
つまり1つの命令は1つのオペコードといくつかのオペランドから成り立っていることになります。もちろんオペランドがない場合も含みます。命令の構造から分類すると下記のようになります。
構造からの分類 | 例 | 例の命令バイト列 | ||||
---|---|---|---|---|---|---|
オペコードだけ | RET | 65 | ||||
オペコードにオペランドを含む | LDI.d 8 | 28 | ||||
オペコード+オペランド1バイト | LDI.b 75 | 30 | 75 | |||
オペコード+オペランド2バイト | LDI.w 1402 | 31 | 14 | 02 | ||
オペコード+オペランド4バイト | LDI.q 31415926 | 32 | 31 | 41 | 59 | 26 |
オペコードにオペランドを含む+オペランド1バイト | JBEQ 40 EQの部分がオペランド |
50 | 40 | |||
オペコード+ 命令バリエーションとオペランドを含む1バイト |
LDM.b R5 | 33 | 05 | |||
オペコード+オペランドを2つ含む1バイト | MASK 6, 4 | 87 | 64 |
プログラムの配置
プログラムは複数の命令の連なりです。DeMは連なった命令を順番に実行します。プログラムはプログラムメモリ中に置かなくてはなりません。WOBではアドレス0000番地から0999番地までの1000バイトがプログラム領域としています。命令を配置するにはアドレスの小さいほうから大きいほうに向かって実行する順に並べていきます。命令はきっちり詰め込んで並べなければなりません。たとえば0400番地に1バイトの命令があった場合は次の命令は必ず0401番地に書かれなければなりません。
これはプログラムカウンター(PC)が次に実行する命令のあるメモリアドレスを覚えているという仕組みによるものです。「カウンター」ですから基本的にプラス1する動作をします。命令を実行する際にオペコードやオペランドを1バイト読み込むごとにプラス1するようにできています。つまり5バイトからなる命令の場合は命令実行後にはPCは5増加することになります。この仕組みはWOBに限らずどのCPUでも基本は同じです。
命令の機能分類
命令表の「Category」の欄では、命令の機能から見た分類がされています。大まかに説明しますと、
Transfer | データのレジスタ間転送と定数代入 |
Memory | レジスタ~メモリ間転送、スタック操作、入出力(レジスタ~I/O間転送) |
Branch | 条件分岐、非条件分岐(ジャンプ)、サブルーチンコール |
Arithmetic | 算術演算(四則演算、比較など) |
Logical | 論理演算(桁シフト、桁抽出、桁挿入など) |
Control | フラグ設定、プロセッサ制御など |
となります。
データ長の指定
データ長指定記号 | 意味 | |
---|---|---|
.d | digit | 10進1桁 |
.b | byte | 1バイト=10進2桁 |
.w | double | 2バイト=10進4桁 |
.q | quad | 4バイト=10進8桁 |
オペランドや操作対象のメモリのデータ長に指定が必要な命令があります。LDI、LDM、STM命令です。ニーモニックの末尾に「.b」などデータ長指定の記号が付きます。記号の意味を右に示します。
データの配置
1バイトを超えるデータ長をどのようにメモリに配置するのでしょう。DeMではアドレスの小さい側にデータの上位桁が来るように配置する方式をとっています。
アドレス | データ |
---|---|
1000 | 12 |
1001 | 34 |
たとえば前述の「.w」すなわち2バイト=10進4桁のデータ長の「1234」という数値は1000番地からのメモリ上では左のように配置されます。
アドレス | データ |
---|---|
1000 | 12 |
1001 | 34 |
1002 | 56 |
1003 | 78 |
また、「.q」すなわち4バイト=10進8桁の「12345678」という数値は右のように配置されます。
この方式は”Big-endian”(ビッグエンディアン)と呼ばれています*1。
*1 Java仮想マシンはビッグエンディアンです。世の中には逆の「リトルエンディアン」という方式を採用しているCPUもあります。アドレスの小さい側に下位の桁を入れる配置です。インテルのWindows用CPUは伝統的に「リトル」のほうを採用しています(一度決めたら互換性を保つために切り替えられない)。近年ではエンディアンを切り替えられるCPUも登場しています。
命令の実行結果
命令は何らかの操作をした後結果を残します。操作対象のレジスタに残った値がその一つ。命令によってはそのほかにステータスレジスタ(SR)にも結果の一部を残すものがあります。演算系の命令がそれです。加算して桁あふれが(繰り上がり)起こった場合の繰り上がりの値。2つのレジスタ間で比較して同じ値だったかどうか、大小関係があったかどうか。これらをSR内のCy(Carry = 繰り上がりまたは桁借り)桁とCd(Condition = 状態または条件)桁に保持します。
命令コード表中のCy、Cd欄が「Y」の場合は命令の実行結果に応じてその桁が変化します。「0」の場合は必ずクリア(0になる)されます。