なでしこさんでなんちゃってアセンブラ
今週も日曜日がやってきた。
いい加減にアレを書きたいところだが、今週は確定申告の期限が迫っており、それにリソースを振っていったからか、残念ながら今週もアレを書くための作業ができず。
来週こそアレを書かないと、再来週にはソレが来るぞ……
というわけで、今日も元気に雑プログラムで繋いでいこう!
今回やったこと
なでしこで、「なんちゃってアセンブラ」を作った。
これは、x86のNOP命令にのみ対応したアセンブラである。
「nop」と (だけ) 書かれた行 (大文字と小文字は区別しない) 1個につき、1個の「90」を出力する。
行の中で、「:」とそれより前の部分はラベル、「;」とそれより後の部分はコメントであり、これらは無視される。
また、ラベルとコメントを取り除いた後の行頭および行末の空白も無視される。
プログラム
なんちゃってアセンブラ (プログラム貯蔵庫)
ポイント
UIの用意
「ソース:」のラベル作成。
改行作成。
ソース欄は空のテキストエリア作成。
それの「rows」に10をDOM属性設定。
それの「cols」に50をDOM属性設定。
それの「width」に「unset」をDOMスタイル設定。
それの「height」に「unset」をDOMスタイル設定。
改行作成。
アセンブルボタンは「アセンブル」のボタン作成。
2回、改行作成。
「結果:」のラベル作成。
改行作成。
結果欄は空のテキストエリア作成。
それの「rows」に5をDOM属性設定。
それの「cols」に50をDOM属性設定。
それの「width」に「unset」をDOMスタイル設定。
それの「height」に「unset」をDOMスタイル設定。
それの「readOnly」にオンをDOM属性設定。
改行作成。
「メッセージ:」のラベル作成。
改行作成。
メッセージ欄は空のテキストエリア作成。
それの「rows」に5をDOM属性設定。
それの「cols」に50をDOM属性設定。
それの「width」に「unset」をDOMスタイル設定。
それの「height」に「unset」をDOMスタイル設定。
それの「readOnly」にオンをDOM属性設定。ソースコードの入力欄
アセンブルを実行するためのボタン
アセンブル結果の出力欄
アセンブル時に検出したエラーの出力欄
をそれぞれ用意する。
執筆時点のなでしこでは、残念ながら「DOM属性設定」で readonly 属性を設定しようとしてもうまくいかないようなので、かわりに O を大文字にした readOnly プロパティを設定している。
さらに、Web簡易エディタでの実行では問題なかったが、プログラム貯蔵庫で実行するとtextareaに対し大きさを指定するスタイルシートが設定されていたため、これを打ち消すスタイル設定を行った。
アセンブルの実行
アセンブルボタンをクリックした時のイベントハンドラで、以下の処理を行う。
ソース欄のテキスト取得。
それの「{CR}{LF}」をLFに置換。
それのCRをLFに置換。
それをLFで区切る。
定数のソース配列はそれ。ソース欄からソースコードを取得し、改行文字を正規化して1行ごとに分割する。
定数のアセンブル結果は空配列。
変数のメッセージは空。アセンブル結果とメッセージを格納する変数を用意する。
行番号で1から(ソース配列の要素数)まで繰り返す
定数のソース行はソース配列@(行番号-1)。
ソース行の「/;.*$/」を空に正規表現置換。
それの「/^.*:/」を空に正規表現置換。
それをトリムして小文字変換。
定数の命令はそれ。
もし、命令が「nop」と等しいならば
アセンブル結果に0x90を配列追加。
違えば、もし、命令が空でなければ
メッセージはメッセージと「{行番号}行目でエラー:未知の命令{カッコ}{命令}{カッコ閉}があります。{改行}」を連結。
ここまで。
ここまで。各行について、ラベルとコメントを削除し、さらに「トリム」で行頭と行末の改行を削除したあと、残った部分が「nop」かを判定する。
「nop」であれば、NOPに対応する機械語である0x90をアセンブル結果に追加する。
「nop」以外の何かが書かれていれば、エラーメッセージを出力する。
変数のアセンブル結果テキストは空。
添字で1から(アセンブル結果の要素数)まで繰り返す
アセンブル結果@(添字-1)を16進数変換して2でゼロ埋め。
アセンブル結果テキストはアセンブル結果テキストとそれを連結。
もし、添字を16で割った余りが0と等しいならば
アセンブル結果テキストはアセンブル結果テキストと改行を連結。
違えば
アセンブル結果テキストはアセンブル結果テキストと「 」を連結。
ここまで。
ここまで。
アセンブル結果テキストはアセンブル結果テキストをトリム。
もし、アセンブル結果の要素数が0超ならば
アセンブル結果テキストはアセンブル結果テキストと改行を連結。
ここまで。数値で配列に格納したアセンブル結果を文字列に変換する。
アセンブル結果はバイトごとに格納されているので、2桁の16進数に変換し、文字列化する。
16バイトごとに改行を入れて出力する。
結果欄にアセンブル結果テキストをテキスト設定。
メッセージ欄にメッセージをテキスト設定。文字列に変換したアセンブル結果と、エラーメッセージをUIに出力する。
おわりに
なでしこさんで、x86のNOP命令のみに対応したアセンブラを作ることができた。
今回のプログラムは、本格的なアセンブラに発展させるにあたって
命令とオペランドを分離していない
ラベルの情報を記録せず、単に捨てている
ラベルやコメントの判定に文字列を考慮していない
などの問題点がある。
これらの問題を (必要に応じて) 解消し、本格的なアセンブラに発展させるのは、読者への宿題としたい。


コメント