NASM actually uses its own variation of Intel syntax, different from the MASM syntax used in Intel's official documentation. The opcode names and operand orders are the same as in Intel so the instructions look the same at first glance, but any significant program will have differences. For example with MASM the instruction used by MOV ax, foo
depends on the type of foo
, while NASM doesn't have types and this always assembles to a move immediate instruction. When the size of an operand can't be determined implicitly MASM requires something like DWORD PTR
to be used where NASM uses DWORD
to mean the same thing. Most of the syntax beyond the instruction mnemonics and basic operand format and ordering is different.
In terms of functionality NASM and GAS are pretty much the same. Both have assembler macro facilities, though NASM's is more extensive and more mature. Many GAS source code files use the C preprocessor instead of GAS's own macro support.
The biggest difference between the two assemblers is their support for 16-bit code. GAS doesn't have any support for defining x86 segments. With GAS you're limited to creating simple single-segment 16-bit binary images, basically just boot sectors and .COM files. NASM has full support for segments and supports OMF format object files which you can use with a suitable linker to create segmented 16-bit executables.
In addition to the OMF object file format, NASM supports a number of formats that GAS doesn't. GAS normally only supports the native format for the machine its running on, basically ELF, PE-COFF, or MACH-O. If you want to support a different format you need to build a "cross-compiling" version of GAS for that format.
Another notable difference is that GAS has support for creating DWARF and Windows 64-bit unwind information (the later required by the Windows x64 ABI) while with NASM you have to create the sections and fill in the data yourself.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…