Intel x86 Assembly Language & Microarchitecture Netwide Assembler - NASM


NASM is by far the most ported assembler for the x86 architecture - it's available for practically every Operating System based on the x86 (even being included with MacOS), and is available as a cross-platform assembler on other platforms.

This assembler uses Intel syntax, but it is different from others because it focuses heavily on its own "macro" language - this permits the programmer to build up more complex expressions using simpler definitions, allowing new "instructions" to be created.

Unfortunately this powerful feature comes at a cost: the type of the data gets in the way of generalised instructions, so data typing is not enforced.

response:    db       'Y'     ; Character that user typed

             cmp      response, 'N' ; *** Error! Unknown size!
             cmp byte response, 'N' ; That's better!
             cmp      response, ax  ; No error!

However, NASM introduced one feature that others lacked: scoped symbol names. When you define a symbol in other assemblers, that name is available throughout the rest of the code - but that "uses up" that name, "polluting" the global name space with symbols.

For example (using NASM syntax):

       STRUC     Point
X      resw      1
Y      resw      1

After this definition, X and Y are forevermore defined. To avoid "using up" the names X and Y, you needed to use more definite names:

       STRUC     Point
Pt_X   resw      1
Pt_Y   resw      1

But NASM offers an alternative. By leveraging its "local variable" concept, you can define structure fields that require you to nominate the containing structure in future references:

       STRUC      Point
.X     resw       1
.Y     resw       1

Cursor ISTRUC     Point

       mov        ax,[Cursor+Point.X]
       mov        dx,[Cursor+Point.Y]

Unfortunately, because NASM doesn't keep track of types, you can't use the more natural syntax:

       mov        ax,[Cursor.X]
       mov        dx,[Cursor.Y]