
■ コードファイルを作る ■
前回は関数が呼出される瞬間に何が行なわれるか説明しました。
また、関数の処理が終了する時に何が行なわれるかも説明しま
した。
関数を呼出す為の命令「call」があると、インテルプロセッサ
は指定された関数を呼出す前にスタック領域に「どこに戻れば
良いか」の情報を格納してくれるのでした。
そして関数の処理終了時に使用される命令「ret」があると、
インテルプロセッサはスタック領域から「どこに戻れば良いか」
の情報を参照して、指定された場所へ処理を移行させるのでし
た。
以下に関数呼出しと関数処理終了の動作イメージを示します。
┌──────────────────────────┐
│ アプリケーションソフトウェア │
│ │
└───┬──────────────────────┘
│ 呼出し スタック領域
1番最初│call near ptr sub ┌─────┐
├─────────────────────→│1番最初 │
│ └─────┘
│ ┌────────┐
├────────→│ sub関数 │
│←──┐ │ │
│ │ └───┬────┘
│ │ │
続きの処理 │ ┌──┴──┐
・ │ │ 処理 │
・ │ └──┬──┘
・ │ │ret命令 スタック領域
・ │ │どこへ戻るか参照┌─────┐
│ 1番最初に戻る │←───────┤1番最初 │
└─────────┘ └─────┘
関数を呼出す時に「call」という命令を使用していますが、こ
の時インテルプロセッサはただ指定された関数に処理を移行さ
せるのではなく、同時に「どこに戻れば良いか」の情報をスタ
ック領域に格納するのでした。
また、関数の処理終了時に「ret」という命令を使用しますが、
この時インテルプロセッサはスタック領域から「どこに戻れば
良いか」の情報を参照し、指定された場所へ処理を移行させる
のでした。
それでは実際に「call」命令を使用した簡単なプログラムを作
ってみましょう。
テキストエディタで新しく「func1.c」というファイルを作成
して、内容を以下の様にしてください。
─↓ここから──────────────────────
#include <stdio.h>
void main(void);
void sub(void);
void main()
{
_asm{
call near ptr sub
}
}
void sub()
{
_asm{
}
}
─↑ここまで──────────────────────
見てもらえると分かると思いますが、このプログラムは「sub」
という関数を呼出すだけの物です。
sub関数は何も処理を行わないので、実質何も処理を行なわ
ないプログラムです。
上の例はC言語でsub関数を作成しましたが、このsub関
数を純粋なアセンブラ言語で表すと以下の様になります。
_sub:
ret
たったこれだけです。
何も処理を行なわない関数なのでこれだけの記述でも良いので
す。
さて、ここまではCコンパイラの機能の1部分である、インラ
インアセンブラを使用してアセンブラ言語のプログラムを作っ
てきました。
インラインアセンブラを使用すると記述が簡単に出来るので分
かりやすいのです。
しかし、ここから先の説明では残念ながらインラインアセンブ
ラだけを使用する事は出来なくなってしまいました。
この講座をお読みの皆さんのレベルが上がってきているので、
インラインアセンブラだけで説明を行なう事が出来なくなって
しまったのです。
これから先の説明では、新しいビルド方法を行ないます。
と言っても、今までのコンパイラオプションに1個追加するだ
けです。
それでは「func1.c」を新しい方法でビルドしてみましょう。
● ●
● ビルドする ●
● ●
コマンドプロンプトを起動した後は必ず環境設定のバッチファ
イルを実行するようにしましょう。
env.bat
上記バッチファイル実行後、コマンドプロンプト上で以下の様
に入力してください。
sc func1.c -j -cod
 ̄ ̄
↑
新しいコンパイラオプション
これでビルドされ、"func1.exe"という実行ファイルが作成さ
れるはずです。
● ●
● 実行する ●
● ●
コマンドプロンプト上で以下の様に入力してください。
func1.exe
何も処理を行なわないプログラムなのですぐに終了したと思い
ます。
何故わざわざこんな意味の無いプログラムを作ってもらったか
と言うと、コンパイラオプションを1つ加えてビルドする事に
よって新たにコードファイルを作りたかったからです。
● ●
● コードファイル ●
● ●
先ほどdmコンパイラのオプション「-cod」を付けてビルドして
もらいました。
このオプションを付ける事によりコードファイルという物が出
力されるようになります。
コードファイルにはアセンブラ言語のソースコードが出力され
ます。
ソースファイルがあるディレクトリと同じディレクトリに
func1.cod
というコードファイルが出来ているはずです。
この様なコンパイラオプションは、Digital Mars社製コンパイ
ラだけでなく、他のコンパイラでも大体付ける事が可能になっ
ていると思います。
興味のある方はそれぞれのコンパイラのヘルプやマニュアルを
調べてみてください。(コードファイル、またはリストファイ
ルという記述で説明がしてあると思います。)
それでは早速ファイルの中身を見てみましょう。
─↓ここから──────────────────────
_TEXT segment dword use32 public 'CODE' ;size is 13
_TEXT ends
_DATA segment dword use32 public 'DATA' ;size is 0
_DATA ends
CONST segment dword use32 public 'CONST' ;size is 0
CONST ends
_BSS segment dword use32 public 'BSS' ;size is 0
_BSS ends
FLAT group
includelib SNN.lib
extrn __acrtused_con
public _main
public _sub
_TEXT segment
assume CS:_TEXT
_main:
push EBX
push ESI
push EDI
call near ptr _sub
pop EDI
pop ESI
pop EBX
ret
_sub:
ret
_TEXT ends
_DATA segment
_DATA ends
CONST segment
CONST ends
_BSS segment
_BSS ends
end
─↑ここまで──────────────────────
初めて見る方にとっては、一見難しく感じると思います。
しかし、1つ1つじっくり見ていくとそれほど難しい物ではな
い事が分かります。
メールヘッダを見るよりは簡単だと思います。
次回はコードファイルの中身について1つずつ見ていく予定で
す。