さて、前回の記事ではgiko005の解釈をした。これでgiko005.asmにアセンブリ言語でかかれたプログラム自体がどういうものかはわかったつもりだけど、アセンブラでアセンブルして出来上がった.nesファイルはまだブラックボックスでよくわからない。だから、この.nesファイルの中身を解析してみようと思う。
前回の記事でも使ったけど、バイナリエディタstirlingを使用する。このバイナリエディタで、nesasmでgiko.asmをアセンブルしてできたgiko.nesを開くといろいろ書いてある。
stirlingの見方は割愛。簡単に言うと左の灰色の部分がアドレスの2桁目以降、上の黄色の部分がアドレスの1桁目を表す。
.nesファイルの中身がどうなっているかは、http://borokobo.web.fc2.com/neo/prghabc/3.html のサイトが超分かりやすい。
さて、1行目の16Byteはヘッダー。ここに.nesファイルの情報が書かれるみたい。
まず、$0000~$0003にかいてる、「4E 45 53 1A」っていうのは、.nesファイル共通の値みたい。この4Byteの値が「このファイルは.nesファイルですよ」ということを表しているらしい。エミュレーターが.nesファイルを開くとき、まず最初の4Byteがちゃんとこの値になっているかを確かめるみたい。右側にNESって書いてあるのが面白い(笑)
で、$0004はプログラムROMのサイズ。(PRG-ROMのサイズ) = 16(KB) * x と考えたとき、xがいくつあるかってことを表す。giko.asmではアセンブリ言語で.inesprg 1と書いたけど、要するにここのパラメータを書いてたってわけだ。bankの数だね。例えば、giko005はPRG-ROMが16KBだから01なんだね。じゃあ以前の記事(http://1936noiv.blog.fc2.com/blog-entry-3.html)の復習だけど、①いっき ②マリオ ③FF1 ④ヨッシーのたまご の.nesふぁいるだとそれぞれどんな値になるかわかる? 答えは、①のいっきはPRG-ROMが16kBだから01。②のマリオはPRG-ROMが32kBだから02。③のFF1はPRG-ROMが256kBだから10。④のヨッシーのたまごはPRG-ROMが128kBだから08。
・・・こんな問題データ見ないで解けたら変態だよ(´・ω・)
つぎに、$0005はCHR-ROMのサイズ。これも(CHR-ROMのサイズ) = 8(KB) * x と考えたとき、xがいくつあるかってことを表す。giko.asmではアセンブリ言語で.ineschr 1と書いたけど、要するにここのパラメータを書いてたってわけだ。じゃあ、さっきと同じことだけど、①いっき ②マリオ ③FF1 ④ヨッシーのたまご の.nesふぁいるだと$0005はそれぞれどんな値になるかわかる? 答えは、①のいっきはCHR-ROMが8kBだから01。②のマリオもCHR-ROMが8kBだから01。③のFF1はCHR-ROMが0kBだから00。④のヨッシーのたまごはCHR-ROMが32kBだから04。
さて、これでヘッダーの$0005までは分かったと思う。とりあえずgiko005を読むにはこれでOK。$0006~$000Fまではhttps://wiki.nesdev.com/w/index.php/INESここに全部書いてあるから、気になる人は、読もう!!(丸投げ)
じゃあ、ヘッダー以降つまり2行目以降($0010~)には何が書いてあるのか。これは、PRG-ROM → CHR-ROMの順にその中身が書いてあるみたい。それぞれの容量はさっき$0004と$0005で分かったよね。giko005.nesの場合、PRG-ROMは16KB(16進数で言うと4000)で、CHR-ROMは8KB(16進数で言うと2000)だった。
つまり、$0010 ~$400FにPRG-ROMが書いてあって、$4010 ~$600FにCHR-ROMの内容が書いてあるはず。
↓実際に確かめてみた。
おお、やっぱりそうなってる!!(感動)
あと忘れてたけど前回の記事でも説明したことで、プログラム上でbank1 としてPRG-ROMの最後の6Byteで割り込みハンドラの設定してたね。CPUのメモリ空間で言う$FFFA~$FFFFのアドレス。ちゃんとgiko005.nesの$400A~$400Fに反映されてる!
そして、giko005.nesファイルの最後のアドレスはちゃんと$600Fであると。
さて、それではPRG-ROMの内容から見てみようか。giko005.asmでPRG-ROMに最初に書いた命令を覚えてる?
Start:
lda $2002 ;
bpl Start ;
だったね(疑似命令の.org $8000は違うぞ。疑似命令はアセンブラに直接伝える命令のことだから。)これがちゃんとnesふぁいるに反映されていることを確かめよう。
まず、6502の命令コード表をどこかから拾ってこよう。http://hp.vector.co.jp/authors/VA042397/nes/6502.htmlとかhttp://www.geocities.jp/g_lsluk/module_6502.htmlとかhttp://pgate1.at-ninja.jp/NES_on_FPGA/nes_cpu.htmとか。
この命令コード表を見ると、「lda (アドレス)」 のコードは「AD」であることが分かると思う。じゃあ、giko.nesの$0010を見てみると・・・確かに「AD」と書いてある!
アセンブラはこんな感じで、アセンブリ言語で書かれたプログラムを機械語の命令コードに変換していたんですなぁ。
じゃあ、アドレスの$2002は?といってgiko005.nesの$0011と$0012を見てみると「02 20」と書いてあってちょっと混乱するかもしれない。これは機械語特有のことなんだけど、2バイトの16進数は下位バイト→上位バイトの順番に書いているから「02 20」とかいてあるわけですな。これはバイナリエディタでチートコードを作ったことがある人にはなじみ深いかも。 http://88mmflak36.tripod.com/edit/edit.html#hitu のサイトが超分かりやすい。
と、いう感じでプログラムを解析していくことができますと。逆に言うと、この解析を進めていくとなんとアセンブリ言語で書かれたプログラムを(完ぺきではないけど)再現できるわけだ。このことを、逆アセンブルとかディスアセンブルっていうみたい。はぇ~
さてさて、とりあえずこれで.nesファイルの解析はいいかな。
ただ、もう一つだけ。giko005.nesを高機能nesエミュレータのfceuxで開いて「Debug → Hex Editor」を選択すると…
CPUやPPUなどのメモリ空間が見れるみたいです!これは非常にうれしい。試しにCPUのメモリ空間の$8000から先に書いてあるはずのプログラムを見てみると、先ほどgiko005.nesをバイナリエディタstirlingでひらいて確認したPRG-ROMの内容と一致している!!
という感じで.nesファイルの中身を堪能したよ。こうやってブラックボックスだったものの中身を解き明かすのって
めっちゃ面白いですな(´▽`*)
コメント