[PP0906] 14. 不正命令例外

ここまでで 28 種類の命令を追加してきました。デコーダにあたる switch 文もかなり長くなったことと思います。ところで、この switch 文ですが、まだ default ラベルを書いていませんね。今回は、定義されていない命令を実行しようとしたときの PP0906 の動作を定義したいと思います。

PP0906 では、定義されていない命令を実行しようとすると、不正命令例外が発生します。不正命令例外はプロセッサの例外の一種です。内部割込みという言いかたをする場合もあります。

不正命令例外が発生すると、PP0906 の場合、現在の PC の値をスタックに退避したうえで、0xf000 番地にある例外ハンドラを呼出します。例外ハンドラは一種のサブルーチンですので、RET 命令で戻ることができます。

それでは、不正命令例外を発生させるプログラムを書いてみることにします。

int program[] =
{
  LXI, 0x10000,
  MOVSX,
 
  -2,
  LI, 123,
  OUT,
  -1
};
 
int illegal[] =
{
  LI, -2,
  OUT,
  RET
};

ここで、-2 というのが「不正命令」にあたります。配列 illegal は不正命令例外のための例外ハンドラですので、memcpy で 0xf000 番地のロードしてください。このプログラムを実行した場合に想定する結果は次の通りです。

0xfffffffe(-2)
0x0000007b(123)

では、不正命令例外を発生させる動作を定義しましょう。

default:
  eaddr = 0xf000;
  sp = sp - 1;
  memory[sp] = pc;
  pc = eaddr;
  break;

CALL 命令と比べてみると、呼出し先のアドレスを取得する必要がない点をのぞけば、まったく同じであることがわかると思います。実際のプロセッサでは、例外ないしは内部割込みの動作が、サブルーチンの呼び出しとは異なる場合もよくあります。例えば、スタックに退避するのが PC だけでなく、フラグなど、別のレジスタも一緒に退避したりします。PP0906 は簡単であることを目標にしていますので、このような設計にしました。

この記事のトラックバックURL:

http://www.kijineko.co.jp/trackback/529
このエントリーを含むはてなブックマーク