NASM - The Netwide Assembler

version 2.16.01

Chapter 5: Standard Macros

NASM defines a set of standard macros, which are already defined when it starts to process any source file. If you really need a program to be assembled with no pre-defined macros, you can use the %clear directive to empty the preprocessor of everything but context-local preprocessor variables and single-line macros, see section 4.13.3.

Most user-level directives (see chapter 7) are implemented as macros which invoke primitive directives; these are described in chapter 7. The rest of the standard macro set is described here.

For compatibility with NASM versions before NASM 2.15, most standard macros of the form __?foo?__ have aliases of form __foo__ (see section 4.2.11). These can be removed with the directive %clear defalias.

5.1 NASM Version Macros

The single-line macros __?NASM_MAJOR?__, __?NASM_MINOR?__, __?NASM_SUBMINOR?__ and __?NASM_PATCHLEVEL?__ expand to the major, minor, subminor and patch level parts of the version number of NASM being used. So, under NASM 0.98.32p1 for example, __?NASM_MAJOR?__ would be defined to be 0, __?NASM_MINOR?__ would be defined as 98, __?NASM_SUBMINOR?__ would be defined to 32, and __?NASM_PATCHLEVEL?__ would be defined as 1.

Additionally, the macro __?NASM_SNAPSHOT?__ is defined for automatically generated snapshot releases only.

5.1.1 __?NASM_VERSION_ID?__: NASM Version ID

The single-line macro __?NASM_VERSION_ID?__ expands to a dword integer representing the full version number of the version of nasm being used. The value is the equivalent to __?NASM_MAJOR?__, __?NASM_MINOR?__, __?NASM_SUBMINOR?__ and __?NASM_PATCHLEVEL?__ concatenated to produce a single doubleword. Hence, for 0.98.32p1, the returned number would be equivalent to:

        dd      0x00622001

or

        db      1,32,98,0

Note that the above lines are generate exactly the same code, the second line is used just to give an indication of the order that the separate values will be present in memory.

5.1.2 __?NASM_VER?__: NASM Version String

The single-line macro __?NASM_VER?__ expands to a string which defines the version number of nasm being used. So, under NASM 0.98.32 for example,

        db      __?NASM_VER?__

would expand to

        db      "0.98.32"

5.2 __?FILE?__ and __?LINE?__: File Name and Line Number

Like the C preprocessor, NASM allows the user to find out the file name and line number containing the current instruction. The macro __?FILE?__ expands to a string constant giving the name of the current input file (which may change through the course of assembly if %include directives are used), and __?LINE?__ expands to a numeric constant giving the current line number in the input file.

These macros could be used, for example, to communicate debugging information to a macro, since invoking __?LINE?__ inside a macro definition (either single-line or multi-line) will return the line number of the macro call, rather than definition. So to determine where in a piece of code a crash is occurring, for example, one could write a routine stillhere, which is passed a line number in EAX and outputs something like line 155: still here. You could then write a macro:

%macro  notdeadyet 0 

        push    eax 
        mov     eax,__?LINE?__ 
        call    stillhere 
        pop     eax 

%endmacro

and then pepper your code with calls to notdeadyet until you find the crash point.

5.3 __?BITS?__: Current Code Generation Mode

The __?BITS?__ standard macro is updated every time that the BITS mode is set using the BITS XX or [BITS XX] directive, where XX is a valid mode number of 16, 32 or 64. __?BITS?__ receives the specified mode number and makes it globally available. This can be very useful for those who utilize mode-dependent macros.

5.4 __?OUTPUT_FORMAT?__: Current Output Format

The __?OUTPUT_FORMAT?__ standard macro holds the current output format name, as given by the -f option or NASM's default. Type nasm -h for a list.

%ifidn __?OUTPUT_FORMAT?__, win32 
 %define NEWLINE 13, 10 
%elifidn __?OUTPUT_FORMAT?__, elf32 
 %define NEWLINE 10 
%endif

5.5 __?DEBUG_FORMAT?__: Current Debug Format

If debugging information generation is enabled, The __?DEBUG_FORMAT?__ standard macro holds the current debug format name as specified by the -F or -g option or the output format default. Type nasm -f output y for a list.

__?DEBUG_FORMAT?__ is not defined if debugging is not enabled, or if the debug format specified is null.

5.6 Assembly Date and Time Macros

NASM provides a variety of macros that represent the timestamp of the assembly session.

All instances of time and date macros in the same assembly session produce consistent output. For example, in an assembly session started at 42 seconds after midnight on January 1, 2010 in Moscow (timezone UTC+3) these macros would have the following values, assuming, of course, a properly configured environment with a correct clock:

      __?DATE?__             "2010-01-01" 
      __?TIME?__             "00:00:42" 
      __?DATE_NUM?__         20100101 
      __?TIME_NUM?__         000042 
      __?UTC_DATE?__         "2009-12-31" 
      __?UTC_TIME?__         "21:00:42" 
      __?UTC_DATE_NUM?__     20091231 
      __?UTC_TIME_NUM?__     210042 
      __?POSIX_TIME?__       1262293242

5.7 __?USE_package?__: Package Include Test

When a standard macro package (see chapter 6) is included with the %use directive (see section 4.8.4), a single-line macro of the form __USE_package__ is automatically defined. This allows testing if a particular package is invoked or not.

For example, if the altreg package is included (see section 6.1), then the macro __?USE_ALTREG?__ is defined.

5.8 __?PASS?__: Assembly Pass

The macro __?PASS?__ is defined to be 1 on preparatory passes, and 2 on the final pass. In preprocess-only mode, it is set to 3, and when running only to generate dependencies (due to the -M or -MG option, see section 2.1.5) it is set to 0.

Avoid using this macro if at all possible. It is tremendously easy to generate very strange errors by misusing it, and the semantics may change in future versions of NASM.

5.9 Structure Data Types

5.9.1 STRUC and ENDSTRUC: Declaring Structure Data Types

The core of NASM contains no intrinsic means of defining data structures; instead, the preprocessor is sufficiently powerful that data structures can be implemented as a set of macros. The macros STRUC and ENDSTRUC are used to define a structure data type.

STRUC takes one or two parameters. The first parameter is the name of the data type. The second, optional parameter is the base offset of the structure. The name of the data type is defined as a symbol with the value of the base offset, and the name of the data type with the suffix _size appended to it is defined as an EQU giving the size of the structure. Once STRUC has been issued, you are defining the structure, and should define fields using the RESB family of pseudo-instructions, and then invoke ENDSTRUC to finish the definition.

For example, to define a structure called mytype containing a longword, a word, a byte and a string of bytes, you might code

struc   mytype 

  mt_long:      resd    1 
  mt_word:      resw    1 
  mt_byte:      resb    1 
  mt_str:       resb    32 

endstruc

The above code defines six symbols: mt_long as 0 (the offset from the beginning of a mytype structure to the longword field), mt_word as 4, mt_byte as 6, mt_str as 7, mytype_size as 39, and mytype itself as zero.

The reason why the structure type name is defined at zero by default is a side effect of allowing structures to work with the local label mechanism: if your structure members tend to have the same names in more than one structure, you can define the above structure like this:

struc mytype 

  .long:        resd    1 
  .word:        resw    1 
  .byte:        resb    1 
  .str:         resb    32 

endstruc

This defines the offsets to the structure fields as mytype.long, mytype.word, mytype.byte and mytype.str.

NASM, since it has no intrinsic structure support, does not support any form of period notation to refer to the elements of a structure once you have one (except the above local-label notation), so code such as mov ax,[mystruc.mt_word] is not valid. mt_word is a constant just like any other constant, so the correct syntax is mov ax,[mystruc+mt_word] or mov ax,[mystruc+mytype.word].

Sometimes you only have the address of the structure displaced by an offset. For example, consider this standard stack frame setup:

push ebp 
mov ebp, esp 
sub esp, 40

In this case, you could access an element by subtracting the offset:

mov [ebp - 40 + mytype.word], ax

However, if you do not want to repeat this offset, you can use –40 as a base offset:

struc mytype, -40

And access an element this way:

mov [ebp + mytype.word], ax

5.9.2 ISTRUC, AT and IEND: Declaring Instances of Structures

Having defined a structure type, the next thing you typically want to do is to declare instances of that structure in your data segment. NASM provides an easy way to do this in the ISTRUC mechanism. To declare a structure of type mytype in a program, you code something like this:

mystruc: 
    istruc mytype 

        at mt_long, dd      123456 
        at mt_word, dw      1024 
        at mt_byte, db      'x' 
        at mt_str,  db      'hello, world', 13, 10, 0 

    iend

The function of the AT macro is to make use of the TIMES prefix to advance the assembly position to the correct point for the specified structure field, and then to declare the specified data. Therefore the structure fields must be declared in the same order as they were specified in the structure definition.

If the data to go in a structure field requires more than one source line to specify, the remaining source lines can easily come after the AT line. For example:

        at mt_str,  db      123,134,145,156,167,178,189 
                    db      190,100,0

Depending on personal taste, you can also omit the code part of the AT line completely, and start the structure field on the next line:

        at mt_str 
                db      'hello, world' 
                db      13,10,0

5.10 Alignment Control

5.10.1 ALIGN and ALIGNB: Code and Data Alignment

The ALIGN and ALIGNB macros provides a convenient way to align code or data on a word, longword, paragraph or other boundary. (Some assemblers call this directive EVEN.) The syntax of the ALIGN and ALIGNB macros is

        align   4               ; align on 4-byte boundary 
        align   16              ; align on 16-byte boundary 
        align   8,db 0          ; pad with 0s rather than NOPs 
        align   4,resb 1        ; align to 4 in the BSS 
        alignb  4               ; equivalent to previous line

Both macros require their first argument to be a power of two; they both compute the number of additional bytes required to bring the length of the current section up to a multiple of that power of two, and then apply the TIMES prefix to their second argument to perform the alignment.

If the second argument is not specified, the default for ALIGN is NOP, and the default for ALIGNB is RESB 1. So if the second argument is specified, the two macros are equivalent. Normally, you can just use ALIGN in code and data sections and ALIGNB in BSS sections, and never need the second argument except for special purposes.

ALIGN and ALIGNB, being simple macros, perform no error checking: they cannot warn you if their first argument fails to be a power of two, or if their second argument generates more than one byte of code. In each of these cases they will silently do the wrong thing.

ALIGNB (or ALIGN with a second argument of RESB 1) can be used within structure definitions:

struc mytype2 

  mt_byte: 
        resb 1 
        alignb 2 
  mt_word: 
        resw 1 
        alignb 4 
  mt_long: 
        resd 1 
  mt_str: 
        resb 32 

endstruc

This will ensure that the structure members are sensibly aligned relative to the base of the structure.

A final caveat: ALIGN and ALIGNB work relative to the beginning of the section, not the beginning of the address space in the final executable. Aligning to a 16-byte boundary when the section you're in is only guaranteed to be aligned to a 4-byte boundary, for example, is a waste of effort. Again, NASM does not check that the section's alignment characteristics are sensible for the use of ALIGN or ALIGNB.

Both ALIGN and ALIGNB do call SECTALIGN macro implicitly. See section 5.10.2 for details.

See also the smartalign standard macro package, section 6.2.

5.10.2 SECTALIGN: Section Alignment

The SECTALIGN macros provides a way to modify alignment attribute of output file section. Unlike the align= attribute (which is allowed at section definition only) the SECTALIGN macro may be used at any time.

For example the directive

SECTALIGN 16

sets the section alignment requirements to 16 bytes. Once increased it can not be decreased, the magnitude may grow only.

Note that ALIGN (see section 5.10.1) calls the SECTALIGN macro implicitly so the active section alignment requirements may be updated. This is by default behaviour, if for some reason you want the ALIGN do not call SECTALIGN at all use the directive

SECTALIGN OFF

It is still possible to turn in on again by

SECTALIGN ON

Note that SECTALIGN <ON|OFF> affects only the ALIGN/ALIGNB directives, not an explicit SECTALIGN directive.