はじめに
前回の記事にて、過日Mind開発者の@killyさんより情報共有いただいたMind8の検証用Consoleをベースにしたhellolevel1.mcoの中間コードのCオリジナルディスパッチャの処理結果をC#互換値に変換することに成功しましたが、その後の精査でリターンスタック値の相対+1の値の出力が間違っていたことが判明しました。
前回ではリターンスタック値の相対+1の値のコンバート自体は行っておりませんでしたが、今回は正しい出力値でかつ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の動作をデバッグ実行で探るために使用します。こちらの記事の環境となります。
お題のCソースコード
前回の記事では素直な出力にいったん戻していましたが、リターンスタックポインタの相対+1の値の出力に誤りがありましたので訂正します。
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));
+ 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])
}
}
}
}
記事に掲示していたコードは間違っていなかったのですが、実際に動かしていたコードが上記訂正前の状態でした。
お題の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 0
2 002F 47 102 1024 0 0 1023 12533850 0
3 0012 18 5862 1024 0 0 1023 12533850 0
4 0036 54 5864 1024 0 0 1023 12533850 0
5 0080 128 5870 1024 0 0 1023 12533850 0
6 0036 54 5872 1024 0 0 1023 12533850 0
7 0070 112 5878 1024 0 0 1023 12533850 0
8 803A 32826 5880 1024 0 0 1023 12533850 0
9 002F 47 238 1024 0 0 1022 12539616 12533850
10 80B8 32952 5858 1024 0 0 1022 12539616 12533850
11 0012 18 5842 1024 0 0 1021 12539594 12539616
12 0036 54 5844 1024 0 0 1021 12539594 12539616
13 0071 113 5850 1024 0 0 1021 12539594 12539616
14 8046 32838 5852 1024 0 0 1021 12539594 12539616
15 8045 32837 326 1024 0 0 1020 12539588 12539594
16 0012 18 314 1024 0 0 1019 12534062 12539588
17 0036 54 316 1024 0 0 1019 12534062 12539588
18 0074 116 322 1024 0 0 1019 12534062 12539588
19 0020 32 324 1024 0 0 1019 12534062 12539588
20 0020 32 328 1024 0 0 1020 12539588 12539594
21 80A3 32931 5854 1024 0 0 1021 12539594 12539616
22 0036 54 3884 1024 0 0 1020 12539590 12539594
23 0012 18 3890 1024 0 0 1020 12539590 12539594
24 016E 366 3892 1024 0 0 1020 12539590 12539594
25 0020 32 3898 1024 0 0 1020 12539590 12539594
26 0020 32 5856 1024 0 0 1021 12539594 12539616
27 0020 32 5860 1024 0 0 1022 12539616 12533850
28 00A5 165 5882 1024 0 0 1023 12533850 0
29 803C 32828 5906 1022 20 12539620 1023 12533850 0
30 002F 47 246 1022 20 12539620 1022 12539642 12533850
31 001A 26 5802 1022 20 12539620 1022 12539642 12533850
32 006E 110 5804 1022 20 12539620 1020 12539590 12539594
33 0015 21 5808 1024 0 0 1020 20 12539620
34 00ED 237 5810 1022 0 1 1020 20 12539620
35 0022 34 5830 1024 0 0 1020 20 12539620
36 00A5 165 5908 1024 0 0 1023 12533850 0
37 00C1 193 5926 1022 14 12539646 1023 12533850 0
$$COLD_FORTH
38 0020 32 5928 1024 0 0 1023 12533850 0
39 80C3 32963 116 1024 0 0 1024 0 0
40 00A5 165 6386 1024 0 0 1023 12533852 0
41 8083 32899 6404 1022 14 12540124 1023 12533852 0
42 0012 18 3510 1022 14 12540124 1022 12540140 12533852
43 004E 78 3512 1022 14 12540124 1022 12540140 12533852
44 00EC 236 3518 1020 0 0 1022 12540140 12533852
45 0096 150 3524 1022 14 12540124 1022 12540140 12533852
46 026D 621 3526 1020 0 1 1022 12540140 12533852
Hello by mind8
47 0020 32 3528 1024 0 0 1022 12540140 12533852
48 0020 32 6406 1024 0 0 1023 12533852 0
49 801A 32794 118 1024 0 0 1024 0 0
50 002F 47 106 1024 0 0 1023 12533854 0
51 00A5 165 5956 1024 0 0 1023 12533854 0
52 00C1 193 5970 1022 10 12539694 1023 12533854 0
実行終り
53 801B 32795 5972 1024 0 0 1023 12533854 0
54 002F 47 110 1024 0 0 1022 12539708 12533854
55 00A5 165 5930 1024 0 0 1022 12539708 12533854
56 00C1 193 5952 1022 18 12539668 1022 12539708 12533854
実行終り時の処理
57 0020 32 5954 1024 0 0 1022 12539708 12533854
58 0012 18 5974 1024 0 0 1023 12533854 0
59 004E 78 5976 1024 0 0 1023 12533854 0
60 0014 20 5982 1022 0 0 1023 12533854 0
お題のMind8の中間コード実行リストのリターンスタック値をC#代替互換にEXCELで加工する
OSがアロケートするメモリ論理アドレスは実行毎に異なります。一方、C#代替実装ではメモリ論理アドレスの代わりにbyte配列のインデックス値がアドレス相当としていますので、その値は実行毎に同一です。この両者は直接比較できないので、どこでどうくるったのかがそのままでは特定しずらい状況でした。
そこで前回記事ではリターンスタックの値rtp+0をEXCEL上で下記のように加工しました。
9ステップのリターンスタックの値がC#版のリターンスタックの値5880(バイト配列のインデックス値)と等価の論理アドレス値と仮定してオフセット値を算出します。この値をアドレスっぽい値のリターンスタック値から減算します。
今回は正しく出力されるようになったリターンスタックの相対+1の値のコンバートも行ってみます。
今回の論理アドレス値では下記のオフセット値となります。
12539616ー5880=12533736
このオフセット値をrtp+0とrtp+1のアドレスっぽい値から減算してC#互換値にコンバートします。
コンバート結果をC#代替のリターンスタック値(インデックス値)と並べた結果が下記です。
SqNo mcode rtp.point rtp+0 rtp+0(補正) rtp+0(C#) rtp+1 rtp+1(補正) rtp+1(C#)
1 8019 1024 0 0 0 0 0 0
2 002F 1023 12533850 114 114 0 0 0
3 0012 1023 12533850 114 114 0 0 0
4 0036 1023 12533850 114 114 0 0 0
5 0080 1023 12533850 114 114 0 0 0
6 0036 1023 12533850 114 114 0 0 0
7 0070 1023 12533850 114 114 0 0 0
8 803A 1023 12533850 114 114 0 0 0
9 002F 1022 12539616 5880 5880 12533850 114 0
10 80B8 1022 12539616 5880 5880 12533850 114 0
11 0012 1021 12539594 5858 5858 12539616 5880 0
12 0036 1021 12539594 5858 5858 12539616 5880 0
13 0071 1021 12539594 5858 5858 12539616 5880 0
14 8046 1021 12539594 5858 5858 12539616 5880 0
15 8045 1020 12539588 5852 5852 12539594 5858 0
16 0012 1019 12534062 326 326 12539588 5852 0
17 0036 1019 12534062 326 326 12539588 5852 0
18 0074 1019 12534062 326 326 12539588 5852 0
19 0020 1019 12534062 326 326 12539588 5852 0
20 0020 1020 12539588 5852 5852 12539594 5858 326
21 80A3 1021 12539594 5858 5858 12539616 5880 5852
22 0036 1020 12539590 5854 5854 12539594 5858 326
23 0012 1020 12539590 5854 5854 12539594 5858 326
24 016E 1020 12539590 5854 5854 12539594 5858 326
25 0020 1020 12539590 5854 5854 12539594 5858 326
26 0020 1021 12539594 5858 5858 12539616 5880 5854
27 0020 1022 12539616 5880 5880 12533850 114 5858
28 00A5 1023 12533850 114 114 0 0 5880
29 803C 1023 12533850 114 114 0 0 5880
30 002F 1022 12539642 5906 5906 12533850 114 5858
31 001A 1022 12539642 5906 5906 12533850 114 5858
32 006E 1020 12539590 5854 0 12539594 5858 114
33 0015 1020 20 12539620 5884 5884
34 00ED 1020 20 12539620 5884 5884
35 0022 1020 20 12539620 5884 5884
36 00A5 1023 12533850 114 5858 0 0 5854
37 00C1 1023 12533850 114 5858 0 0 5854
$$COLD_FORTH
38 0020 1023 12533850 114 5858 0 0 5854
39 80C3 1024 0 5906 0 0 5858
40 00A5 1023 12533852 116 0
41 8083 1023 12533852 116 0
42 0012 1022 12540140 6404 12533852 116
43 004E 1022 12540140 6404 12533852 116
44 00EC 1022 12540140 6404 12533852 116
45 0096 1022 12540140 6404 12533852 116
46 026D 1022 12540140 6404 12533852 116
Hello by mind8
47 0020 1022 12540140 6404 12533852 116
48 0020 1023 12533852 116 0 0
49 801A 1024 0 0 0
50 002F 1023 12533854 118 0 0
51 00A5 1023 12533854 118 0 0
52 00C1 1023 12533854 118 0 0
実行終り
53 801B 1023 12533854 118 0 0
54 002F 1022 12539708 5972 12533854 118
55 00A5 1022 12539708 5972 12533854 118
56 00C1 1022 12539708 5972 12533854 118
実行終り時の処理
57 0020 1022 12539708 5972 12533854 118
58 0012 1023 12533854 118 0 0
59 004E 1023 12533854 118 0 0
60 0014 1023 12533854 118 0 0
mcodeの値が出力された時点ではそのコードはまだ実行されておらず、これから実行しますよという状態ですので、同時に出力されているスタック値の状態は、そのmcodeが処理される直前の状態を意味します。
rtp+1の値もC#互換にコンバートしてみますと、前回想定していた位置よりだいぶ手前から値がずれていることが判明しました。
つづく
生成されたhello.mcoを解釈して、C#側で「Hello by mind8」が出力されるようにするまでの長い道のりですが(初期処理をショートカットすればこの処理自体は処理できていますが、初期処理をどの程度対応するかで道のりの長さは大きく変動しまして、カメの動きとなっております。)、問題個所の特定を引き続き行ってまいります。