【お知らせ】プログラミング記事の投稿はQiitaに移行しました。

ファイルシステムの読み込み


id:oraccha:20101101の手順を参考に、UNIX V6をSIMHで動かしてみました。分析のためファイルを取り出そうとしたのですが、TCP/IP以前のOSのためネットワークが使えるのか不明で、ディスクイメージからファイルを取り出す方法も分かりません。仕方ないのでカーネルのソースを読みながらファイルを取り出してみました。

読み込みツールはF#で実装しました。ブラウザ上から実行できるようにSilverlight化しました。id:n7shi:20101004で作成したZIP圧縮コードにより、ファイルシステム全体をZIPファイルとして保存することができます。

【追記:2015.11.12】ローカルで動かすGUI版もあります。(Silverlight非依存)

以下、UNIX V6のC言語ソースを引用しながら簡単に説明します。ソースコードはタブで整形されていますが、レイアウトが崩れるのを防ぐためスペースに置換して引用しました。タブは8文字を想定しているようです。

続きを読む

高速化

id:n7shi:20100727でAlpha逆アセンブラインタプリタ上で動かしましたが、あまりにも遅かったです。使用しているすべてのlibc関数をfopen()等と同じようにF#でインタプリタ側に実装して、ループの無駄等を見直しました。その結果、約10倍ほど高速化しました。

ある種のチートですが、インタプリタ言語ではよくある構造だと思います。Alphaコードの実行はインタプリタのままでJITは行っていません。JITがなくてもこのくらいの速度が確保できれば、簡易Cコンパイラホスティングも視野に入りそうです。

逆アセンブラのホスティング

C言語でAlphaの逆アセンブラ(以下7d)を開発して、id:n7shi:20100712でSilverlight化したAlphaインタプリタ上で動かしてみました。デフォルトでDisassembleのタブに出てくるアセンブリが7dの出力です。横のコンボボックスで従来の組み込み逆アセンブラと切り替えられるようになっています。

ファイルの読み書きはlibcをインタプリタ側でシミュレートしています。C言語からはアドレス決め打ちで呼び出して、インタプリタ側でフックして処理を返しています。

void (*exit)(int) = (void *)0x00ef0000;
int (*fputc)(int, FILE *) = (void *)0x00ef0004;
int (*fgetc)(FILE *) = (void *)0x00ef0008;
FILE *(*fopen)(const char *, const char *) = (void *)0x00ef000c;
int (*fclose)(FILE *) = (void *)0x00ef0010;
int (*fwrite)(const void *, int, int, FILE *) = (void *)0x00ef0014;
int (*fread)(void *, int, int, FILE *) = (void *)0x00ef0018;
int (*fseek)(FILE *, long, int) = (void *)0x00ef001c;

逆アセンブラ・インタプリタ

id:n7shi:20100710の方法でVWD2010EEでもF#が使えるようになったので、id:n7shi:20100709でF#に移植したAlpha逆アセンブラインタプリタSilverlight化しました。

動作はC#版とまったく同じです。XAMLのコードビハインドはC#にして、C#からF#を呼び出しています。F#部分はGUIに依存していないためWindows Forms版と共通のコードです。VWDではF#のインテリセンスが効かないので、インテリセンスの効くVS2008Shellの方で開発を進めるという作戦です。そのためソリューションにはSilverlightとWinFormsのプロジェクトが同居して、F#のプロジェクトを共有しています。

列挙型配列の初期化エラー

【追記1】いげ太さんより、XP SP3 + Visual Studio 2010 Proの環境でも同様の問題が発生するとのご報告がありました。

【追記2】いげ太さんより、Don Syme氏直々のご回答をご報告いただきました。

昨日(id:n7shi:20100710)のテストで、Module1.fsを以下の内容にすると初期化エラーが発生します。

module Module1

type E = | A = 0
let a = [| E.A; E.A; E.A; E.A; E.A; E.A |]
let hello = sprintf "%A" a

配列の要素を1つ少なくしたり、列挙型ではなく整数型にしたり、配列ではなくリストにしたりすれば落ちません。List.toArrayで変換すれば配列が得られます。リリースビルドで生成されたHTMLファイルを手動で開くと正常動作することから、デバッガのアタッチ周りで何か問題があるのかもしれません。無理やりビルドしているのが原因の可能性もありますが・・・。

VWD2010でF#

SilverlightでF#を使用する場合、Visual Studio 2010 ProfessionalではC# SilverlightアプリケーションとF# Silverlightクラスライブラリを組み合わせる方法が推奨されているようです。

フリーのVisual Web Developer 2010 Express Edition(以下VWD)で試行錯誤した結果、小細工でF#がビルドできることが分かりました。

  1. C# Silverlightアプリケーションのソリューションを作成します。
  2. C# Silverlightクラスライブラリのプロジェクトを追加します。
  3. クラスライブラリプロジェクトを書き換えてF#用にします。
  4. アプリケーションからクラスライブラリを参照します。

3と4の詳細は以下の通りです。

続きを読む

逆アセンブラ・インタプリタ

Alphaの命令について調査するため、Silverlightで逆アセンブラインタプリタを作成しました。以下でホスティングしています。ページ上部の[Test1]などのボタンを押すとサンプルを読み込んで実行します。

また、これを作りながらAlphaの命令表をまとめました。

gxemulのtestマシンを参考にしました。testalphaはまだ動かないようですが、OSや実機がなくても命令の調査ができることを教えてもらえました。ちなみにid:n7shi:20091216で取り上げたid:syuu1228さんの独自OS Shiitakeはtestmipsをターゲットとしています。