by shigemk2

当面は技術的なことしか書かない

SH-3用のEXEコンパイラで"Hello"を出力するEXEファイルを作る

実物

コード

makesh3exe.2014101210.js

ヘッダ、というか.textセクション以外は他のCPUと同じ構造なので、.textセクションだけをごにょごにょしたらいい。

x86とは違うのは、

  • ImageBase=0x10000固定
  • MSVCRT.DLLではなくCOREDLL.DLL
  • 命令はリトルエンディアン
  • 遅延スロット

そう、リトルエンディアン!

さらに、inc命令が、ない!

.textセクションまわりのコード

f:id:shigemk2:20141012104715p:plain

DLLを呼び出して、アドレスの値に気をつけつつ、コードを追加していく。

最後にexitするのを忘れずに。

今日やったこと #ikebin

SH-3のBrainfuckEXEコンパイラをNode.jsで作る。半分まで。

アセンブリを16進数でNode.jsに手入力して、それをバイナリでファイルに吐くという簡単なお仕事。

+-<>.まで対応する。たぶんKernel VMには間に合わない。

流れ

DLLを呼び出す命令をBFまわりの命令の前にレジスタで定義して、値を入れておく。 BRA命令でその部分はジャンプする。

これは、C言語をsh-elf-gccでコンパイルして、sh-elf-objdumpで逆アセンブルすると、アセンブリがどういう使い方をなされているかがなんとなく分かる。

なお、BRA命令のあとにはNOP命令が来る。これを遅延スロットというが、どこまでジャンプするかはアセンブラで指定している。

R8-R13はPermanent Registersと呼ばれ、値が不変であることから、putcharやgetcharなどの命令はR8-R11に格納する。

やっている作業はまあだいたいこんな感じ。

CPU-ファイルフォーマット、みたいな感じ。

SH-PEとか、SH-ELFとか。なお、fileコマンドでファイルの形式を知ることが出来る。

gccでコンパイルするときにOオプションをつけると最適化してくれる。O2ってやるともっと最適化してくれる。gオプションをつけると逆アセンブル時にデバッグ情報を付与してくれる。

完成品(未完成)

EXEコンパイラ

makebrainfuckexe-sh3.2014101222.js

BFコード

33.b

実行結果

スクリーンショットはXPCEを使用。

f:id:shigemk2:20141012230318j:plain

どのコードがどのアセンブリなのかを知るときの流れ

簡単なC言語を書いて、O(最適化)とg(デバッグ情報付与)オプションをつけてgccでコンパイル。

で、objdumpで逆アセンブルをかける。すると、知りたい情報を得ることが出来たりする。

a.c