Next Chapter | Previous Chapter | Contents | Index
NASM contains a powerful macro processor, which supports conditional
assembly, multi-level file inclusion, two forms of macro (single-line and
multi-line), and a `context stack' mechanism for extra macro power.
Preprocessor directives all begin with a 
The preprocessor collapses all lines which end with a backslash (\) character into a single line. Thus:
%define THIS_VERY_LONG_MACRO_NAME_IS_DEFINED_TO \ 
        THIS_VALUE
will work like a single-line macro without the backslash-newline sequence.
%define Single-line macros are defined using the
%define ctrl    0x1F & 
%define param(a,b) ((a)+(a)*(b)) 
        mov     byte [param(2,ebx)], ctrl 'D'
which will expand to
        mov     byte [(2)+(2)*(ebx)], 0x1F & 'D'
When the expansion of a single-line macro contains tokens which invoke another macro, the expansion is performed at invocation time, not at definition time. Thus the code
%define a(x)    1+b(x) 
%define b(x)    2*x 
        mov     ax,a(8)
will evaluate in the expected way to
Macros defined with 
There is a mechanism which detects when a macro call has occurred as a result of a previous expansion of the same macro, to guard against circular references and infinite loops. If this happens, the preprocessor will only expand the first occurrence of the macro. Hence, if you code
%define a(x)    1+a(x) 
        mov     ax,a(3)
the macro 
You can overload single-line macros: if you write
%define foo(x) 1+x %define foo(x,y) 1+x*y
the preprocessor will be able to handle both types of macro call, by
counting the parameters you pass; so 
%define foo bar
then no other definition of 
This doesn't prevent single-line macros being redefined: you can perfectly well define a macro with
%define foo bar
and then re-define it later in the same source file with
%define foo baz
Then everywhere the macro 
You can pre-define single-line macros using the `-d' option on the NASM command line: see section 2.1.18.
%define %xdefine To have a reference to an embedded single-line macro resolved at the
time that it is embedded, as opposed to when the calling macro is expanded,
you need a different mechanism to the one offered by
Suppose you have the following code:
%define isTrue 1 %define isFalse isTrue %define isTrue 0 val1: db isFalse %define isTrue 1 val2: db isFalse
In this case, 
If you wanted 
%xdefine isTrue 1 %xdefine isFalse isTrue %xdefine isTrue 0 val1: db isFalse %xdefine isTrue 1 val2: db isFalse
Now, each time that 
%+ Individual tokens in single line macros can be concatenated, to produce longer tokens for later processing. This can be useful if there are several similar macros that perform similar functions.
Please note that a space is required after 
As an example, consider the following:
%define BDASTART 400h ; Start of BIOS data area
struc   tBIOSDA                      ; its structure 
        .COM1addr       RESW    1 
        .COM2addr       RESW    1 
        ; ..and so on 
endstruc
Now, if we need to access the elements of tBIOSDA in different places, we can end up with:
        mov     ax,BDASTART + tBIOSDA.COM1addr 
        mov     bx,BDASTART + tBIOSDA.COM2addr
This will become pretty ugly (and tedious) if used in many places, and can be reduced in size significantly by using the following macro:
; Macro to access BIOS variables by their names (from tBDA):
%define BDA(x) BDASTART + tBIOSDA. %+ x
Now the above code can be written as:
        mov     ax,BDA(COM1addr) 
        mov     bx,BDA(COM2addr)
Using this feature, we can simplify references to a lot of macros (and, in turn, reduce typing errors).
%? %?? The special symbols 
For example:
%idefine Foo mov %?,%?? 
        foo 
        FOO
will expand to:
        mov foo,Foo 
        mov FOO,Foo
The sequence:
%idefine keyword $%?
can be used to make a keyword "disappear", for example in case a new instruction has been used as a label in older code. For example:
%idefine pause $%? ; Hide the PAUSE instruction
%undef Single-line macros can be removed with the
%define foo bar 
%undef  foo 
        mov     eax, foo
will expand to the instruction 
Macros that would otherwise be pre-defined can be undefined on the command-line using the `-u' option on the NASM command line: see section 2.1.19.
%assign An alternative way to define single-line macros is by means of the
Like 
%assign i i+1
to increment the numeric value of a macro.
The expression passed to 
%defstr 
For example:
%defstr test TEST
is equivalent to
%define test 'TEST'
This can be used, for example, with the 
%defstr PATH %!PATH ; The operating system PATH variable
It's often useful to be able to handle strings in macros. NASM supports two simple string handling macro operators from which more complex operations can be constructed.
All the string operators define or redefine a value (either a string or a numeric value) to a single-line macro.
%strcat The 
For example:
%strcat alpha "Alpha: ", '12" screen'
... would assign the value 
%strcat beta '"', "'"
... would assign the value 
The use of commas to separate strings is permitted but optional.
%strlen The 
%strlen charcnt 'my string'
In this example, 
%define sometext 'my string' %strlen charcnt sometext
As in the first case, this would result in
%substr Individual letters or substrings in strings can be extracted using the
%substr mychar 'xyzw' 1 ; equivalent to %define mychar 'x' %substr mychar 'xyzw' 2 ; equivalent to %define mychar 'y' %substr mychar 'xyzw' 3 ; equivalent to %define mychar 'z' %substr mychar 'xyzw' 2,2 ; equivalent to %define mychar 'yz' %substr mychar 'xyzw' 2,-1 ; equivalent to %define mychar 'yzw' %substr mychar 'xyzw' 2,-2 ; equivalent to %define mychar 'yz'
As with 
%macro Multi-line macros are much more like the type of macro seen in MASM and TASM: a multi-line macro definition in NASM looks something like this.
%macro  prologue 1 
        push    ebp 
        mov     ebp,esp 
        sub     esp,%1 
%endmacro
This defines a C-like function prologue as a macro: so you would invoke the macro with a call such as
myfunc: prologue 12
which would expand to the three lines of code
myfunc: push    ebp 
        mov     ebp,esp 
        sub     esp,12
The number 
Multi-line macros, like single-line macros, are case-sensitive, unless
you define them using the alternative directive
If you need to pass a comma as part of a parameter to a multi-line macro, you can do that by enclosing the entire parameter in braces. So you could code things like
%macro  silly 2 
    %2: db      %1 
%endmacro 
        silly 'a', letter_a             ; letter_a:  db 'a' 
        silly 'ab', string_ab           ; string_ab: db 'ab' 
        silly {13,10}, crlf             ; crlf:      db 13,10
As with single-line macros, multi-line macros can be overloaded by defining the same macro name several times with different numbers of parameters. This time, no exception is made for macros with no parameters at all. So you could define
%macro  prologue 0 
        push    ebp 
        mov     ebp,esp 
%endmacro
to define an alternative form of the function prologue which allocates no local stack space.
Sometimes, however, you might want to `overload' a machine instruction; for example, you might want to define
%macro  push 2 
        push    %1 
        push    %2 
%endmacro
so that you could code
        push    ebx             ; this line is not a macro call 
        push    eax,ecx         ; but this one is
Ordinarily, NASM will give a warning for the first of the above two
lines, since 
NASM allows you to define labels within a multi-line macro definition in
such a way as to make them local to the macro call: so calling the same
macro multiple times will use a different label each time. You do this by
prefixing 
%macro  retz 0 
        jnz     %%skip 
        ret 
    %%skip: 
%endmacro
You can call this macro as many times as you want, and every time you
call it NASM will make up a different `real' name to substitute for the
label 
Occasionally it is useful to define a macro which lumps its entire command line into one parameter definition, possibly after extracting one or two smaller parameters from the front. An example might be a macro to write a text string to a file in MS-DOS, where you might want to be able to write
        writefile [filehandle],"hello, world",13,10
NASM allows you to define the last parameter of a macro to be greedy, meaning that if you invoke the macro with more parameters than it expects, all the spare parameters get lumped into the last defined one along with the separating commas. So if you code:
%macro  writefile 2+ 
        jmp     %%endstr 
  %%str:        db      %2 
  %%endstr: 
        mov     dx,%%str 
        mov     cx,%%endstr-%%str 
        mov     bx,%1 
        mov     ah,0x40 
        int     0x21 
%endmacro
then the example call to 
The greedy nature of the macro is indicated to NASM by the use of the
If you define a greedy macro, you are effectively telling NASM how it
should expand the macro given any number of parameters from the
actual number specified up to infinity; in this case, for example, NASM now
knows what to do when it sees a call to 
Of course, the above macro could have been implemented as a non-greedy macro, in which case the call to it would have had to look like
          writefile [filehandle], {"hello, world",13,10}
NASM provides both mechanisms for putting commas in macro parameters, and you choose which one you prefer for each macro definition.
See section 6.3.1 for a better way to write the above macro.
NASM also allows you to define a multi-line macro with a range of allowable parameter counts. If you do this, you can specify defaults for omitted parameters. So, for example:
%macro  die 0-1 "Painful program death has occurred." 
        writefile 2,%1 
        mov     ax,0x4c01 
        int     0x21 
%endmacro
This macro (which makes use of the 
In general, you supply a minimum and maximum number of parameters for a macro of this type; the minimum number of parameters are then required in the macro call, and then you provide defaults for the optional ones. So if a macro definition began with the line
%macro foobar 1-3 eax,[ebx+2]
then it could be called with between one and three parameters, and
You can provide extra information to a macro by providing too many default parameters:
%macro quux 1 something
This will trigger a warning by default; see
section 2.1.24 for more
information. When 
You may omit parameter defaults from the macro definition, in which case
the parameter default is taken to be blank. This can be useful for macros
which can take a variable number of parameters, since the
This defaulting mechanism can be combined with the greedy-parameter
mechanism; so the 
%macro die 0-1+ "Painful program death has occurred.",13,10
The maximum parameter count can be infinite, denoted by
%0 The parameter reference 
%rotate Unix shell programmers will be familiar with the
NASM provides a similar mechanism, in the form of
So a pair of macros to save and restore a set of registers might work as follows:
%macro  multipush 1-* 
  %rep  %0 
        push    %1 
  %rotate 1 
  %endrep 
%endmacro
This macro invokes the 
Note also the use of 
It would be convenient, when using this macro, to have a
This can be done by the following definition:
%macro  multipop 1-* 
  %rep %0 
  %rotate -1 
        pop     %1 
  %endrep 
%endmacro
This macro begins by rotating its arguments one place to the
right, so that the original last argument appears as
NASM can concatenate macro parameters on to other text surrounding them. This allows you to declare a family of symbols, for example, in a macro definition. If, for example, you wanted to generate a table of key codes along with offsets into the table, you could code something like
%macro keytab_entry 2 
    keypos%1    equ     $-keytab 
                db      %2 
%endmacro 
keytab: 
          keytab_entry F1,128+1 
          keytab_entry F2,128+2 
          keytab_entry Return,13
which would expand to
keytab: 
keyposF1        equ     $-keytab 
                db     128+1 
keyposF2        equ     $-keytab 
                db      128+2 
keyposReturn    equ     $-keytab 
                db      13
You can just as easily concatenate text on to the other end of a macro
parameter, by writing 
If you need to append a digit to a macro parameter, for example
defining labels 
This concatenation can also be applied to other preprocessor in-line
objects, such as macro-local labels (section
4.3.2) and context-local labels (section
4.7.2). In all cases, ambiguities in syntax can be resolved by
enclosing everything after the 
NASM can give special treatment to a macro parameter which contains a
condition code. For a start, you can refer to the macro parameter
Far more usefully, though, you can refer to the macro parameter by means
of 
%macro  retc 1 
        j%-1    %%skip 
        ret 
  %%skip: 
%endmacro
This macro can now be invoked using calls like
The 
When NASM is generating a listing file from your program, it will generally expand multi-line macros by means of writing the macro call and then listing each line of the expansion. This allows you to see which instructions in the macro expansion are generating what code; however, for some macros this clutters the listing up unnecessarily.
NASM therefore provides the 
%macro foo 1.nolist
Or like this:
%macro bar 1-5+.nolist a,b,c,d,e,f,g,h
%unmacro Multi-line macros can be removed with the
For example:
%macro foo 1-3 
        ; Do something 
%endmacro 
%unmacro foo 1-3
removes the previously defined macro 
%unmacro bar 1-3 
        ; Do something 
%endmacro 
%unmacro bar 1
does not remove the macro 
Similarly to the C preprocessor, NASM allows sections of a source file to be assembled only if certain conditions are met. The general syntax of this feature looks like this:
%if<condition> 
    ; some code which only appears if <condition> is met 
%elif<condition2> 
    ; only appears if <condition> is not met but <condition2> is 
%else 
    ; this appears if neither <condition> nor <condition2> was met 
%endif
The inverse forms 
The 
There are a number of variants of the 
%ifdef Beginning a conditional-assembly block with the line
For example, when debugging a program, you might want to write code such as
          ; perform some function 
%ifdef DEBUG 
          writefile 2,"Function performed successfully",13,10 
%endif 
          ; go and do something else
Then you could use the command-line option
You can test for a macro not being defined by using
%ifmacro The 
For example, you may be working with a large project and not have control over the macros in a library. You may want to create a macro with one name if it doesn't already exist, and another name if one with that name does exist.
The 
%ifmacro MyMacro 1-3 
     %error "MyMacro 1-3" causes a conflict with an existing macro. 
%else 
     %macro MyMacro 1-3 
             ; insert code to define the macro 
     %endmacro 
%endif
This will create the macro "MyMacro 1-3" if no macro already exists which would conflict with it, and emits a warning if there would be a definition conflict.
You can test for the macro not existing by using the
%ifctx The conditional-assembly construct 
For more details of the context stack, see
section 4.7. For a sample use of
%if The conditional-assembly construct 
The expression given to 
Like other 
%ifidn %ifidni The construct 
For example, the following macro pushes a register or number on the
stack, and allows you to treat 
%macro  pushparam 1 
  %ifidni %1,ip 
        call    %%label 
  %%label: 
  %else 
        push    %1 
  %endif 
%endmacro
Like other 
%ifid %ifnum %ifstr Some macros will want to perform different tasks depending on whether they are passed a number, a string, or an identifier. For example, a string output macro might want to be able to cope with being passed either a string constant or a pointer to an existing string.
The conditional assembly construct 
For example, the 
%macro writefile 2-3+ 
  %ifstr %2 
        jmp     %%endstr 
    %if %0 = 3 
      %%str:    db      %2,%3 
    %else 
      %%str:    db      %2 
    %endif 
      %%endstr: mov     dx,%%str 
                mov     cx,%%endstr-%%str 
  %else 
                mov     dx,%2 
                mov     cx,%3 
  %endif 
                mov     bx,%1 
                mov     ah,0x40 
                int     0x21 
%endmacro
Then the 
        writefile [file], strpointer, length 
        writefile [file], "hello", 13, 10
In the first, 
Note the use of 
The usual 
%iftoken Some macros will want to do different things depending on if it is
passed a single token (e.g. paste it to something else using
The conditional assembly construct 
For example:
%iftoken 1
will assemble the subsequent code, but
%iftoken -1
will not, since 
The usual 
%ifempty The conditional assembly construct 
The usual 
%rep NASM's 
The directives 
%assign i 0 
%rep    64 
        inc     word [table+2*i] 
%assign i i+1 
%endrep
This will generate a sequence of 64 
For more complex termination conditions, or to break out of a repeat
loop part way along, you can use the 
fibonacci: 
%assign i 0 
%assign j 1 
%rep 100 
%if j > 65535 
    %exitrep 
%endif 
        dw j 
%assign k j+i 
%assign i j 
%assign j k 
%endrep 
fib_number equ ($-fibonacci)/2
This produces a list of all the Fibonacci numbers that will fit in 16
bits. Note that a maximum repeat count must still be given to
These commands allow you to split your sources into multiple files.
%include Using, once again, a very similar syntax to the C preprocessor, NASM's
preprocessor lets you include other source files into your code. This is
done by the use of the 
%include "macros.mac"
will include the contents of the file
Include files are searched for in the current directory (the directory
you're in when you run NASM, as opposed to the location of the NASM
executable or the location of the source file), plus any directories
specified on the NASM command line using the 
The standard C idiom for preventing a file being included more than once
is just as applicable in NASM: if the file
%ifndef MACROS_MAC 
    %define MACROS_MAC 
    ; now define some macros 
%endif
then including the file more than once will not cause errors, because
the second time the file is included nothing will happen because the macro
You can force a file to be included even if there is no
%pathsearch The 
For example,
%pathsearch MyFoo "foo.bin"
... with 
%depend The 
This is generally used in conjunction with
%imacro incbin 1-2+ 0 
%pathsearch dep %1 
%depend dep 
        incbin dep,%2 
%endmacro
This first resolves the location of the file into the macro
%use The 
Unlike the 
%use altreg %use 'altreg'
Standard macro packages are protected from multiple inclusion. When a
standard macro package is used, a testable single-line macro of the form
Having labels that are local to a macro definition is sometimes not
quite powerful enough: sometimes you want to be able to share labels
between several macro calls. An example might be a
NASM provides this level of power by means of a context stack.
The preprocessor maintains a stack of contexts, each of which is
characterized by a name. You add a new context to the stack using the
%push %pop The 
%push foobar
This pushes a new context called 
The directive 
Just as the usage 
%macro repeat 0 
    %push   repeat 
    %$begin: 
%endmacro 
%macro until 1 
        j%-1    %$begin 
    %pop 
%endmacro
and invoked by means of, for example,
        mov     cx,string 
        repeat 
        add     cx,3 
        scasb 
        until   e
which would scan every fourth byte of a string in search of the byte in
If you need to define, or access, labels local to the context
below the top one on the stack, you can use
NASM also allows you to define single-line macros which are local to a particular context, in just the same way:
%define %$localmac 3
will define the single-line macro 
%repl If you need to change the name of the top context on the stack (in
order, for example, to have it respond differently to
NASM provides the directive 
%pop %push newname
with the non-destructive version
This example makes use of almost all the context-stack features,
including the conditional-assembly construct
%macro if 1 
    %push if 
    j%-1  %$ifnot 
%endmacro 
%macro else 0 
  %ifctx if 
        %repl   else 
        jmp     %$ifend 
        %$ifnot: 
  %else 
        %error  "expected `if' before `else'" 
  %endif 
%endmacro 
%macro endif 0 
  %ifctx if 
        %$ifnot: 
        %pop 
  %elifctx      else 
        %$ifend: 
        %pop 
  %else 
        %error  "expected `if' or `else' before `endif'" 
  %endif 
%endmacro
This code is more robust than the 
In addition, the 
The 
A sample usage of these macros might look like:
        cmp     ax,bx 
        if ae 
               cmp     bx,cx 
               if ae 
                       mov     ax,cx 
               else 
                       mov     ax,bx 
               endif 
        else 
               cmp     ax,cx 
               if ae 
                       mov     ax,cx 
               endif 
        endif
The block-
The following preprocessor directives provide a way to use labels to refer to local variables allocated on the stack.
%arg %stacksize %local %arg The 
While NASM has macros which attempt to duplicate this functionality (see
section 8.4.5), the syntax is not
particularly convenient to use. and is not TASM compatible. Here is an
example which shows the use of 
some_function: 
    %push     mycontext        ; save the current context 
    %stacksize large           ; tell NASM to use bp 
    %arg      i:word, j_ptr:word 
        mov     ax,[i] 
        mov     bx,[j_ptr] 
        add     ax,[bx] 
        ret 
    %pop                       ; restore original context
This is similar to the procedure defined in
section 8.4.5 and adds the value
in i to the value pointed to by j_ptr and returns the sum in the ax
register. See section 4.7.1 for an explanation
of 
%stacksize The 
%stacksize flat
This form causes NASM to use stack-based parameter addressing relative
to 
%stacksize flat64
This form causes NASM to use stack-based parameter addressing relative
to 
%stacksize large
This form uses 
%stacksize small
This form also uses 
%local The 
silly_swap: 
    %push mycontext             ; save the current context 
    %stacksize small            ; tell NASM to use bp 
    %assign %$localsize 0       ; see text for explanation 
    %local old_ax:word, old_dx:word 
        enter   %$localsize,0   ; see text for explanation 
        mov     [old_ax],ax     ; swap ax & bx 
        mov     [old_dx],dx     ; and swap dx & cx 
        mov     ax,bx 
        mov     dx,cx 
        mov     bx,[old_ax] 
        mov     cx,[old_dx] 
        leave                   ; restore old bp 
        ret                     ; 
    %pop                        ; restore original context
The 
%error %warning %fatal The preprocessor directive 
%ifdef F1 
    ; do some setup 
%elifdef F2 
    ; do some different setup 
%else 
    %error "Neither F1 nor F2 was defined." 
%endif
Then any user who fails to understand the way your code is supposed to be assembled will be quickly warned of their mistake, rather than having to wait until the program crashes on being run and then not knowing what went wrong.
Similarly, 
%ifdef F1 
    ; do some setup 
%elifdef F2 
    ; do some different setup 
%else 
    %warning "Neither F1 nor F2 was defined, assuming F1." 
    %define F1 
%endif
It is optional for the message string after
%if foo > 64 
    %assign foo_over foo-64 
    %error foo is foo_over bytes too large 
%endif
NASM also has preprocessor directives which allow access to information from external sources. Currently they include:
The following preprocessor directive is supported to allow NASM to correctly handle output of the cpp C language preprocessor.
%line %! %line The 
This preprocessor directive is not generally of use to programmers, by
may be of interest to preprocessor authors. The usage of the
%line nnn[+mmm] [filename]
In this directive, 
After reading a 
%! <env> The 
For example, suppose that you have an environment variable
%defstr FOO %!FOO
See section 4.1.7 for notes on the
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
Most user-level assembler directives (see chapter 6) are implemented as macros which invoke primitive directives; these are described in chapter 6. The rest of the standard macro set is described here.
The single-line macros 
Additionally, the macro 
__NASM_VERSION_ID__ The single-line macro 
        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.
__NASM_VER__ The single-line macro 
        db      __NASM_VER__
would expand to
        db      "0.98.32"
__FILE__ __LINE__ Like the C preprocessor, NASM allows the user to find out the file name
and line number containing the current instruction. The macro
These macros could be used, for example, to communicate debugging
information to a macro, since invoking 
%macro  notdeadyet 0 
        push    eax 
        mov     eax,__LINE__ 
        call    stillhere 
        pop     eax 
%endmacro
and then pepper your code with calls to
__BITS__ The 
__OUTPUT_FORMAT__ The 
%ifidn __OUTPUT_FORMAT__, win32 %define NEWLINE 13, 10 %elifidn __OUTPUT_FORMAT__, elf32 %define NEWLINE 10 %endif
NASM provides a variety of macros that represent the timestamp of the assembly session.
__DATE__ __TIME__ "YYYY-MM-DD" "HH:MM:SS" __DATE_NUM__ __TIME_NUM__ YYYYMMDD HHMMSS __UTC_DATE__ __UTC_TIME__ "YYYY-MM-DD" "HH:MM:SS" __UTC_DATE_NUM__ __UTC_TIME_NUM__ YYYYMMDD HHMMSS __POSIX_TIME__ 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
__USE_ __ When a standard macro package is included with the
For example, if the 
__PASS__ The macro 
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.
STRUC ENDSTRUC 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
For example, to define a structure called
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: 
The reason why the structure type name is defined at zero 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
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
ISTRUC AT IEND 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 
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 
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 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 mt_str 
                db      'hello, world' 
                db      13,10,0
ALIGN ALIGNB The 
        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
If the second argument is not specified, the default for
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: 
See also the