「自作エミュレータで学ぶx86アーキテクチャ」という面白そうな本を見つけたことは以下の記事に書きました。
それから5か月経ってようやくこちらに関わることができたので、続きを書きます。連載にしていきたいと思います。
この記事には「自作エミュレータで学ぶx86アーキテクチャ」の概要とC言語プログラム(のファイル)から機械語(のファイル)を作成する方法を書いています。
「自作エミュレータで学ぶx86アーキテクチャ」の概要
自作エミュレータで学ぶx86アーキテクチャはどんな本か?
コンピュータの中身を詳しく知りたい人のための本です。x86CPUの仕組み、CPUと深い関係にある部品、メモリ、キーボード、ディスプレイとCPUの関係についても説明されているとのことです。
非常に興味深く面白そうです。
CPUの振る舞いをPC上で再現するソフトのことをエミュレータといいますが、本書ではエミュレータの作成を通してコンピュータの中身全般の理解を目指します。
対象読者
C言語を学び終えて、コンピュータの中身を知りたい方と書いてあります。
学び終えてというのがどの程度のレベルを指しているかわかりませんが、とりあえず、本の内容についていってみたいと思います。
この本の目的
機械語レベルでCPUが動く仕組みを理解できる
x86エミュレータの作り方と改造の仕方がわかる
の2点です。
すごく面白そうです。
エミュレータとは何か?
CPUの振る舞いを模倣することで、仮想コンピュータをPC上に作成する。実機の上に仮想コンピュータを作成すること。現時点ではこの程度の理解で読み進めています。
エミュレータを作ることの意味
エミュレータを作ることによってコンピュータの仕組みがよくわかる、ということらしいです。
本書の構成
1章
C言語、アセンブリ言語、機械語の関係を学習する。
2章
ポインタをアセンブリ言語の世界から眺めて理解する。
3章
エミュレータを作りながらCPUが動く仕組みを理解していく。
4章
BIOSについて学習。実機を使ってOSの助けなしに自作プログラムを動かすとのこと。現時点ではどういう意味か理解できません。
では、1章から学習していきます。
Chapter1
Chapter1では C言語、アセンブリ言語、機械語とはそれぞれ何なのか?とそれらの関係を理解していきます。
1.1 C言語から機械語へ
まず、C言語と機械語の関係を見ていきます。
C言語のプログラムは英単語のような命令が書かれたテキストファイルです。
人間は読んで理解できますが、CPUは理解できません。
例:C言語プログラム casm-c-sample.c
void func(void){
int val = 0;
val++;
}
一方、CPUは機械語だけ理解、実行できます。
上のC言語プログラムを機械語にすると以下のようになります。
55 89 e5 83 (以下省略)
上の数字は16進数で表現されています。コンピュータはこれを0と1のかたまりとして理解し、実行します。
CPUは0と1だけから成る機械語しか理解できません。
これ以上詳しく書きませんが、コンピュータが0と1しか扱えないのは電子回路がデジタル回路だからです。
ここでは0と1しか扱えないという理解にとどめておきます。
いずれにしても人間がどんなプログラミング言語でプログラムを作っても、0と1からなる機械語にしないとCPUは実行できません。
1.1のまとめ
この節ではCPUは機械語しか理解、実行できないことを学んだ。
1.2 機械語とアセンブリ言語
上に書いた通りCPUは機械語しか理解、実行できませんが、人間に機械語は理解できません。
そこで機械語と1対1で対応し、人間にも(比較的)読みやすい言語としてアセンブリ言語が作られました。
(比較的)読みやすいことの例として下にアセンブリ言語と機械語の対応を書いてみました。左の英単語のようなものが並んでいるのがアセンブリ言語で、その右の数字(16進数)が機械語です。
push ebp 55
mov ebp,esp 89 e5
以下略
アセンブリ言語と機械語は1対1に対応するので、必ず、push ebp は機械語では55と表現され、逆に機械語の55はアセンブリ言語の pushu ebp に対応します。
これに対してC言語では同じ記述が異なる機械語に変換されたり、異なる記述が同じ機械語に変換されたりします。
1.2のまとめ
アセンブリ言語と機械語は1対1に対応する。
C言語と機械語は1対1に対応しない。
1.3 機械語に飛び込む
機械語は人間にとって、数字の羅列にしか見えません。
機械語を読むときは(比較的)読みやすいアセンブリ言語に変換してから読みます。
この変換を逆アセンブルとかディスアセンブルといいます。
この節では機械語を逆アセンブルします。
そのためには機械語ファイルを手に入れる必要があります。そのために、C言語ファイル(ここではcams-c-sample.c)を機械語に変換します。
C言語ファイルから機械語ファイルを作成する手順
以下機械語(binファイル)を作成する手順を書いていきます。
サポートページからダウンロードしたツールセットのバッチファイルをクリックしてコマンドプロンプトを起動します。
以下のコマンドをコマンドプロンプトに入力して機械語(binファイル)を作成します。
gcc -Wl,--entry=func,--oformat=binary -nostdlib -fno-asynchronous-unwind-tables -o casm-c-sample.bin casm-c-sample.c
入力したらenterキーを押してコマンドを実行。下の画像のように何も表示されなければコマンド成功です。
作成した機械語は次の通りです。Bzというバイナリエディタで開くと以下のようになります。
55から始まる数字の羅列(実際は2進数の0,1)を見ることができました。
ここまでで機械語(のファイル)を得ることができました。
次回以降はこの機械語のファイルを逆アセンブルしてアセンブリ言語(のファイル)を作成していきます。
この記事は以上です。