6502逆アセンブラに関する考察 その1

tl;dr: taotao54321/td6502

懲りずに6502逆アセンブラについて考えてみます。まあ素直に IDA を買えという話なのかもしれませんが、結構お高いですし、プロプライエタリでない選択肢があってもいいと思うので…。なお、私はNES以外のプラットフォームには詳しくないのでNESの話が多くなると思います。

何が問題か

要はなるべくコードとデータを自動で判別したいということですね。例えば以下のような出力はしてほしくないわけです:

; NES用プログラム(マッパー0とする)

lda $00         ; 不満: 直後がデータなんだから、ここもデータのはず
db $02          ; 非公式命令 (KIL) なのでデータとして出力
jmp ($5555)     ; 不満: $5555 には何も割り当てられてないんだから、普通はデータのはず

それで以前適当な自動判別機能が付いた逆アセンブラ作ってみたのですが、これは対象によってうまく行ったり行かなかったりで微妙だったので、この際きちんと考え直して文書として残しておこうと思ったわけです(大して高度なことではないですが)。

アセンブラの機能としては他にもアドレスラベルの処理やコメント付加、出力整形など色々な話題がありますが、ここではコード判定のみに絞って書くことにします。

前提

アセンブラを解析と出力の2フェーズに分けて考えます。

解析フェーズではアドレス空間 ($0000-$FFFF) 内の各アドレスについてコード判定を行い、判定結果として以下の3通りの値のうちいずれかを与えます:

  • CODE (コード。厳密にはオペコード)
  • NOTCODE (非コード。厳密には非オペコード)
  • UNKNOWN (不明)

初期状態では全アドレスが UNKNOWN です。ここから解析フェーズでなるべく多くのアドレスを非 UNKNOWN 状態にして(ただし誤判定は極力避ける)、出力フェーズではその結果を利用して出力を行います。

なお、難しくなりすぎるのでバンク切り替えの追跡までは行わないことにします。

次回から解析フェーズを考えていきます。