LoginSignup
2
1

こちらの記事にてMind開発者の@killyさんより情報共有いただいたMind8の検証用Consoleをベースに一部正規のConsoleのコードを取り込んだ中間コードhellolevel0.mco(Mind中間コードステップ数51)を完走させましたが、ステップ数60のhellolevel1.mcoはまだ完走できずにいます。そこで本記事ではMind8のオリジナルCランタイムディスパッチャのmcodeモニタ機能を改修して、C#代替ディスパッチャと同等となるようにスタック値をコンバートしてみることとします。

前提条件

Windows11 Pro 22H2
VSCode(Visual Studo Code) 1.86.1
Microsoft Visual C++ 2008 Express Edition
Mind Version 8.0.08 for Windows
C# 12
dotnet-sdk-8.0.204-win-x64

VSCodeの拡張機能

C/C++ for Visual Studio Code 1.18.5 Microsoft
C/C++ Extension Pack 1.3.0 Microsoft
.NET Install Tool 2.0.2 Microsoft
Base language support for C# 2.18.16 Microsoft

C/C++のデバッガはCで実装されているMind8kernelの動作をデバッグ実行で探るために使用します。こちらの記事の環境となります。

お題のMind8の中間コード実行リスト

C側検証環境で、お題のステップ数60のhellolevel1.mco中間コードファイルをディスパッチャで処理させた結果が下記です。途中略しています。

SqNo mcode mc(dec) mpoint dtp.point  dtp+0   dtp+1 rtp.point  rtp+0  rtp+1
   1 8019  32793     57   1024        0        0   1024        0        0
   2 002F     47     51   1024        0        0   1023        0        0
   3 0012     18   2931   1024        0        0   1023        0        0
   4 0036     54   2932   1024        0        0   1023        0        0
   5 0080    128   2935   1024        0        0   1023        0        0
   6 0036     54   2936   1024        0        0   1023        0        0
   7 0070    112   2939   1024        0        0   1023        0        0
   8 803A  32826   2940   1024        0        0   1023        0        0
   9 002F     47    119   1024        0        0   1022        0 13385794
  10 80B8  32952   2929   1024        0        0   1022        0 13385794
  11 0012     18   2921   1024        0        0   1021        0 13391560
  12 0036     54   2922   1024        0        0   1021        0 13391560
  13 0071    113   2925   1024        0        0   1021        0 13391560
  14 8046  32838   2926   1024        0        0   1021        0 13391560
  15 8045  32837    163   1024        0        0   1020        0 13391538

  36 00A5    165   2954   1024        0        0   1023        0        0
  37 00C1    193   2963   1022       14 13391590   1023       14        0
$$COLD_FORTH
  38 0020     32   2964   1024        0        0   1023        0        0
  39 80C3  32963     58   1024        0        0   1024        0        0
  40 00A5    165   3193   1024        0        0   1023        0        0
  41 8083  32899   3202   1022       14 13392068   1023       14        0
  42 0012     18   1755   1022       14 13392068   1022       14 13385796
  43 004E     78   1756   1022       14 13392068   1022       14 13385796
  44 00EC    236   1759   1020        0        0   1022        0 13385796
  45 0096    150   1762   1022       14 13392068   1022       14 13385796
  46 026D    621   1763   1020        0        1   1022        0 13385796
Hello by mind8
  47 0020     32   1764   1024        0        0   1022        0 13385796
  48 0020     32   3203   1024        0        0   1023        0        0
  49 801A  32794     59   1024        0        0   1024        0        0
  50 002F     47     53   1024        0        0   1023        0        0
  51 00A5    165   2978   1024        0        0   1023        0        0
  52 00C1    193   2985   1022       10 13391638   1023       10        0
実行終り
  53 801B  32795   2986   1024        0        0   1023        0        0
  54 002F     47     55   1024        0        0   1022        0 13385798
  55 00A5    165   2965   1024        0        0   1022        0 13385798
  56 00C1    193   2976   1022       18 13391612   1022       18 13385798
実行終り時の処理
  57 0020     32   2977   1024        0        0   1022        0 13385798
  58 0012     18   2987   1024        0        0   1023        0        0
  59 004E     78   2988   1024        0        0   1023        0        0
  60 0014     20   2991   1022        0        0   1023        0        0

お題のCソースコード

上記の出力は下記のコードによるものです。オリジナルのwinprintf文によるモニタコードは除去してあります。
ヘッダはテキスト編集しています。(手抜きのためコードからは出力していません。)
今回のお題のため下記コードを見直したところ、rtp+0の出力はリターンスタックの指す値ではなく、データスタックの指す値となっていることに気づきました。これは今回訂正します。

dispatch.c

PRIVATE void                            /* 戻値:無し */
    dispatcher( void )                  /* 引数:無し */
{
                tMcode     mcode;
                int        retcode;

        retcode = setjmp( RESTARTENV );		/* ←ディスパッチャ再 */

        if ( retcode != 2 )			/* 強制脱出の検査 */
        {
		/* retcode = 0 or 1 */
                int i=0;
                for(;;)
                {
                        i++;
                        //#define  FETCH_MCODE        (*McodePointer.w++)
                        mcode = FETCH_MCODE;
                        
                        winprintf("%4d",i);
                        winprintf(" %04X",mcode);
                        winprintf(" %6d",mcode);
                        winprintf(" %6d",McodePointer.w-McodeBase);
                        winprintf(" %6d",(DstackPointer-DataStack));
                        winprintf(" %8d",(*DstackPointer));
                        winprintf(" %8d",(*(DstackPointer+1)));
                        winprintf(" %6d",(RstackPointer-RetnStack));
                        winprintf(" %8d",(*DstackPointer));
                        winprintf(" %8d\n",(*(RstackPointer+1)));
                        if ( !(mcode & 0x8000) )
                        {
                                /* C関数 */
                                C_Words_Addr[mcode]();
                        }
                        else
                        {
                                /* Mind単語 */
                                PUSH_R( McodePointer.l );//#define  PUSH_R(addr) *(--RstackPointer)=(ULONG)(addr)
                                SET_MCODE_POINTER_BY_WORDNO( mcode & 0x7fff );
                                //McodePointer.b = (UCHAR *)(WordOffsetTable[wordNo])
                        }
                }
        }
}

上記のコードの状態でも、ディスパッチャが処理するmcodeの値とmcodeポインタの値、データスタックポインタの相対値、リターンスタックポインタの相対値はC#代替版と同じように出力できています。(mcodeポインタの値はC#版はC版の2倍となっています。C#は1バイトづつのインデックス値のため)

お題のCソースコード(改定版)

Cオリジナル版の場合、データスタックやリターンスタックにアドレス値が乗る場合がありますが、C#版はスタック用配列のインデックス値であるため、値の大きさがかなり異なった出力となります。本記事ではCオリジナル版のアドレス値を操作して、C#版のスタック用配列のインデックス値と同等の値に変換して出力してみます。

Cオリジナル版の場合、スタックはアドレスの高位から消費していく
C#代替版の場合、スタック配列はインデックス0から消費していく。ただし、スタックポインタは最大値から減算されるように実装されています。

下記のコードはリターンスタックポインタにはデータスタックのアドレスが置かれることが多いという仮説の上に実装されています。

dispatch.c
              winprintf("%4d",i);
              winprintf(" %04X",mcode);
              winprintf(" %6d",mcode);
              winprintf(" %6d",(McodePointer.w-McodeBase)*2);
              winprintf(" %6d",(DstackPointer-DataStack));
              winprintf(" %8d",(*DstackPointer));
              winprintf(" %8d",(*(DstackPointer+1)));
              winprintf(" %6d",(RstackPointer-RetnStack));
            if((*RstackPointer)==0){
              winprintf(" %8d",(*RstackPointer));
            }else{
              winprintf(" %8d",(DataStack-(unsigned int *)(*RstackPointer)));
            }
            if((*RstackPointer+1)==0){
              winprintf(" %8d",(*RstackPointer+1));
            }else{
              winprintf(" %8d\n",(DataStack-(unsigned int *)(*(RstackPointer+1))));
            }
                        

お題のMind8の中間コード実行リスト(上記モニタ改定版)

上記モニタ改定版のC側検証環境で、お題のステップ数60のhellolevel1.mco中間コードファイルをディスパッチャで処理させた結果が下記です。途中までとしています。

SqNo mcode mc(dec) mpoint dtp.point  dtp+0   dtp+1 rtp.point  rtp+0  rtp+1
   1 8019  32793    114   1024        0        0   1024        0  3025768
   2 002F     47    102   1024        0        0   1023     6999  3025768
   3 0012     18   5862   1024        0        0   1023     6999  3025768
   4 0036     54   5864   1024        0        0   1023     6999  3025768
   5 0080    128   5870   1024        0        0   1023     6999  3025768
   6 0036     54   5872   1024        0        0   1023     6999  3025768
   7 0070    112   5878   1024        0        0   1023     6999  3025768
   8 803A  32826   5880   1024        0        0   1023     6999  3025768
   9 002F     47    238   1024        0        0   1022     5558     6999
  10 80B8  32952   5858   1024        0        0   1022     5558     6999
  11 0012     18   5842   1024        0        0   1021     5563     5558
  12 0036     54   5844   1024        0        0   1021     5563     5558
  13 0071    113   5850   1024        0        0   1021     5563     5558
  14 8046  32838   5852   1024        0        0   1021     5563     5558
  15 8045  32837    326   1024        0        0   1020     5565     5563
  16 0012     18    314   1024        0        0   1019     6946     5565
  17 0036     54    316   1024        0        0   1019     6946     5565
  18 0074    116    322   1024        0        0   1019     6946     5565
  19 0020     32    324   1024        0        0   1019     6946     5565
  20 0020     32    328   1024        0        0   1020     5565     5563
  21 80A3  32931   5854   1024        0        0   1021     5563     5558
  22 0036     54   3884   1024        0        0   1020     5564     5563
  23 0012     18   3890   1024        0        0   1020     5564     5563
  24 016E    366   3892   1024        0        0   1020     5564     5563
  25 0020     32   3898   1024        0        0   1020     5564     5563
  26 0020     32   5856   1024        0        0   1021     5563     5558
  27 0020     32   5860   1024        0        0   1022     5558     6999
  28 00A5    165   5882   1024        0        0   1023     6999  3025768
  29 803C  32828   5906   1022       20 12080844   1023     6999  3025768
  30 002F     47    246   1022       20 12080844   1022     5551     6999
  31 001A     26   5802   1022       20 12080844   1022     5551     6999
  32 006E    110   5804   1022       20 12080844   1020     5564     5563
  33 0015     21   5808   1024        0        0   1020  3025763     5557
  34 00ED    237   5810   1022        0        1   1020  3025763     5557
  35 0022     34   5830   1024        0        0   1020  3025763     5557
  36 00A5    165   5908   1024        0        0   1023     6999  3025768
  37 00C1    193   5926   1022       14 12080870   1023     6999  3025768
$$COLD_FORTH
  38 0020     32   5928   1024        0        0   1023     6999  3025768
  39 80C3  32963    116   1024        0        0   1024        0  3025768

お題のMind8の中間コード実行リスト(C#代替版)

下記はC#代替版でお題のステップ数60のhellolevel1.mco中間コードファイルを処理させた結果です。ほぼ正常の途中までとしています。
39ステップ目がオリジナルとmcodeの値が異なってしまっていますが、それ以外では各ステップのmcodeの値、mcodeポインタの値、データスタックポインタの値、データスタックポインタの指す値、リターンスタックポインタの値は合致していることがわかります。
いまのところ合致が確認できないのは、データスタックポインタのオフセット1の指す値と、リターンスタックポインタのオフセット0,1の指す値ということになります。

SqNo mcode mc(dec) mpoint dtp.point  dtp+0   dtp+1 rtp.point  rtp+0  rtp+1
   1 8019  32793    114   1024        0        0   1024        0        0
   2 002F     47    102   1024        0        0   1023      114        0
   3 0012     18   5862   1024        0        0   1023      114        0
   4 0036     54   5864   1024        0        0   1023      114        0
   5 0080    128   5870   1024        0        0   1023      114        0
   6 0036     54   5872   1024        0        0   1023      114        0
   7 0070    112   5878   1024        0        0   1023      114        0
   8 803A  32826   5880   1024        0        0   1023      114        0
   9 002F     47    238   1024        0        0   1022     5880        0
  10 80B8  32952   5858   1024        0        0   1022     5880        0
  11 0012     18   5842   1024        0        0   1021     5858        0
  12 0036     54   5844   1024        0        0   1021     5858        0
  13 0071    113   5850   1024        0        0   1021     5858        0
  14 8046  32838   5852   1024        0        0   1021     5858        0
  15 8045  32837    326   1024        0        0   1020     5852        0
  16 0012     18    314   1024        0        0   1019      326        0
  17 0036     54    316   1024        0        0   1019      326        0
  18 0074    116    322   1024        0        0   1019      326        0
  19 0020     32    324   1024        0        0   1019      326        0
  20 0020     32    328   1024        0        0   1020     5852      326
  21 80A3  32931   5854   1024        0        0   1021     5858     5852
  22 0036     54   3884   1024        0        0   1020     5854      326
  23 0012     18   3890   1024        0        0   1020     5854      326
  24 016E    366   3892   1024        0        0   1020     5854      326
  25 0020     32   3898   1024        0        0   1020     5854      326
  26 0020     32   5856   1024        0        0   1021     5858     5854
  27 0020     32   5860   1024        0        0   1022     5880     5858
  28 00A5    165   5882   1024        0        0   1023      114     5880
  29 803C  32828   5906   1022       20        0   1023      114     5880
  30 002F     47    246   1022       20        0   1022     5906     5858
  31 001A     26   5802   1022       20        0   1022     5906     5858
  32 006E    110   5804   1022       20        0   1020        0      114
  33 0015     21   5808   1024        0     5884   1020       20     5884
  34 00ED    237   5810   1022        0        0   1020       20     5884
  35 0022     34   5830   1024        0        1   1020       20     5884
  36 00A5    165   5908   1024        0        1   1023     5858     5854
  37 00C1    193   5926   1022       14        0   1023     5858     5854
$$COLD_FORTH
  38 0020     32   5928   1024        0     5910   1023     5858     5854
  39 0020     32   5860   1024        0     5910   1024     5906     5858

つづく

生成されたhello.mcoを解釈して、C#側で「Hello by mind8」が出力されるようにするまでの長い道のりですが、いそがば回れということでオリジナルのCディスパッチャの挙動をもう少しうまくモニタできるようにしてみます。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1