アセンブラの違い    [アセンブラ][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バイト