SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

MASMとなでしこによるオリジナルコンパイラの制作

MASMとなでしこによるオリジナルコンパイラの制作 3

コンパイラを作成してコンパイルをする

コンソール上への文字列の表示

1.実装について

 コンソール上への文字列の表示には、VEFBLでこのように実現させようと思います。

print "(String)"

 (String)とは、特殊な記号を除いた文字列を意味します。特殊な記号については、後で説明します。

2.アセンブリ

 「vefbl」フォルダに「astest」のフォルダを作り、その中に先ほど「vefbl」フォルダにコピーした「iolib.dll」をコピーします。さらに「astest」フォルダ内に「1.asm」を新規作成してください。

ファイル構成(太字が追加箇所)
 +---vefbl
       +---build.exe
       +---build.nako
       +---tokentest.nako
       +---dnako.dll
       +---astest.exe
       +---makejapanese.bat
       +---makewinjapanese.bat
       +---vsvars32.bat
       +---astest
              +---iolib.dll
              +---1.asm
       +---plug-ins
              +---nakofile.dll
              +---nakostr.dll

 以下のテキストを記述します。

1.asm
.586
.model flat, stdcall

include iolib.inc
includelib iolib.lib
include kernel32.inc
includelib kernel32.lib

.code
_start:
        invoke OutputString, "Hello Word!"
        invoke ExitProcess, 0
end _start

 OutputString関数は、「iolib.dll」の中で定義されています。「kernel32」は、ExitProcessのために必要なのでincludeしています。そしてこれをアセンブルするわけなのですが、アセンブラのコマンドラインの指定はとても複雑です。そこで、簡単にアセンブリをアセンブルできるツールを用意しました。「astest.exe」です。

 まず、「astest」フォルダを右クリックして[コマンドプロンプトから開く]をクリックし、出てきたコマンドプロンプトに次のように打ち込んでください。

コマンドライン
cd astest
..\astest 1
コマンドプロンプトから開く方法
 [コマンドプロンプトから開く]を実行する方法は、前回の記事で紹介しているので、こちらを参照してください。

 上記のコマンドラインは、「1.asmをアセンブルする」という意味です。ファイル名は拡張子を付加しない「1」を指定します。アセンブルに成功すると拡張子.asmが付加された「1.asm」ファイルが作成されます。

 間違って「1.asm」とコマンドラインで指定すると、astest.exeは「1.asm.asmは存在しません」というメッセージを返します。ちゃんとファイルの存在まで調べてくれるのです。astest.exeでは、指定したアセンブリがカレントディレクトリ(現在パスが通っているディレクトリ)にないとリンクエラーを起こします。そのため、必ずカレントディレクトリをアセンブリのあるところに変更します。

 では、改めてアセンブルした結果を見てみましょう。すると、エラーが発生していました。

エラー
C:\Documents and Settings\????????\My Documents\samples\codezine\vefbl
\astest\1.asm(11) : error A2084: constant value too large
C:\Documents and Settings\????????\My Documents\samples\codezine\vefbl
\astest\1.asm(11) : error A2114: INVOKE argument type mismatch : argum
ent : 1

 エラーの種類にはいろいろありますが、以下、エラー番号(error A2084:の「A2084」の部分)のみで説明します。

 A2084の発生理由は「型の指定サイズが大きすぎます」ということになります。A2114の発生理由は、「invokeで呼び出された外部DLLで定義されている型と一致しません」ということです。どこがいけないのでしょうか。エラーの発生した行を見てみましょう。

原因
invoke OutputString, "Hello Word!"

 MASMでは、何かの引数に文字列を指定する場合、一度「.data」内のデータに文字列を登録しておいて、その文字列の変数名を指定する必要があるのです。それをしなかったために、エラーが発生したようです。そのため、以下の通りに修正します。

1.asmを修正(太字が修正箇所)
.586
.model flat, stdcall

include iolib.inc
includelib iolib.lib
include kernel32.inc
includelib kernel32.lib

.data
        PrintText db "Hello Word!", 0

.code
_start:

        invoke OutputString, PrintText
        invoke ExitProcess, 0
end _start

 さて、もう一回アセンブルして実行してみましょう。今度はうまくいきそうです。

Error
C:\Documents and Settings\????????\My Documents\samples\codezine\vefbl
\astest\1.asm(14) : error A2114: INVOKE argument type mismatch : argum
ent : 1

 ところが、またエラーが発生してしまいました。エラーメッセージが指定している14行目を見た結果、さっきと同じところが原因です。

原因?
invoke OutputString, PrintText

 実は、すべてがすべて、というわけではありませんが、外部DLLによっては「~のポインタを指定します」といった説明がAPIリファレンスに書かれていることがあります。「iolib.dll」は『コンパイラ入門 C#で学ぶ理論と実践』(冨沢高明 著、ソフトバンククリエイティブ、2006年2月)の筆者が製作したものですのでAPIの資料はありませんが、とりあえずポインタを指定してみます。

 ポインタは、メモリのアドレス(特定の場所)を指すもので、MASMからポインタを指定するときはoffsetを使います。他にもaddrがありますが、これは非常用みたいなものです。ここではoffsetを指定してみます。

3度目の修正(太字が修正箇所)
.586
.model flat, stdcall

include iolib.inc
includelib iolib.lib
include kernel32.inc
includelib kernel32.lib

.data
        PrintText db "Hello Word!", 0

.code
_start:

        invoke OutputString, offset PrintText
        invoke ExitProcess, 0
end _start

 アセンブルしてみると、今度は成功しました。文字列の格納された変数を指定する時は、よくoffsetを使います。また同時に、「以下のプロジェクトファイルを生成しました」と表示され、「1.exe」という実行ファイルも作成されました。さっそくコマンドラインに

1.exe

 と打ち込みます。すると、

実行結果
実行結果

 と、きちんと「Hello Word!」が表示されました。「iolibが見つかりません」とでてきた人は、「iolib.dll」を「astest」フォルダに移動しているか確認してください。

次のページ
コンパイラの作成

この記事は参考になりましたか?

MASMとなでしこによるオリジナルコンパイラの制作連載記事一覧

もっと読む

この記事の著者

KMY(かみぃ)

とあるごく平凡な中学生。兵庫県在住。日本語プログラミング言語「なでしこ」に惹かれ、たくさんのプログラムを作り利用している。なでしこ以外にも、他の言語を心得ており、HTMLがなでしこの次に得意であり、Perlが第3位(かも)。ベクターにも多彩な作品を残している。作文がど苦手。KMYpage

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/766 2007/03/08 19:10

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー