naskについてのペー ジ
おおざっぱな説明
- コンパイラの下請けができればそれで十分だろうという発想のもとに作られたNASM風アセンブラ。
- だからアセンブラを本格的に使う人が直接使うのにはあまり向かない。KはASKAという変なアセンブラを使っていて、naskはその下請けとして使っている(ASKAにnask用のソースを作らせている)。
- この本ではアセンブラをちょっとしか使わないし、それにASKAは普通じゃなさ過ぎておすすめできないので、naskでいいかなと判断。多分たくさんアセンブラを使うことになったら、NASMにしていたと思う。
- 生成コードの質がNASMより良い。BINモードでは、アドレス値そのものに対する乗算やビット演算などを許すなど、文法が理解しやすい(NASMではアドレスに対して許されるのは加算と減算のみであって、乗算やビット演算などはアドレス差に対してのみ許される)。
- naskは下請け用途で作ってあるのでエラーメッセージが貧弱。マクロもない。
もっと詳しいエラーが見たい!ときは・・・
- まずリストファイルを出力させます。そしてリストファイルをテキストエディタで開いて、ERRORという文字列を検索してみてください。いろいろ分かると思います。
NASMとの違いは?
- 基本的にほとんどありません。
- あれこれいうよりも、NASMで書いたらどうなるかを見るほうが早いと思うので、helloos5をNASMで書き直してみました。
| nask | NASM | NASM(警告なし) |
| JMP entry | JMP SHORT entry | JMP SHORT entry |
| RESB 18 | RESB 18 | TIMES 18 DB 0 |
| RESB 0x7dfe-$ | RESB 0x1fe-($-$$) | TIMES 0x1fe-($-$$) DB 0 |
- 直すのは全60行中、この2ヶ所(警告なしでは3ヶ所)だけでした。ちなみに$$というのはORGの番地のことで、つまり0x7c00です。naskでも$$は使えるのでNASM用に書き換えても問題なくアセンブルできますが、なんでわざわざ$$みたいなものを使わなきゃいけないのか、初心者には理解しにくいと思います。naskを使うだけでそういう面倒な説明を本文に書かずに済んでいます。
- NASMでは「JMP entry」のSHORTを省略すると意図しないコードになるようです。
- 名無しさんの報告によると、NASMはRESBをコード内に混ぜるのが好きではないらしく警告が出ます。警告を抑えたいときは、RESBをTIMES命令と DB 0 命令に分解します。
- こういうややこしさもNASMを使わない理由です。naskならSHORT指定をしなくてもSHORTになりますし、分かりやすいRESBだけで済みますからね。
- これだけじゃつまらないのでharib00gのipl10.nasでもやってみました。
| nask | NASM | NASM(警告なし) |
| JMP entry | JMP SHORT entry | JMP SHORT entry |
| RESB 18 | RESB 18 | TIMES 18 DB 0 |
| RESB 0x7dfe-$ | RESB 0x1fe-($-$$) | TIMES 0x1fe-($-$$) DB 0 |
- おっとこれも全107行のうちこれだけしか違わないようです。
- 物足りないのでさらにharib00iのasmhead.nasでもやってみました。
| nask | NASM | NASM(警告なし) |
| [INSTRSET "i486p"] | この行削除 | この行削除 |
| RESB 8 | RESB 8 | TIMES 8 DB 0 |
| ALIGNB 16 | ALIGNB 16 | ALIGN 16, DB 0 |
- 全147行中、直したのはこれだけです。NASMには命令セットを指定する命令がありません。
- ALIGNB ? は、 ALIGN ?, RESB 1 の省略形なので、警告を出させたくないときは DB 0 に直しました。
- WCOFFの例もあったほうがいいかなと思ったので書いておきます。harib04gのnaskfunc.nasです。
| nask | NASM |
| [FORMAT "WCOFF"] | この行削除 |
| [INSTRSET "i486p"] | この行削除 |
| [FILE "naskfunc.nas"] | この行削除 |
- NASMでは[FORMAT]文がありません。代わりにアセンブルするときにコマンドラインに -fwin32 を書きます。[FILE]文もありません。だから削除します。
- もしかしたら条件ジャンプ命令で「short jump is out of range」というエラーが出るかもしれません。そのときは JNE NEAR _asm_end_app というふうに「NEAR」キーワードを入れてください。naskでは何も書かない場合はNEARかSHORTなのかを自動的に選択しますが、NASMではこのような自動最適化能力がないせいです(うわさによると一部のバージョンではこの能力がある?)。
WCOFFってなに?
- WCOFFは win32-COFF の略で、.objファイルの種類の一つです。もともとCOFFといえばDJGPP-COFFのことを言うと思うのですが、マイクロソフト社はこれを一部改造した亜流のCOFFを使っています。これがwin32-COFFです。
- NASMではこの.objを出力させるときは -fwin32 と指定します( -fcoff だとDJGPP-COFFの.objになる)。
- ちなみにGNUのアセンブラであるgasも、Windows版ではwin32-COFFを出力しているようです。
未定義命令はエラーにしてよ!
- 「たとえばCPUID。エラーにならないから気が付くのに苦労しちゃったよ!」
- まずはどうもすみません。これがエラーにならない最大の理由は、文法のお手本にしたNASMとの互換性のためでした。NASMではたとえば
hogehoge
と書くと、これは hogehoge: というラベルの宣言だとみなされる仕様になっています。つまり未知の命令に遭遇するとそれはラベル宣言だと解釈してしまうわけです。で、この仕様をnaskも忠実に引き継いでいるのです。
- 当時はできるだけNASMに近づけておくほうがドキュメントの整備が楽になるからいいやとばかりに、こんな細かい仕様まで気にしてあわせた記憶があります。しかし今になって思えば、これはむしろNASMの欠陥を引き継いだともいえます。HLTと書くべきところをHALTと書いてしまったとしても気づけないことになりますからね。
- ということで今度のnaskの修正時には、単独のラベル宣言に関しては、末尾にコロンがない場合はエラーにするようにします。ただし、デフォルトの [OPTION 0] ではNASM互換を優先して、このエラーを無効にする予定です。
- ついでに、naskでのエラー発生時にエラー行を出力するようにするかもしれません。
こめんと欄
- 指示どおりやってみました。nasm のバージョンは 0.98.39 です。最初の2つは警告どまりでしたが、最後の1つはエラーでした。 -- 名無しさん 2006-03-23 (木) 11:36:24
$ nasm ipl09.nas
ipl09.nas:29: warning: uninitialised space declared in .text section: zeroing
ipl09.nas:152: warning: uninitialised space declared in .text section: zeroing
$ nasm asmhead.nas
asmhead.nas:191: warning: uninitialised space declared in .text section: zeroing
asmhead.nas:191: warning: uninitialised space declared in .text section: zeroing
asmhead.nas:191: warning: uninitialised space declared in .text section: zeroing
asmhead.nas:191: warning: uninitialised space declared in .text section: zeroing
asmhead.nas:191: warning: uninitialised space declared in .text section: zeroing
asmhead.nas:193: warning: uninitialised space declared in .text section: zeroing
$ nasm -fwin32 naskfunc.nas
naskfunc.nas:177: error: short jump is out of range
- 追記:"JNE near _asm_end_app" のように near をつけたら通りました! -- 名無しさん 2006-03-23 (木) 11:41:13
- ご報告ありがとうございました。「NASMとの違いは?」に書き足しました。 -- K 2006-03-23 (木) 15:00:40
- 間違いなくビルド方法が悪いのだと思いますが、ブートローダー部分がうまく書き込めませんでした・・。使用したのは harib00j です。 -- 名無しさん 2006-03-23 (木) 19:13:03
all:
nasm -fbin -o ipl10.bin ipl10.nas
nasm -fbin -o asmhead.bin asmhead.nas
nasm -fwin32 naskfunc.nas
gcc -nostdlib -Wall -fno-builtin -O3 -DHOST_CYGWIN -c bootpack.c
ld -e _HariMain --Map third.map -n -Ttext 0xc200 -static -o haribote.bin bootpack.o naskfunc.obj
strip.exe -O binary haribote.bin
cat asmhead.bin haribote.bin > haribote.sys
-rm haribote.img
edimg imgin:fdimg0at.tek \
wbinimg src:ipl10.bin len:512 from:0 to:0 \
copy from:haribote.sys to:@: \
imgout:haribote.img
clean:
-rm haribote.img haribote.sys haribote.bin ipl10.bin asmhead.bin *.obj *.o *.map
nasm -fbin -o ipl10.bin ipl10.nas
nasm -fbin -o asmhead.bin asmhead.nas
nasm -fwin32 naskfunc.nas
gcc -nostdlib -Wall -fno-builtin -O3 -DHOST_CYGWIN -c bootpack.c
ld -e _HariMain --Map haribote.map -n -Ttext 0xc200 -static -o haribote.bin bootpack.o naskfunc.obj
strip.exe -O binary haribote.bin
cat asmhead.bin haribote.bin > haribote.sys
rm haribote.img
rm: cannot remove `haribote.img': No such file or directory
make: [all] Error 1 (ignored)
edimg imgin:fdimg0at.tek \
wbinimg src:ipl10.bin len:512 from:0 to:0 \
copy from:haribote.sys to:@: \
imgout:haribote.img
imgout BPB data error.
make: *** [all] Error 37
- ご報告ありがとうございます。こちらでも実験してみたところ「JMP entry」の部分の問題のようです。直し方について「NASMとの違いは?」に書き足しました。ちなみにgccやldのオプションがそれでいいかどうかは当方では確認していません。 -- K 2006-03-24 (金) 00:43:58
- CPUIDやRDMSRなどNASKが未対応な命令は無視されるようですが、せめてエラーメッセージが出てくれたほうがわかりやすいと思います。未対応だということに気が付くのに少し時間がかかってしまいました。 -- ひよひよ 2006-04-20 (木) 00:22:38
- 改善要望をありがとうございました。お返事を上記の「未定義命令はエラーにしてよ!」に書きましたので、よろしければごらんください。 -- K 2006-04-20 (木) 05:16:41
- ご回答ありがとうございました。ラベルとして認識されていたのですか・・・納得です。 -- ひよひよ 2006-04-20 (木) 07:38:56
- toolsのnaskを見ようとしたらなぜかこのページに来てしまいます。URLはhttp://hrb.osask.jp/wiki/?tools/naskです。 -- ken6 2009-05-04 (月) 12:15:43
- ご指摘ありがとうございます。なぜかSeroさんのページと混ざっていたようです。バックアップから修復しました。 -- K 2009-05-04 (月) 15:40:52
- NASMで命令セットを指定したい場合はCPUディレクティブを使えば大丈夫です。 -- skyblue 2015-02-20 (金) 16:54:01