JH8CHUのホームページ>仮想機械(VM)

仮想機械(Virtual Machine)


アーキテクチャと命令仕様について記述。(2013/02/26)
疑似命令仕様変更(end命令追加。dd命令はレベル1から外す)。(2016/09/04)
疑似命令に-->(next sector)を追加。(2016/09/14)
  1. 仮想機械アーキテクチャ

    1. 特徴
      • FORTH言語の仕様を参考に定義
        FORTH言語の仕様に似せて、独自に定義した仮想機械です。
        機械語(f-code)はrun timeルーチンにより実行します。
      • スタック・マシン
        演算やメモリ・アクセスは全てスタック・ポインタを中心に行われます。
        (いわゆるアキュームレータや汎用レジスタなどはありません。)
      • 固定少数点演算
        仮想機械が直接実行出来るのはFORTHと同様、固定少数点演算のみです。
      • パラメータ・スタックとリターン・スタック
        スタック・ポインタとしては、パラメータ・スタック・ポインタ(sp)と
        リターン・スタック・ポインタ(rp)の2本のポインタを持ちます。
        演算のデータを置くのがパラメータ・スタック、サブルーチンからの
        リターン・アドレスの格納等に使用するのがリターン・スタックです。

    2. レジスタ
        レジスタはいずれもマシン・レベルによってビット長が異なります。
        2013年2月時点で定義されているのはビット幅16bitのマシン・レベル1
        のみです。
      • pc (Program Counter)
         実行する仮想機械語命令の格納されたアドレスを指すポインタです。
      • sp (Parameter stack Pinter)
         演算データを格納するメモリ(スタック領域)のアドレスを指すポインタです。
         スタックに最後に積まれたデータをTOS (Top Of Stack)と呼びます。
         以下、2番目、3番目のデータを2nd、3rdと呼びます。
         スタックはメモリ番地の低い方に向かって伸びて行きます。
         以下の説明では、単にTOSと言えばパラメータ・スタックのトップを
         指します。リターン・スタックのトップはリターン・スタックの
         TOSと記述します。以下、2nd、3rdなども同様です。
      • rp (Return Stack Pinter)
         サブルーチンからのリターン・アドレスの格納等に使用しますが、
         ループ処理命令(do)などでも使用されます。(詳細は命令仕様を参照)
         spはマシン・レベル1においては16bit長です。
         スタックはメモリ番地の低い方に向かって伸びて行きます。
         スタックのデータ幅は16bit単位です。
      • 例外処理用レジスタ【仕様未決】
         本仮想機械で例外処理を行うためのレジスタです。
         このレジスタはFORTHには定義がありません。
         本仮想機械の独自仕様です。
    3. データ構造
      スタック上のデータは2バイト単位です。
      2バイトのデータの上位バイトと下位バイトがそれぞれ偶数番地と奇数番地の
      どちらに格納されるか(すなわちエンディアン)はCPUによって異なるため
      仮想機械としては定義しません。
      従って、特定のエンディアンを想定したプログラムは記述しないこととします。
    4. マシン・レベルとメモリ空間
       実際のCPUはアドレス空間が64kバイト(16bit)、4Gバイト(32bit)など
       あるため、本仮想機械ではマシン・レベルとゆう概念を導入して
       アドレス空間の違いに対応します。但し、現状、仕様が確定しているのは
       マシン・レベル1のみです。
       マシン・レベル1の仮想機械がマシン・レベル2またはマシン・レベル3
       の命令語を実行しようとすると特権違反の例外処理となります。
      1. マシン・レベル1
        アドレス・リーチ:16bit = 64kバイト
      2. マシン・レベル2
        アドレス・リーチ:32bit = 4Gバイト
      3. マシン・レベル3
        アドレス・リーチ:64bit
       マシンレベル1マシンレベル3マシンレベル3
      レベル1機械語実行可不可不可
      レベル2機械語実行可実行可不可
      レベル3機械語実行可実行可実行可
    5. 入出力
      後報
    6. 例外処理
      仕様未決
      現在、特権違反が発生すると、仮想機械は異常終了となる。

  2. 命令仕様

    1. データの表現
      • addr メモリアドレス(16bit)
      • b  8ビットデータ
      • d  32ビット符号付き倍精度整数。TOSは符号付き上位16ビット
      • n  16ビット符号付き単精度整数。
      • u  16ビット符号なし整数
      • ud  32ビット符号なし整数
      • f  ブール・フラグ。0は「偽」、非ゼロは「真」
      • tf  ブール・真フラグ。すなちわ非ゼロ。
      • ff  ブール・偽フラグ。すなわち0。

    2. パラメータの表現
      命令表のパラメータ欄の記述は、例えば+命令の場合
      n1 n2 --- sum
      となっていますが、これは命令実行前後のパラメータスタックの
      使われ方を示します。上記の例では、命令実行前にスタックにはn1、n2
      データが用意されており、命令実行後にsumのデータがスタックに
      残ることを表現しています。



    3. 命令コードの分類(暫定版)
      命令コード
      <16進数)
      ニーモニック機能
      0f〜7f システム予約
      10〜7f 16bitアドレス(マシン・レベル1)
      80〜bf 32bitアドレス(マシン・レベル2)
      c0〜ef 予約
      f0〜7f システム予約

    4. システム予約命令(この表の詳細は後報)
      コード
      (16進数)
      ニーモニック機能
      後報 COLD START
      後報 HOT START
      後報emitASCII文字Cをターミナルに出力
      後報key次に入力されるASCII文字をTOSに得る
      後報qtermブレークキーを押したか否かのチェックをする
      後報expectシステム予約
      後報setdrvシステム予約
      後報setioシステム予約
      後報sec_rdシステム予約
      後報sec_wtシステム予約

    5. スタック・アクセス用命令(マシン・レベル1命令)
      コード
      (16進数)
      命令長ニーモニックパラメータ 機能
      後報3lit [n]--- n命令語のオペランド(n)をTOSに積む
      後報1dupn --- n nTOSをコピーする
      後報1overn1 n2 --- n1 n2 n12ndをコピーする
      後報1rotn1 n2 n3 --- n2 n3 n1TOS,2nd,3rdの3データを回転し 3rdがトップとなるようにする
      後報1dropn --- TOSを捨てる
      後報1r>--- nリターンスタックのトップをTOSにコピーし リターンスタックの
      トップは捨てる。 r>は「R from」と読む
      後報1>rn ---TOSをリターンスタックのトップにコピーし TOSは捨てる。
      >rは「to R」と読む
      後報1i--- nリターンスタックのトップをTOSにコピーする。
      リターンスタックは影響を受けない。
      後報1sp@--- nTOSのメモリアドレス、すなわちパラメータ スタックポインタ
      の値をスタック (TOS)に得る
      後報1rp@--- nリターンスタックのメモリアドレス、すなわち
      リターンスタックポインタの値を スタックに得る
      後報1sp!---パラメータスタックを初期化する
      後報1rp!---リターンスタックを初期化する

    6. メモリ・アクセス用命令
      コード
      (16進数)
      命令長ニーモニックパラメータ 機能
      後報1@addr --- nTOSで示される番地のメモリ2バイトの内容を 読み、
      それをTOSに積む。 番地は捨てられる。
      @は「fetch」と読む
      後報1!n addr ---2ndの値をTOSで示される番地のメモリ
      2バイトに格納する。 !は「store」と読む。
      後報1c@addr --- bTOSで示される番地のメモリ1バイトの内容を 読み、
      それをTOSに積む。 番地は捨てられる。
      c@は「c fetch」と読む
      後報1c!b addr ---2ndの値の1バイトをTOSで示される番地のメモリ
      1バイトに格納する。 c!は「c store」と読む。
      後報12@addr --- 2dTOSで示される番地のメモリ4バイトの内容を 読み、
      それをTOSに積む。 番地は捨てられる。
      2@は「two fetch」と読む
      後報12!d addr--- 2nd,3rdの値をTOSで示される番地のメモリ
      4バイトに格納する。 2!は「two store」と読む。

    7. 演算用命令
      コード
      (16進数)
      命令長ニーモニックパラメータ 機能
      後報1+n1 n2 --- sum単精度(2バイト)の2整数の和を求める
      後報1-n1 n2 --- diff2ndからTOSを引いた差を求める
      diff=n1 - n2 。単精度
      後報1minusn1 --- n2TOSの符号を反転する
      後報1<n1 n2 --- tf (n1<n2のとき)
             ff (n1>n2のとき)
      大小判断し結果のフラグをTOSに求める
      後報10=n --- tf (n1=0のとき)
          ff (n1≠0のとき)
      ゼロの検査をする
      「真」「偽」フラグの反転にも使用します
      (NOTと同じ)
      後報10<n --- tf (n1<0のとき)
          ff (n1≧0のとき)
      負符号の検査をする
      0<はn 0 <の略記
      後報11+n1 --- n2TOSに1を加える
      後報11-n1 --- n2TOSから1を引く
      後報12+n1 --- n2TOSに2を加える
      後報12-n1 --- n2TOSから2を引く
      後報12*n1 --- n2TOSの2倍を求める
      後報12/n1 --- n2単精度符号付き整数n1を2で除しその商n2
      を求める。割り切れないときは商は
      切り捨てられる
      後報1andn1 n2 --- n3n1とn2のビット毎の論理積を求める
      後報1orn1 n2 --- n3n1とn2のビット毎の論理和を求める
      後報1xorn1 n2 --- n3n1とn2のビット毎の排他的論理和を求める
      後報1d+d1 d2 --- dsum倍精度(4バイト)の2整数の和を求める
      後報1dminusd1 --- d2倍精度整数の符号を反転する
      後報1u*u1 u2 --- ud単精度符号なし整数u1とu2の積を
      倍精度符号なし整数udに求める
      後報1u/ud u1 --- u2 u3倍精度符号なし整数udを単精度
      符号なし整数u1で割り、単精度符号なし
      整数の余りu2と商u3を求める
      後報1s->dn --- d符号付き単精度整数nを符号付き倍精度
      整数dに変換する。s->dは
      「singl to double」と読む
      後報1+!n addr --- TOSで示される番地の2バイトの内容に
      2ndを加える。+!は「plus store」と読む

    8. 分岐用命令
      コード
      (16進数)
      命令長ニーモニックパラメータ 機能
      後報3bsr [n]---命令語のアドレスからオペランド(n)で
      示される相対番地のサブルーチンに分岐する
      リターンアドレスはリターンスタックに積まれる
      後報1rts---サブルーチンからメインルーチンに戻る
      後報1jmpaddr ---TOSで示す絶対番地(addr)に分岐する
      後報1leave---do 〜 loopまたはdo 〜 +loopの間で用い
      リターンスタックの限界値を制御値と等しく
      することによりloopまたは+loopに到達したとき
      ループを終了する。詳細は擬似命令の
      do、loop、+loopを参照

    9. 構造化用命令
      これらの命令はアセンブラの構造化用擬似命令によりアセンブルされます。
      アセンブラで直接記述することは出来ません。
      コード
      (16進数)
      命令長ニーモニックパラメータ 機能
      後報3bran [n]---命令語のアドレスからオペランド(n)で
      示される相対番地に分岐する
      後報30bran [n1]n2 ---TOS(n2)の値が0なら
      命令語のアドレスからオペランド(n1)で
      示される相対番地に分岐する
      TOSが0でないなら0branの次の命令を実行
      後報1(do)n1 n2 ---TOSはリターンスタックのトップに
      2ndはリターンスタックの2ndに移される
      後報3(loop) [n]---リターンスタックのTOS(制御値)に1を加え
      加えた値がリターンスタックの2nd(限界値)
      以内なら(loop)命令のアドレスからnで
      で示される相対番地に分岐する
      後報3(+loop) [n1]n2 ---リターンスタックのTOS(制御値)にn2を加え
      加えた値がリターンスタックの2nd(限界値)
      以内なら(+loop)命令のアドレスからn1で
      で示される相対番地に分岐する


  3. f-code仮想機械(ランタイムルーチン)の実装例 (マシン・レベル1対応)

    1. javaよる実装

      javaによる実装の詳細はこちら。(工事中)

    2. C言語による実装(H8/3069F用)

      C言語による実装(H8/3069F用)の詳細はこちら。(工事中)

    3. C言語による実装(PC用)

      C言語による実装(PC用)の詳細はこちら。(工事中)

    4. オリジナルCPUによる実装

      計画中。

  4. アセンブラ (マシン・レベル1対応)

    1. 特徴
      • FORTHライクな構造化アセンブラ。
      • このアセンブラの目的は、主に、モニター、VTL、FORTHの
        記述です。。 今後、仮想OSやtinyコンパイラが立ち上がった場合、
        使用頻度は低下するため、使い勝手よりも、仕様が小さくなることを
        優先します。

    2. 仕様
      • 命令語、擬似命令
        大文字と小文字は区別される。
      • ラベル
        英数記号を使用出来る。大文字も使用可能。 記号のみのラベルも定義できる。
        漢字は使用できない。
      • 数値
        16進数のみ使用可能。
        a,b,c,d,e,fは小文字のみ使用可能。A,B,C,D,E,Fはエラーとなる。
        最大4桁まで指定できるが、4桁を超えた場合、下位4桁のみ有効。
        【この仕様は、暫定。マシン・レベル2対応時見直す】
      • 定数(db、dw、dd)
        16進数のみ指定可能。ここにラベルの指定は出来ない。
      • コメント
        左カッコ ( 以降の記述はコメントになる。
        左カッコの前後にはスペースがひとつ必要。
        コメントは右カッコまでとなる。
        右カッコの前後のスペースは必須ではない。
        コメントは行をまたげない。右カッコはなくてもよい。
        その場合、行末までがコメントとみなされる。
        コメント内にタブを置くことは出来ない。
        (コメントの終了とみなされる。右カッコと同じ扱い)
        漢字の使用は想定していない。
      • 区切り文字
        区切り文字は特に指定がなければスペースと改行。
      • 擬似命令
        後報

    3. 構造化用擬似命令
      内部処理用
      擬似コード
      (16進数)
      ニーモニックパラメータ 機能
      後報iff ---(実行時) 次の形で使用する
      if (真の処理) endif
      if (真の処理) else (偽の処理) endif
      後報else---
      後報endif---
      後報don1 n2 ---(実行時) 次の形で使用する
      do (反復実行する処理) loop
      do (反復実行する処理) +loop

      doにおいてTOSはリターンスタックのトップに
      2ndはリターンスタックの2ndに移される
      +loopは対応するdoとの間の制御値にnを
      加え、限界値と比較して限界値以内なら
      反復実行する処理する。
      限界値を超えていたらループから抜け、
      リターンスタックに積まれた制御値と
      限界値を捨てる
      後報loop---
      後報+loopn ---(実行時)
      後報begin--- 次の形で使用する
      begin (反復する処理) again (無条件反復)
      begin (反復する処理) until (条件反復)
      begin (反復する処理1) while (反復する処理2) repeat(条件反復)

      untilに到達したときフラグfが「偽」なら
      beginまで戻り、フラグfが「真」なら
      untilの次の処理に進む

      whileに到達したとき、フラグfが「真」なら
      (反復する処理2)を実行しrepeatまで進み
      対応するbeginまで無条件で戻る
      whileに到達したとき、フラグfが「偽」なら
      repeatの後ろに進みループを抜ける
      後報again---
      後報untilf ---(実行時)
      後報whilef ---(実行時)
      後報repeat---

    4. その他擬似命令
      内部処理用
      擬似コード
      (16進数)
      ニーモニックパラメータ 機能備考
      後報lit [n]---定数[n]をTOSに積む 
      後報lit.a---  
      後報.org--- n 保留。
      後報.end---実行時、プログラムを終了する。
      (仮想機械が終了する)
      .end命令は必須ではない。またソース中に
      複数記述してもよい。
       
      後報db [b] --- メモリ上に1バイトの領域を確保しその内容を
      bとする。bは16進数で、2桁を超えた場合は
      下2桁のみ有効となる
       
      後報dw [w] --- メモリ上に2バイトの領域を確保しその内容を
      wとする。wは16進数で、4桁を超えた場合は
      下2桁のみ有効となる
       
      後報dd [d] --- メモリ上に4バイトの領域を確保しその内容を
      dとする。dは16進数で、8桁を超えた場合は
      下2桁のみ有効となる
      レベル1仕様
      からは外す。
      後報fca [label] --- メモリ上に2バイトの領域を確保し
      その内容を[label]で指定したアドレスの内容
      とする。[label]はfcaから参照する以前に
      定義されている必要がある。
       
      後報$+2 --- メモリ上に2バイトの領域を確保しその内容を
      メモリ領域のアドレスに2を加えた値とする
      これはFORTHを定義するための擬似命令なので
      詳細はFORTHを参照。(後報)
       
      後報label---labelの位置にある命令のアドレスをラベルテーブルに
      登録し、bsr命令、fca命令より参照出来るようにする
       
      後報(---コメントの開始を表し、コメントの終了は)までとなる
      (は擬似命令なので、前後にスペースが必要で
      あることに注意
       
      後報-->---"next sector"と呼ぶ。
      現在アセンブル中の仮想セクタNo.の次のNo.の
      仮想セクタを読み込み、アセンブルを継続する。
      アセンブラ・ソースが複数セクタにまたがる
      とき使用する。セクタNo.は連続して
      いなければならない。
       
      後報endbsr [n]ソース・プログラムの終わりを示す。
      この命令以降のソースはアセンブルされない。
      ラベル[n]はプログラムの開始位置を示すラベルで
      省略は出来ない。endはソース・プログラム中に
      必ずひとつ必要。2つ以上記述した場合、最初の
      記述が有効になる。
      .end命令とは異なるので注意。
       


  5. アセンブラの実装例(マシン・レベル1対応)

    1. VTLよる実装
      VTLによる実装の詳細はこちら。(工事中)

    2. C言語による実装

    3. 参考〜アセンブラのソース事例

      (1)ソース・プログラム例@


      (2)パソコン上での実行例@


      (3)ソース・プログラム例A


      (4)パソコン上での実行例A



  6. モニター (マシン・レベル1対応)

    この仕様は大幅に縮小予定。
    1. mコマンド 【完成】
    2. pコマンド 【開発中】
    3. hコマンド 【保留】
    4. cコマンド 【保留】
    5. gコマンド 【保留】
    6. rコマンド
    7. sコマンド
    8. qコマンド 【完成】
    9. dコマンド 【仕様検討中】
    10. lコマンド 【仕様検討中】
    11. vコマンド 【仕様検討中】
    12. oコマンド (名称検討中)

  7. サブルーチン作成事例

    1. 数値入出力

    2. 初等関数(固定小数点)
    3. 浮動小数点演算


JH8CHUのホームページ>仮想機械(VM)


Copyright (C)2013, 2016 Masahiro.Matsuda(JH8CHU), all rights reserved.