X86アセンブラ/NASM構文

出典: フリー教科書『ウィキブックス(Wikibooks)』
ナビゲーションに移動 検索に移動
このページ「X86アセンブラ/NASM構文」は、書きかけです。加筆・訂正など、協力いただける皆様の編集を心からお待ちしております。また、ご意見などがありましたら、お気軽にノートへどうぞ。

基本の知識[編集]

インストール方法[編集]

Linuxの場合

まず、インストール方法は、Linux の Fedora の31 場合

sudo dnf install nasm

で入る。

Windowsの場合、公式サイトからインストーラーをダウンロードできる。

ウィキペディア『w:Netwide Assembler』に公式サイトへのリンクがあるので、そこから たどって、ダウンロードしよう。

Windows版NASMでの初期設定の方法などは、

wikibooks『X86アセンブラ/x86アセンブラ』で書いておいた。けっこう初期設定が難しいので、Windowsでnasmを使用したい人は、ぜひリンク先を読もう。Windows版では、普通にボタンをぽちぽちと押しているだけでは、初期設定が終わらず、さらにパス(path)の設定などが必要になる。

Linux の場合も、後述のように「リンカ」というものの使用が必要になる(くわしくは、あとで説明するので、分からなくても、読み進めてもいい)。

特徴[編集]

NASM で

nasm test.asm -o test.o

でコンパイルしても、出力されるコードは、Windowsの実行ファイル形式のexe形式ではないし、Linuxの実行ファイル形式のELF形式でもない。

この場合、特定のOSに依存しない、インテルのCPUの規格に従って機械語が出力されるので、BIOSやブートローダでしか実行できない。

なので、

Windowsの実行ファイルとして出力したい場合は、下記のように nasm -f win32 または nasm -f win64 と引数を追加する必要があります。 たとえば

nasm -f win32 test.asm -o test.o

のようになります。

Linuxの場合、64ビットCPU環境なら下記のように nasm -f elf64 と引数を追加する必要があります。32ビット用なら引数は nasm -f elf だけです。

ただし、これだけでは、まだ実行可能ファイルになっておらず、さらに下記のように「リンカ」処理をする必要がある。

Linux の場合[編集]

Linux の場合、とりあえず下記の手順で実行できる。

まず、ネットで nasm 用のHello World プログラムのソースファイルを公開してくれている人々がいるので、彼等のファイルで実験しよう。

とりあえず、彼等のファイルを 「hello.s」 という名前で、テキストエディタで保存したとする。

[ユーザ名@localhost ~]$ nasm -f elf64 hello.s -o hello.o
[ユーザ名@localhost ~]$ ld -m elf_x86_64 hello.o
[ユーザ名@localhost ~]$ ./a.out

(Fedora 31 で動作を確認ずみ)

これで、

Hello World 

みたいな文章が表示されるハズである(おおもとの公開プログラムが間違ってないかぎりは)。


で、実はコマンド「 nasm -f elf64 hello.s -o hello.o」で出力されるファイル hello.o は、まだELF形式に、なってない。証拠は、バイナリエディタで中身の大きさを調べれば分かる。この段階では、冒頭のヘッダ部分などの一部がELF用に書き変わっただけである。

なので、ファイルの長さ/大きさが、この段階のファイル hello.o と、実際の実行可能ファイルとでは、まったく違う。この段階のファイル hello.o のサイズは小さく、バイナリエディタでも見ても、マウスホイールを2〜3回くらい動かせば末尾まで見終わってしまう。

いっぽう、実際に実行可能なファイルの大きさは、マウスホイールを20回くらい動かして、ようやく末尾を見終れるほどの大きさである。


なので、この「 nasm -f elf64 」後に完全なELF形式にするためには、追加の作業として ld -m elf_x86_64 hello.o のような完成させるためのコマンドが必要になる。

LD コマンドとは、実行可能ファイルにするための そういった処理をするための Unix/Linux コマンドである。Linux用のLDコマンドは一般に、GNUが実装しているので(Gnu LD)、おそらくこれもGnu LD だろう。プログラミング用語でいう、いわゆる「リンカ」である。


なお、上記のコマンドで最終的に出力されるファイル名は「a.out」なので、もしこのファイル名が嫌だったり、他にもファイルを出力するのでファイル名を変えたい場合などには、LinuxのGUI側からマウスの右クリック操作などで普通にファイル名を変えよう。

ファイル名をつけて実行ファイルを出力したい場合は、下記のような入力順になる。

[ユーザ名@localhost ~]$ nasm -f elf64 hello.s -o hello.o
[ユーザ名@localhost ~]$ ld -o hello3 hello2.o -m elf_x86_64
[ユーザ名@localhost ~]$ ./hello3

(Fedora 31 で動作を確認ずみ)

なお上記例では、a.outの例と区別しやすくするため、出力ファイルの名前を「hello3」に変えた。

ld コマンドの語順の制約がけっこう厳しく、ちょっとでも語順を変えると、よくエラーメッセージで

ld: cannot find hello3: No such file or directory

(意訳: そのようなファイル名またはディレクトリはないです)とか言われてエラーになるので、もう上記のコマンドをそのままコピーして、ファイル名だけ変えて使おう。

機械語での出力[編集]

なお

nasm -f bin

と引数を追加すると、機械語で出力できます。

また、特に出力フォーマットを指定しない場合は、機械語の出力になります(なので、nasmでブートローダなどを簡単に作れる)。

つまり

nasm test.asm -o test.img

とした場合、これはBIOSなどが読み取る機械語です。