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などが読み取る機械語です。