はじめに
こちらの記事にてMind開発者の@killyさんより情報共有いただいたMind8の検証用Consoleをベースに一部正規のConsoleのコードを取り込んだ中間コードhellolevel0.mco(Mind中間コードステップ数51)を完走させましたが、ステップ数60のhellolevel1.mcoはまだ完走できずにいました。その後急がば回れということもあって、Cオリジナル版のリターンスタックの出力値(C版はOSが採番した論理アドレス値が格納される場合があり、C#版はbyte配列のインデックス値のため直接比較できなかったの)を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の動作をデバッグ実行で探るために使用します。こちらの記事の環境となります。
カスタマイズConsoleのビルド
killyさんよりご提供いただいた情報に従い、下記のようにカスタマイズConsoleのビルド用のフォルダfilelevel群を作成しています。
ビルド用フォルダ構成
現状は下記のようなフォルダ構成となります。filedummyフォルダは起動検証用Consoleのビルド環境です。fileフォルダは正規のソースファイルが格納されたフォルダです。filelevel2フォルダは従来のfilelevel0フォルダです。
filedummyの内容はこちらの記事を、filelevel1,2(旧0)の内容はこちらの記事を参照してください。今回のお題はfilelevel1内のconslevel1.src上でビルドされたサンプルです。
C:\developments\vscode\mind8>tree
C:.
├─bin
├─file
│ └─obj
├─filedummy
│ └─obj
├─filelevel0
│ └─obj
├─filelevel1
│ └─obj
├─filelevel2
│ └─obj
├─kernel
│ └─.vscode
├─lib
├─libY
└─sample
お題のMindソースコード
こちらの記事を参照してください。
$$COLD_FORTHの内容を「各ライブラリ初期化」まで正規版Consoleと同じとして、さらに「各ライブラリ初期化」の中身も「コンソール初期化・基本部」までとし、そしてさらに「コンソール初期化・基本部」の中身も「空白文字列初期化し」までとして、正規版の実装から各所後半を大幅にカットしています。
お題のMind8のソースファイル
メインとは
「Hello by mind8」を 表示すること。
アプリケーションとしてのユーザーコードは上記だけですが、Mind8ランタイムの初期化コードがいろいろな提示済単語をチェック処理していて、現在フルスペックのチェックコードを通過できないため、前記のような初期処理のショートカット版のバージョンを段階的に作成して完走を試みているというのが現状です。
お題のC#ソースコード
前回記事でリターンスタック値に差異がではじまたのは、ステップ31の001Aが処理された後であることが判明しました。001Aのコードは下記のような実装となっており、001A自体というよりはスタックポインタライブラリのMoveStackPointerに問題がありそうでした。
namespace Mind8Kernel
{
public partial class Dispatcher
{
private void ZzReserve2L(){ /* ;DUMMYWORD */
/* Mコード=0x001A */
//RstackPointer -= 2;
rtp.MoveStackPointer(-2);
}
ちょっと紛らわしい話ですが、MindのリターンスタックはCメモリ確保されたアドレスの最後尾から先頭に向かってプッシュしていきますが、C#代替実装ではbyte配列のインデックス0からプッシュしていきますので、そのあたりMind互換にするためインデックス値とは別にポインタ値を設定してそちらは最大値から減らしていくようにしておりましたので、下記のスタックポインタ値を相対移動する関数の実装で、byte配列インデックス値の増減をポインタ値とは逆むきにしておくことが漏れていました。
namespace Mind8Kernel
{
/// <summary>スタックポインタ</summary>
public class StackPointer{
//~略~
public void MoveStackPointer(int point){
stackPointer=(uint)(stackPointer+point);
- stackIndex=(uint)(stackIndex + point*stackSize);
+ stackIndex=(uint)(stackIndex - point*stackSize);//byte配列インデックス=アドレスポインタ変数の値*4
}
お題のMind8の中間コードのC#代替ディスパッチャ実行リスト
C#側検証環境で、お題の中間コードファイルを上記箇所を訂正した状態でビルドしたC#代替ディスパッチャで処理させます。
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 114
10 80B8 32952 5858 1024 0 0 1022 5880 114
11 0012 18 5842 1024 0 0 1021 5858 5880
12 0036 54 5844 1024 0 0 1021 5858 5880
13 0071 113 5850 1024 0 0 1021 5858 5880
14 8046 32838 5852 1024 0 0 1021 5858 5880
15 8045 32837 326 1024 0 0 1020 5852 5858
16 0012 18 314 1024 0 0 1019 326 5852
17 0036 54 316 1024 0 0 1019 326 5852
18 0074 116 322 1024 0 0 1019 326 5852
19 0020 32 324 1024 0 0 1019 326 5852
20 0020 32 328 1024 0 0 1020 5852 5858
21 80A3 32931 5854 1024 0 0 1021 5858 5880
22 0036 54 3884 1024 0 0 1020 5854 5858
23 0012 18 3890 1024 0 0 1020 5854 5858
24 016E 366 3892 1024 0 0 1020 5854 5858
25 0020 32 3898 1024 0 0 1020 5854 5858
26 0020 32 5856 1024 0 0 1021 5858 5880
27 0020 32 5860 1024 0 0 1022 5880 114
28 00A5 165 5882 1024 0 0 1023 114 0
29 803C 32828 5906 1022 20 5884 1023 114 0
30 002F 47 246 1022 20 5884 1022 5906 114
31 001A 26 5802 1022 20 5884 1022 5906 114
32 006E 110 5804 1022 20 5884 1020 5854 5858
33 0015 21 5808 1024 0 0 1020 20 5858
34 00ED 237 5810 1022 0 1 1020 20 5858
35 0022 34 5830 1024 0 0 1020 20 5858
36 00A5 165 5908 1024 0 0 1023 114 0
37 00C1 193 5926 1022 14 5910 1023 114 0
$$COLD_FORTH
38 0020 32 5928 1024 0 0 1023 114 0
39 80C3 32963 116 1024 0 0 1024 0 0
40 00A5 165 6386 1024 0 0 1023 116 0
41 8083 32899 6404 1022 14 6388 1023 116 0
42 0012 18 3510 1022 14 6388 1022 6404 116
43 004E 78 3512 1022 14 6388 1022 6404 116
44 00EC 236 3518 1020 0 0 1022 6404 116
45 0096 150 3524 1022 14 6388 1022 6404 116
46 026D 621 3526 1020 0 1 1022 6404 116
Hello by mind8
47 0020 32 3528 1024 0 0 1022 6404 116
48 0020 32 6406 1024 0 0 1023 116 0
49 801A 32794 118 1024 0 0 1024 0 0
50 002F 47 106 1024 0 0 1023 118 0
51 00A5 165 5956 1024 0 0 1023 118 0
52 00C1 193 5970 1022 10 5958 1023 118 0
実行終り
53 801B 32795 5972 1024 0 0 1023 118 0
54 002F 47 110 1024 0 0 1022 5972 118
55 00A5 165 5930 1024 0 0 1022 5972 118
56 00C1 193 5952 1022 18 5932 1022 5972 118
実行終り時の処理
57 0020 32 5954 1024 0 0 1022 5972 118
58 0012 18 5974 1024 0 0 1023 118 0
59 004E 78 5976 1024 0 0 1023 118 0
60 0014 20 5982 1022 0 0 1023 118 0
例外がスローされました: 'Mind8Kernel.Dispatcher.ExitModule' (mind8dispatch.dll の中)
プログラム '[1328] mind8dispatch.dll' がコード 0 (0x0) で終了しました。
最後が例外スローされていますが、これはmcode=0014の「プロセス終り0」で意図的にスローさせたアプリケーション例外です。
終了動作としては意図したものですので、今回ようやくlevel1が無事に完走したようでした!
つづく
生成されたhello.mcoを解釈して、C#側で「Hello by mind8」が出力されるようにするまでの長い道のりですが(初期処理をショートカットすればこの処理自体は処理できていますが、初期処理をどの程度対応するかで道のりの長さは大きく変動しまして、カメの動きとなっております。)、次のレベルの完走を引き続き行ってまいります。