X86 Assembly/NASM Syntax

The Netwide Assembler is an x86 and x86-64 assembler that uses syntax similar to Intel. It supports a variety of object file formats, including:


 * 1) ELF32/64
 * 2) Linux a.out
 * 3) NetBSD/FreeBSD a.out
 * 4) MS-DOS 16-bit/32-bit object files
 * 5) Win32/64 object files
 * 6) COFF
 * 7) Mach-O 32/64
 * rdf
 * 1) binary

NASM runs on both Unix/Linux and Windows/DOS.

NASM Syntax
The Netwide Assembler (NASM) uses a syntax "designed to be simple and easy to understand, similar to Intel's but less complex". This means that the operand order is dest then src, as opposed to the AT&T style used by the GNU Assembler. For example,

mov ax, 9

loads the number 9 into register ax.

For those using gdb with nasm, you can set gdb to use Intel-style disassembly by issuing the command:

set disassembly-flavor intel

Comments
A single semi-colon is used for comments, and functions the same as double slash in C++: the compiler ignores from the semicolon to the next newline.

Macros
NASM has powerful macro functions, similar to C's preprocessor. For example,

Example I/O (Linux and BSD)
To pass the kernel a simple input command on Linux, you would pass values to the following registers and then send the kernel an interrupt signal. To read in a single character from standard input (such as from a user at their keyboard), do the following:

After the,   will contain the number of bytes read. If this number is < 0, there was a read error of some sort.

Outputting follows a similar convention:

BSD systems (MacOS X included) use similar system calls, but convention to execute them is different. While on Linux you pass system call arguments in different registers, on BSD systems they are pushed onto stack (except the system call number, which is put into eax, the same way as in Linux). BSD version of the code above:

Hello World (Linux)
Below we have a simple Hello world example, it lays out the basic structure of a nasm program:

In order to assemble, link and run the program we need to do the following:

Hello World (Using only Win32 system calls)
In this example we are going to rewrite the hello world example using Win32 system calls. There are several major differences:


 * 1) The intermediate file will be a Microsoft Win32 (i386) object file
 * 2) We will avoid using interrupts since they may not be portable and, this is Windows, not DOS, therefore we need to bring in several calls from kernel32 DLL

In order to assemble, link and run the program we need to do the following:

In this example we use the  command line option when invoking   to specify the entry point for program execution. Otherwise we would have to use  as the entry point rather than. This example was run under cygwin, in a Windows command prompt the link step would be different. One last note,  does not behave well within a cygwin console, so in order to see output the final exe should be run within a Windows command prompt.

Hello World (Using C libraries and Linking with gcc)
In this example we will rewrite Hello World to use  from the C library and link using. This has the advantage that going from Linux to Windows requires minimal source code changes and a slightly different assemble and link steps. In the Windows world this has the additional benefit that the linking step will be the same in the Windows command prompt and cygwin. There are several major changes:


 * 1) The  string now becomes the format string for   and therefore needs to be null terminated. This also means we do not need to explicitly specify its length anymore.
 * 2) gcc expects the entry point for execution to be main
 * 3) Microsoft will prefix functions using the  calling convention with a underscore. So   and   will become   and   respectively in the Windows development environment.

In order to assemble, link and run the program we need to do the following.

The Windows version with prefixed underscores:

In order to assemble, link and run the program we need to do the following.