アセンブラの違い [アセンブラ][MASM][NASM]
特に MASM32 に
こだわるわけではないですが、移植の際に多少でも楽になるよう、気がついた
NASM との違いを ここに書き留めておく。
1)擬似命令の違い。
① assume命令を使わない。
assume cs:CSEG, ds:CSEG, ss:CSEG
は削除する。
② DB命令の違い。
MASMでは、値を入れない領域確保に
例;40バイト確保の場合、
DB 40 dup (?)
と書くが、NASMでは、
RESB 40
と書く。
(ただし、セクションBBS内か 構造体内のみ有効)
他のセクションでは、
TIMES 40 DB 0
とするのが、良い。
(40回 DB 0を繰り返す)
このセンスの無い (?) は使わなくて良い。
③ ALIGNB命令が使えない。
MASMでは ALINE関連の命令が無い。
NASMなら、
ALIGNB 2
で、必ずこの次のコードやデータは
偶数アドレスに割り当てられる。
MASMでは、リストファイルを見て、必要なだけNOPを
入れるしかない。
これが面倒であれば、データを先頭に集めるか、
バイト境界でバグるような、コードを書かないことである。
2) MASMでは使えない命令がある。
8086時代にはなかった命令は、当然使えない。
MASM32でも対応していないのは?不思議だが。
例えば、
① シフト、ローテイト命令の複数ビット。
SHL BX,4 とかは使えない。
これは、
SHL BX,1
SHL BX,1
SHL BX,1
SHL BX,1
と同じ。
② 固定値の PUSH。
例えば、 PUSH 100h とかは出来ない。
空いているレジスタに、値をいれてからPUSHする。
3) 命令の描き方の違い。
① ptr は不要。
MASMでは、
MOV AL,byte ptr [200h]
と書くが、NASMでは、
MOV AL,BYTE [200h]
でいい。
この意味の無い ptr は書かない。
(ptr : Pointerの略?)
同じように word ptr も WORD。
② offsetがいらない。
アドレスを代入する場合、MASMでは
MOV AX,offset MSG
のように書くが、NASMでは、このoffsetが不要。
MOV AX,MSG
③ セグメントの書き方の違い
MASMではセグメントはカッコの外。
MOV AX, DS:[ SI ]
NASMはカッコの中。
MOV AX, [ DS:SI ]
4) 局所(ローカル)ラベルのルールが違う
MASM32では @@ を局所ラベルとして使えた。
jmp @b で上の@@へ
jmp @f で下にある@@へ移動できる。
NASMでは、これが無い。
.(ピリオド)で始まる名前が局所ラベルとなる。
ただし、局所ラベルはアセンブラによってかなり
仕様が異なる1つでsり、使用には注意が必要。
・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・・
また、細かな違いであるが、MASM系とNASM系で一部コードの展開が異なる。
例えば、
XOR AX,AX
という、命令がある。
MASMでは、33h C0h と展開されるが、
NASMでは、31h C0h と展開される。
どちらも動作は、全く同じだが、バイナリで比較を行う時に "違い" として現れてしまう。
また、当然ではあるが、セグメントを明示するかどうかで、展開するコードのバイト数が違ってくる。
例:
MOV AX,[SI] 8Bh,04h の2バイト
MOV AX,[DS:SI] 3Eh,8Bh,04h の3バイト