diff options
Diffstat (limited to 'doc/info/nasm.info-1')
-rw-r--r-- | doc/info/nasm.info-1 | 7484 |
1 files changed, 7484 insertions, 0 deletions
diff --git a/doc/info/nasm.info-1 b/doc/info/nasm.info-1 new file mode 100644 index 0000000..d1896f8 --- /dev/null +++ b/doc/info/nasm.info-1 @@ -0,0 +1,7484 @@ +This is nasm.info, produced by makeinfo version 4.13 from nasmdoc.texi. + +INFO-DIR-SECTION Programming +START-INFO-DIR-ENTRY +* NASM: (nasm). The Netwide Assembler for x86. +END-INFO-DIR-ENTRY + + This file documents NASM, the Netwide Assembler: an assembler +targetting the Intel x86 series of processors, with portable source. + + Copyright 1996-2009 The NASM Development Team + + This document is redistributable under the license given in the file +"COPYING" distributed in the NASM archive. + + +File: nasm.info, Node: Top, Next: Chapter 1, Prev: (dir), Up: (dir) + +The Netwide Assembler for x86 +***************************** + +This file documents NASM, the Netwide Assembler: an assembler +targetting the Intel x86 series of processors, with portable source. + +* Menu: + +* Chapter 1:: Introduction +* Chapter 2:: Running NASM +* Chapter 3:: The NASM Language +* Chapter 4:: The NASM Preprocessor +* Chapter 5:: Standard Macro Packages +* Chapter 6:: Assembler Directives +* Chapter 7:: Output Formats +* Chapter 8:: Writing 16-bit Code (DOS, Windows 3/3.1) +* Chapter 9:: Writing 32-bit Code (Unix, Win32, DJGPP) +* Chapter 10:: Mixing 16 and 32 Bit Code +* Chapter 11:: Writing 64-bit Code (Unix, Win64) +* Chapter 12:: Troubleshooting +* Appendix A:: Ndisasm +* Appendix B:: Instruction List +* Appendix C:: NASM Version History +* Index:: + + +File: nasm.info, Node: Chapter 1, Next: Section 1.1, Prev: Top, Up: Top + +Chapter 1: Introduction +*********************** + +* Menu: + +* Section 1.1:: What Is NASM? +* Section 1.2:: Contact Information +* Section 1.3:: Installation + + +File: nasm.info, Node: Section 1.1, Next: Section 1.1.1, Prev: Chapter 1, Up: Chapter 1 + +1.1. What Is NASM? +================== + +The Netwide Assembler, NASM, is an 80x86 and x86-64 assembler designed +for portability and modularity. It supports a range of object file +formats, including Linux and `*BSD' `a.out', `ELF', `COFF', `Mach-O', +Microsoft 16-bit `OBJ', `Win32' and `Win64'. It will also output plain +binary files. Its syntax is designed to be simple and easy to +understand, similar to Intel's but less complex. It supports all +currently known x86 architectural extensions, and has strong support +for macros. + +* Menu: + +* Section 1.1.1:: Why Yet Another Assembler? +* Section 1.1.2:: License Conditions + + +File: nasm.info, Node: Section 1.1.1, Next: Section 1.1.2, Prev: Section 1.1, Up: Section 1.1 + +1.1.1. Why Yet Another Assembler? +--------------------------------- + +The Netwide Assembler grew out of an idea on `comp.lang.asm.x86' (or +possibly `alt.lang.asm' - I forget which), which was essentially that +there didn't seem to be a good _free_ x86-series assembler around, and +that maybe someone ought to write one. + + * `a86' is good, but not free, and in particular you don't get any + 32- bit capability until you pay. It's DOS only, too. + + * `gas' is free, and ports over to DOS and Unix, but it's not very + good, since it's designed to be a back end to `gcc', which always + feeds it correct code. So its error checking is minimal. Also, its + syntax is horrible, from the point of view of anyone trying to + actually _write_ anything in it. Plus you can't write 16-bit code + in it (properly.) + + * `as86' is specific to Minix and Linux, and (my version at least) + doesn't seem to have much (or any) documentation. + + * `MASM' isn't very good, and it's (was) expensive, and it runs only + under DOS. + + * `TASM' is better, but still strives for MASM compatibility, which + means millions of directives and tons of red tape. And its syntax + is essentially MASM's, with the contradictions and quirks that + entails (although it sorts out some of those by means of Ideal + mode.) It's expensive too. And it's DOS-only. + + So here, for your coding pleasure, is NASM. At present it's still in +prototype stage - we don't promise that it can outperform any of these +assemblers. But please, _please_ send us bug reports, fixes, helpful +information, and anything else you can get your hands on (and thanks to +the many people who've done this already! You all know who you are), +and we'll improve it out of all recognition. Again. + + +File: nasm.info, Node: Section 1.1.2, Next: Section 1.2, Prev: Section 1.1.1, Up: Section 1.1 + +1.1.2. License Conditions +------------------------- + +Please see the file `LICENSE', supplied as part of any NASM +distribution archive, for the license conditions under which you may use +NASM. NASM is now under the so-called 2-clause BSD license, also known +as the simplified BSD license. + + Copyright 1996-2009 the NASM Authors - All rights reserved. + + Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A +PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +File: nasm.info, Node: Section 1.2, Next: Section 1.3, Prev: Section 1.1.2, Up: Chapter 1 + +1.2. Contact Information +======================== + +The current version of NASM (since about 0.98.08) is maintained by a +team of developers, accessible through the `nasm-devel' mailing list +(see below for the link). If you want to report a bug, please read +*note Section 12.2:: first. + + NASM has a website at `http://www.nasm.us/'. If it's not there, +google for us! + + New releases, release candidates, and daily development snapshots of +NASM are available from the official web site. + + Announcements are posted to `comp.lang.asm.x86', and to the web site +`http://www.freshmeat.net/'. + + If you want information about the current development status, please +subscribe to the `nasm-devel' email list; see link from the website. + + +File: nasm.info, Node: Section 1.3, Next: Section 1.3.1, Prev: Section 1.2, Up: Chapter 1 + +1.3. Installation +================= + +* Menu: + +* Section 1.3.1:: Installing NASM under MS-DOS or Windows +* Section 1.3.2:: Installing NASM under Unix + + +File: nasm.info, Node: Section 1.3.1, Next: Section 1.3.2, Prev: Section 1.3, Up: Section 1.3 + +1.3.1. Installing NASM under MS-DOS or Windows +---------------------------------------------- + +Once you've obtained the appropriate archive for NASM, +`nasm-XXX-dos.zip' or `nasm-XXX-win32.zip' (where `XXX' denotes the +version number of NASM contained in the archive), unpack it into its +own directory (for example `c:\nasm'). + + The archive will contain a set of executable files: the NASM +executable file `nasm.exe', the NDISASM executable file `ndisasm.exe', +and possibly additional utilities to handle the RDOFF file format. + + The only file NASM needs to run is its own executable, so copy +`nasm.exe' to a directory on your PATH, or alternatively edit +`autoexec.bat' to add the `nasm' directory to your `PATH' (to do that +under Windows XP, go to Start > Control Panel > System > Advanced > +Environment Variables; these instructions may work under other versions +of Windows as well.) + + That's it - NASM is installed. You don't need the nasm directory to +be present to run NASM (unless you've added it to your `PATH'), so you +can delete it if you need to save space; however, you may want to keep +the documentation or test programs. + + If you've downloaded the DOS source archive, `nasm-XXX.zip', the +`nasm' directory will also contain the full NASM source code, and a +selection of Makefiles you can (hopefully) use to rebuild your copy of +NASM from scratch. See the file `INSTALL' in the source archive. + + Note that a number of files are generated from other files by Perl +scripts. Although the NASM source distribution includes these +generated files, you will need to rebuild them (and hence, will need a +Perl interpreter) if you change insns.dat, standard.mac or the +documentation. It is possible future source distributions may not +include these files at all. Ports of Perl for a variety of platforms, +including DOS and Windows, are available from www.cpan.org. + + +File: nasm.info, Node: Section 1.3.2, Next: Chapter 2, Prev: Section 1.3.1, Up: Section 1.3 + +1.3.2. Installing NASM under Unix +--------------------------------- + +Once you've obtained the Unix source archive for NASM, +`nasm-XXX.tar.gz' (where `XXX' denotes the version number of NASM +contained in the archive), unpack it into a directory such as +`/usr/local/src'. The archive, when unpacked, will create its own +subdirectory `nasm-XXX'. + + NASM is an auto-configuring package: once you've unpacked it, `cd' to +the directory it's been unpacked into and type `./configure'. This +shell script will find the best C compiler to use for building NASM and +set up Makefiles accordingly. + + Once NASM has auto-configured, you can type `make' to build the +`nasm' and `ndisasm' binaries, and then `make install' to install them +in `/usr/local/bin' and install the man pages `nasm.1' and `ndisasm.1' +in `/usr/local/man/man1'. Alternatively, you can give options such as +`--prefix' to the configure script (see the file `INSTALL' for more +details), or install the programs yourself. + + NASM also comes with a set of utilities for handling the `RDOFF' +custom object-file format, which are in the `rdoff' subdirectory of the +NASM archive. You can build these with `make rdf' and install them with +`make rdf_install', if you want them. + + +File: nasm.info, Node: Chapter 2, Next: Section 2.1, Prev: Section 1.3.2, Up: Top + +Chapter 2: Running NASM +*********************** + +* Menu: + +* Section 2.1:: NASM Command-Line Syntax +* Section 2.2:: Quick Start for MASM Users + + +File: nasm.info, Node: Section 2.1, Next: Section 2.1.1, Prev: Chapter 2, Up: Chapter 2 + +2.1. NASM Command-Line Syntax +============================= + +To assemble a file, you issue a command of the form + + nasm -f <format> <filename> [-o <output>] + + For example, + + nasm -f elf myfile.asm + + will assemble `myfile.asm' into an `ELF' object file `myfile.o'. And + + nasm -f bin myfile.asm -o myfile.com + + will assemble `myfile.asm' into a raw binary file `myfile.com'. + + To produce a listing file, with the hex codes output from NASM +displayed on the left of the original sources, use the `-l' option to +give a listing file name, for example: + + nasm -f coff myfile.asm -l myfile.lst + + To get further usage instructions from NASM, try typing + + nasm -h + + As `-hf', this will also list the available output file formats, and +what they are. + + If you use Linux but aren't sure whether your system is `a.out' or +`ELF', type + + file nasm + + (in the directory in which you put the NASM binary when you +installed it). If it says something like + + nasm: ELF 32-bit LSB executable i386 (386 and up) Version 1 + + then your system is `ELF', and you should use the option `-f elf' +when you want NASM to produce Linux object files. If it says + + nasm: Linux/i386 demand-paged executable (QMAGIC) + + or something similar, your system is `a.out', and you should use `-f +aout' instead (Linux `a.out' systems have long been obsolete, and are +rare these days.) + + Like Unix compilers and assemblers, NASM is silent unless it goes +wrong: you won't see any output at all, unless it gives error messages. + +* Menu: + +* Section 2.1.1:: The `-o' Option: Specifying the Output File Name +* Section 2.1.2:: The `-f' Option: Specifying the Output File Format +* Section 2.1.3:: The `-l' Option: Generating a Listing File +* Section 2.1.4:: The `-M' Option: Generate Makefile Dependencies +* Section 2.1.5:: The `-MG' Option: Generate Makefile Dependencies +* Section 2.1.6:: The `-MF' Option: Set Makefile Dependency File +* Section 2.1.7:: The `-MD' Option: Assemble and Generate Dependencies +* Section 2.1.8:: The `-MT' Option: Dependency Target Name +* Section 2.1.9:: The `-MQ' Option: Dependency Target Name (Quoted) +* Section 2.1.10:: The `-MP' Option: Emit phony targets +* Section 2.1.11:: The `-F' Option: Selecting a Debug Information Format +* Section 2.1.12:: The `-g' Option: Enabling Debug Information. +* Section 2.1.13:: The `-X' Option: Selecting an Error Reporting Format +* Section 2.1.14:: The `-Z' Option: Send Errors to a File +* Section 2.1.15:: The `-s' Option: Send Errors to `stdout' +* Section 2.1.16:: The `-i' Option: Include File Search Directories +* Section 2.1.17:: The `-p' Option: Pre-Include a File +* Section 2.1.18:: The `-d' Option: Pre-Define a Macro +* Section 2.1.19:: The `-u' Option: Undefine a Macro +* Section 2.1.20:: The `-E' Option: Preprocess Only +* Section 2.1.21:: The `-a' Option: Don't Preprocess At All +* Section 2.1.22:: The `-O' Option: Specifying Multipass Optimization +* Section 2.1.23:: The `-t' Option: Enable TASM Compatibility Mode +* Section 2.1.24:: The `-w' and `-W' Options: Enable or Disable Assembly Warnings +* Section 2.1.25:: The `-v' Option: Display Version Info +* Section 2.1.26:: The `-y' Option: Display Available Debug Info Formats +* Section 2.1.27:: The `--prefix' and `--postfix' Options. +* Section 2.1.28:: The `NASMENV' Environment Variable + + +File: nasm.info, Node: Section 2.1.1, Next: Section 2.1.2, Prev: Section 2.1, Up: Section 2.1 + +2.1.1. The `-o' Option: Specifying the Output File Name +------------------------------------------------------- + +NASM will normally choose the name of your output file for you; +precisely how it does this is dependent on the object file format. For +Microsoft object file formats (`obj', `win32' and `win64'), it will +remove the `.asm' extension (or whatever extension you like to use - +NASM doesn't care) from your source file name and substitute `.obj'. +For Unix object file formats (`aout', `as86', `coff', `elf32', `elf64', +`ieee', `macho32' and `macho64') it will substitute `.o'. For `dbg', +`rdf', `ith' and `srec', it will use `.dbg', `.rdf', `.ith' and +`.srec', respectively, and for the `bin' format it will simply remove +the extension, so that `myfile.asm' produces the output file `myfile'. + + If the output file already exists, NASM will overwrite it, unless it +has the same name as the input file, in which case it will give a +warning and use `nasm.out' as the output file name instead. + + For situations in which this behaviour is unacceptable, NASM +provides the `-o' command-line option, which allows you to specify your +desired output file name. You invoke `-o' by following it with the name +you wish for the output file, either with or without an intervening +space. For example: + + nasm -f bin program.asm -o program.com + nasm -f bin driver.asm -odriver.sys + + Note that this is a small o, and is different from a capital O , +which is used to specify the number of optimisation passes required. See +*note Section 2.1.22::. + + +File: nasm.info, Node: Section 2.1.2, Next: Section 2.1.3, Prev: Section 2.1.1, Up: Section 2.1 + +2.1.2. The `-f' Option: Specifying the Output File Format +--------------------------------------------------------- + +If you do not supply the `-f' option to NASM, it will choose an output +file format for you itself. In the distribution versions of NASM, the +default is always `bin'; if you've compiled your own copy of NASM, you +can redefine `OF_DEFAULT' at compile time and choose what you want the +default to be. + + Like `-o', the intervening space between `-f' and the output file +format is optional; so `-f elf' and `-felf' are both valid. + + A complete list of the available output file formats can be given by +issuing the command `nasm -hf'. + + +File: nasm.info, Node: Section 2.1.3, Next: Section 2.1.4, Prev: Section 2.1.2, Up: Section 2.1 + +2.1.3. The `-l' Option: Generating a Listing File +------------------------------------------------- + +If you supply the `-l' option to NASM, followed (with the usual +optional space) by a file name, NASM will generate a source-listing file +for you, in which addresses and generated code are listed on the left, +and the actual source code, with expansions of multi-line macros +(except those which specifically request no expansion in source +listings: see *note Section 4.3.10::) on the right. For example: + + nasm -f elf myfile.asm -l myfile.lst + + If a list file is selected, you may turn off listing for a section +of your source with `[list -]', and turn it back on with `[list +]', +(the default, obviously). There is no "user form" (without the +brackets). This can be used to list only sections of interest, avoiding +excessively long listings. + + +File: nasm.info, Node: Section 2.1.4, Next: Section 2.1.5, Prev: Section 2.1.3, Up: Section 2.1 + +2.1.4. The `-M' Option: Generate Makefile Dependencies +------------------------------------------------------ + +This option can be used to generate makefile dependencies on stdout. +This can be redirected to a file for further processing. For example: + + nasm -M myfile.asm > myfile.dep + + +File: nasm.info, Node: Section 2.1.5, Next: Section 2.1.6, Prev: Section 2.1.4, Up: Section 2.1 + +2.1.5. The `-MG' Option: Generate Makefile Dependencies +------------------------------------------------------- + +This option can be used to generate makefile dependencies on stdout. +This differs from the `-M' option in that if a nonexisting file is +encountered, it is assumed to be a generated file and is added to the +dependency list without a prefix. + + +File: nasm.info, Node: Section 2.1.6, Next: Section 2.1.7, Prev: Section 2.1.5, Up: Section 2.1 + +2.1.6. The `-MF' Option: Set Makefile Dependency File +----------------------------------------------------- + +This option can be used with the `-M' or `-MG' options to send the +output to a file, rather than to stdout. For example: + + nasm -M -MF myfile.dep myfile.asm + + +File: nasm.info, Node: Section 2.1.7, Next: Section 2.1.8, Prev: Section 2.1.6, Up: Section 2.1 + +2.1.7. The `-MD' Option: Assemble and Generate Dependencies +----------------------------------------------------------- + +The `-MD' option acts as the combination of the `-M' and `-MF' options +(i.e. a filename has to be specified.) However, unlike the `-M' or +`-MG' options, `-MD' does _not_ inhibit the normal operation of the +assembler. Use this to automatically generate updated dependencies with +every assembly session. For example: + + nasm -f elf -o myfile.o -MD myfile.dep myfile.asm + + +File: nasm.info, Node: Section 2.1.8, Next: Section 2.1.9, Prev: Section 2.1.7, Up: Section 2.1 + +2.1.8. The `-MT' Option: Dependency Target Name +----------------------------------------------- + +The `-MT' option can be used to override the default name of the +dependency target. This is normally the same as the output filename, +specified by the `-o' option. + + +File: nasm.info, Node: Section 2.1.9, Next: Section 2.1.10, Prev: Section 2.1.8, Up: Section 2.1 + +2.1.9. The `-MQ' Option: Dependency Target Name (Quoted) +-------------------------------------------------------- + +The `-MQ' option acts as the `-MT' option, except it tries to quote +characters that have special meaning in Makefile syntax. This is not +foolproof, as not all characters with special meaning are quotable in +Make. + + +File: nasm.info, Node: Section 2.1.10, Next: Section 2.1.11, Prev: Section 2.1.9, Up: Section 2.1 + +2.1.10. The `-MP' Option: Emit phony targets +-------------------------------------------- + +When used with any of the dependency generation options, the `-MP' +option causes NASM to emit a phony target without dependencies for each +header file. This prevents Make from complaining if a header file has +been removed. + + +File: nasm.info, Node: Section 2.1.11, Next: Section 2.1.12, Prev: Section 2.1.10, Up: Section 2.1 + +2.1.11. The `-F' Option: Selecting a Debug Information Format +------------------------------------------------------------- + +This option is used to select the format of the debug information +emitted into the output file, to be used by a debugger (or _will_ be). +Prior to version 2.03.01, the use of this switch did _not_ enable +output of the selected debug info format. Use `-g', see *note Section +2.1.12::, to enable output. Versions 2.03.01 and later automatically +enable `-g' if `-F' is specified. + + A complete list of the available debug file formats for an output +format can be seen by issuing the command `nasm -f <format> -y'. Not all +output formats currently support debugging output. See *note Section +2.1.26::. + + This should not be confused with the `-f dbg' output format option +which is not built into NASM by default. For information on how to +enable it when building from the sources, see *note Section 7.14::. + + +File: nasm.info, Node: Section 2.1.12, Next: Section 2.1.13, Prev: Section 2.1.11, Up: Section 2.1 + +2.1.12. The `-g' Option: Enabling Debug Information. +---------------------------------------------------- + +This option can be used to generate debugging information in the +specified format. See *note Section 2.1.11::. Using `-g' without `-F' +results in emitting debug info in the default format, if any, for the +selected output format. If no debug information is currently +implemented in the selected output format, `-g' is _silently ignored_. + + +File: nasm.info, Node: Section 2.1.13, Next: Section 2.1.14, Prev: Section 2.1.12, Up: Section 2.1 + +2.1.13. The `-X' Option: Selecting an Error Reporting Format +------------------------------------------------------------ + +This option can be used to select an error reporting format for any +error messages that might be produced by NASM. + + Currently, two error reporting formats may be selected. They are the +`-Xvc' option and the `-Xgnu' option. The GNU format is the default and +looks like this: + + filename.asm:65: error: specific error message + + where `filename.asm' is the name of the source file in which the +error was detected, `65' is the source file line number on which the +error was detected, `error' is the severity of the error (this could be +`warning'), and `specific error message' is a more detailed text +message which should help pinpoint the exact problem. + + The other format, specified by `-Xvc' is the style used by Microsoft +Visual C++ and some other programs. It looks like this: + + filename.asm(65) : error: specific error message + + where the only difference is that the line number is in parentheses +instead of being delimited by colons. + + See also the `Visual C++' output format, *note Section 7.5::. + + +File: nasm.info, Node: Section 2.1.14, Next: Section 2.1.15, Prev: Section 2.1.13, Up: Section 2.1 + +2.1.14. The `-Z' Option: Send Errors to a File +---------------------------------------------- + +Under `MS-DOS' it can be difficult (though there are ways) to redirect +the standard-error output of a program to a file. Since NASM usually +produces its warning and error messages on `stderr', this can make it +hard to capture the errors if (for example) you want to load them into +an editor. + + NASM therefore provides the `-Z' option, taking a filename argument +which causes errors to be sent to the specified files rather than +standard error. Therefore you can redirect the errors into a file by +typing + + nasm -Z myfile.err -f obj myfile.asm + + In earlier versions of NASM, this option was called `-E', but it was +changed since `-E' is an option conventionally used for preprocessing +only, with disastrous results. See *note Section 2.1.20::. + + +File: nasm.info, Node: Section 2.1.15, Next: Section 2.1.16, Prev: Section 2.1.14, Up: Section 2.1 + +2.1.15. The `-s' Option: Send Errors to `stdout' +------------------------------------------------ + +The `-s' option redirects error messages to `stdout' rather than +`stderr', so it can be redirected under `MS-DOS'. To assemble the file +`myfile.asm' and pipe its output to the `more' program, you can type: + + nasm -s -f obj myfile.asm | more + + See also the `-Z' option, *note Section 2.1.14::. + + +File: nasm.info, Node: Section 2.1.16, Next: Section 2.1.17, Prev: Section 2.1.15, Up: Section 2.1 + +2.1.16. The `-i' Option: Include File Search Directories +-------------------------------------------------------- + +When NASM sees the `%include' or `%pathsearch' directive in a source +file (see *note Section 4.6.1::, *note Section 4.6.2:: or *note Section +3.2.3::), it will search for the given file not only in the current +directory, but also in any directories specified on the command line by +the use of the `-i' option. Therefore you can include files from a macro +library, for example, by typing + + nasm -ic:\macrolib\ -f obj myfile.asm + + (As usual, a space between `-i' and the path name is allowed, and +optional). + + NASM, in the interests of complete source-code portability, does not +understand the file naming conventions of the OS it is running on; the +string you provide as an argument to the `-i' option will be prepended +exactly as written to the name of the include file. Therefore the +trailing backslash in the above example is necessary. Under Unix, a +trailing forward slash is similarly necessary. + + (You can use this to your advantage, if you're really perverse, by +noting that the option `-ifoo' will cause `%include "bar.i"' to search +for the file `foobar.i'...) + + If you want to define a _standard_ include search path, similar to +`/usr/include' on Unix systems, you should place one or more `-i' +directives in the `NASMENV' environment variable (see *note Section +2.1.28::). + + For Makefile compatibility with many C compilers, this option can +also be specified as `-I'. + + +File: nasm.info, Node: Section 2.1.17, Next: Section 2.1.18, Prev: Section 2.1.16, Up: Section 2.1 + +2.1.17. The `-p' Option: Pre-Include a File +------------------------------------------- + +NASM allows you to specify files to be _pre-included_ into your source +file, by the use of the `-p' option. So running + + nasm myfile.asm -p myinc.inc + + is equivalent to running `nasm myfile.asm' and placing the directive +`%include "myinc.inc"' at the start of the file. + + For consistency with the `-I', `-D' and `-U' options, this option +can also be specified as `-P'. + + +File: nasm.info, Node: Section 2.1.18, Next: Section 2.1.19, Prev: Section 2.1.17, Up: Section 2.1 + +2.1.18. The `-d' Option: Pre-Define a Macro +------------------------------------------- + +Just as the `-p' option gives an alternative to placing `%include' +directives at the start of a source file, the `-d' option gives an +alternative to placing a `%define' directive. You could code + + nasm myfile.asm -dFOO=100 + + as an alternative to placing the directive + + %define FOO 100 + + at the start of the file. You can miss off the macro value, as well: +the option `-dFOO' is equivalent to coding `%define FOO'. This form of +the directive may be useful for selecting assembly-time options which +are then tested using `%ifdef', for example `-dDEBUG'. + + For Makefile compatibility with many C compilers, this option can +also be specified as `-D'. + + +File: nasm.info, Node: Section 2.1.19, Next: Section 2.1.20, Prev: Section 2.1.18, Up: Section 2.1 + +2.1.19. The `-u' Option: Undefine a Macro +----------------------------------------- + +The `-u' option undefines a macro that would otherwise have been pre- +defined, either automatically or by a `-p' or `-d' option specified +earlier on the command lines. + + For example, the following command line: + + nasm myfile.asm -dFOO=100 -uFOO + + would result in `FOO' _not_ being a predefined macro in the program. +This is useful to override options specified at a different point in a +Makefile. + + For Makefile compatibility with many C compilers, this option can +also be specified as `-U'. + + +File: nasm.info, Node: Section 2.1.20, Next: Section 2.1.21, Prev: Section 2.1.19, Up: Section 2.1 + +2.1.20. The `-E' Option: Preprocess Only +---------------------------------------- + +NASM allows the preprocessor to be run on its own, up to a point. Using +the `-E' option (which requires no arguments) will cause NASM to +preprocess its input file, expand all the macro references, remove all +the comments and preprocessor directives, and print the resulting file +on standard output (or save it to a file, if the `-o' option is also +used). + + This option cannot be applied to programs which require the +preprocessor to evaluate expressions which depend on the values of +symbols: so code such as + + %assign tablesize ($-tablestart) + + will cause an error in preprocess-only mode. + + For compatiblity with older version of NASM, this option can also be +written `-e'. `-E' in older versions of NASM was the equivalent of the +current `-Z' option, *note Section 2.1.14::. + + +File: nasm.info, Node: Section 2.1.21, Next: Section 2.1.22, Prev: Section 2.1.20, Up: Section 2.1 + +2.1.21. The `-a' Option: Don't Preprocess At All +------------------------------------------------ + +If NASM is being used as the back end to a compiler, it might be +desirable to suppress preprocessing completely and assume the compiler +has already done it, to save time and increase compilation speeds. The +`-a' option, requiring no argument, instructs NASM to replace its +powerful preprocessor with a stub preprocessor which does nothing. + + +File: nasm.info, Node: Section 2.1.22, Next: Section 2.1.23, Prev: Section 2.1.21, Up: Section 2.1 + +2.1.22. The `-O' Option: Specifying Multipass Optimization +---------------------------------------------------------- + +NASM defaults to not optimizing operands which can fit into a signed +byte. This means that if you want the shortest possible object code, +you have to enable optimization. + + Using the `-O' option, you can tell NASM to carry out different +levels of optimization. The syntax is: + + * `-O0': No optimization. All operands take their long forms, if a + short form is not specified, except conditional jumps. This is + intended to match NASM 0.98 behavior. + + * `-O1': Minimal optimization. As above, but immediate operands which + will fit in a signed byte are optimized, unless the long form is + specified. Conditional jumps default to the long form unless + otherwise specified. + + * `-Ox' (where `x' is the actual letter `x'): Multipass + optimization. Minimize branch offsets and signed immediate bytes, + overriding size specification unless the `strict' keyword has been + used (see *note Section 3.7::). For compatability with earlier + releases, the letter `x' may also be any number greater than one. + This number has no effect on the actual number of passes. + + The `-Ox' mode is recommended for most uses. + + Note that this is a capital `O', and is different from a small `o', +which is used to specify the output file name. See *note Section +2.1.1::. + + +File: nasm.info, Node: Section 2.1.23, Next: Section 2.1.24, Prev: Section 2.1.22, Up: Section 2.1 + +2.1.23. The `-t' Option: Enable TASM Compatibility Mode +------------------------------------------------------- + +NASM includes a limited form of compatibility with Borland's `TASM'. +When NASM's `-t' option is used, the following changes are made: + + * local labels may be prefixed with `@@' instead of `.' + + * size override is supported within brackets. In TASM compatible + mode, a size override inside square brackets changes the size of + the operand, and not the address type of the operand as it does in + NASM syntax. E.g. `mov eax,[DWORD val]' is valid syntax in TASM + compatibility mode. Note that you lose the ability to override the + default address type for the instruction. + + * unprefixed forms of some directives supported (`arg', `elif', + `else', `endif', `if', `ifdef', `ifdifi', `ifndef', `include', + `local') + + +File: nasm.info, Node: Section 2.1.24, Next: Section 2.1.25, Prev: Section 2.1.23, Up: Section 2.1 + +2.1.24. The `-w' and `-W' Options: Enable or Disable Assembly Warnings +---------------------------------------------------------------------- + +NASM can observe many conditions during the course of assembly which are +worth mentioning to the user, but not a sufficiently severe error to +justify NASM refusing to generate an output file. These conditions are +reported like errors, but come up with the word `warning' before the +message. Warnings do not prevent NASM from generating an output file and +returning a success status to the operating system. + + Some conditions are even less severe than that: they are only +sometimes worth mentioning to the user. Therefore NASM supports the `-w' +command-line option, which enables or disables certain classes of +assembly warning. Such warning classes are described by a name, for +example `orphan-labels'; you can enable warnings of this class by the +command- line option `-w+orphan-labels' and disable it by +`-w-orphan-labels'. + + The suppressible warning classes are: + + * `macro-params' covers warnings about multi-line macros being + invoked with the wrong number of parameters. This warning class is + enabled by default; see *note Section 4.3.2:: for an example of + why you might want to disable it. + + * `macro-selfref' warns if a macro references itself. This warning + class is disabled by default. + + * `macro-defaults' warns when a macro has more default parameters + than optional parameters. This warning class is enabled by + default; see *note Section 4.3.5:: for why you might want to + disable it. + + * `orphan-labels' covers warnings about source lines which contain no + instruction but define a label without a trailing colon. NASM + warns about this somewhat obscure condition by default; see *note + Section 3.1:: for more information. + + * `number-overflow' covers warnings about numeric constants which + don't fit in 64 bits. This warning class is enabled by default. + + * `gnu-elf-extensions' warns if 8-bit or 16-bit relocations are used + in `-f elf' format. The GNU extensions allow this. This warning + class is disabled by default. + + * `float-overflow' warns about floating point overflow. Enabled by + default. + + * `float-denorm' warns about floating point denormals. Disabled by + default. + + * `float-underflow' warns about floating point underflow. Disabled by + default. + + * `float-toolong' warns about too many digits in floating-point + numbers. Enabled by default. + + * `user' controls `%warning' directives (see *note Section 4.9::). + Enabled by default. + + * `error' causes warnings to be treated as errors. Disabled by + default. + + * `all' is an alias for _all_ suppressible warning classes (not + including `error'). Thus, `-w+all' enables all available warnings. + + In addition, you can set warning classes across sections. Warning +classes may be enabled with `[warning +warning-name]', disabled with +`[warning -warning-name]' or reset to their original value with +`[warning *warning-name]'. No "user form" (without the brackets) exists. + + Since version 2.00, NASM has also supported the gcc-like syntax +`-Wwarning' and `-Wno-warning' instead of `-w+warning' and +`-w-warning', respectively. + + +File: nasm.info, Node: Section 2.1.25, Next: Section 2.1.26, Prev: Section 2.1.24, Up: Section 2.1 + +2.1.25. The `-v' Option: Display Version Info +--------------------------------------------- + +Typing `NASM -v' will display the version of NASM which you are using, +and the date on which it was compiled. + + You will need the version number if you report a bug. + + +File: nasm.info, Node: Section 2.1.26, Next: Section 2.1.27, Prev: Section 2.1.25, Up: Section 2.1 + +2.1.26. The `-y' Option: Display Available Debug Info Formats +------------------------------------------------------------- + +Typing `nasm -f <option> -y' will display a list of the available debug +info formats for the given output format. The default format is +indicated by an asterisk. For example: + + nasm -f elf -y + + valid debug formats for 'elf32' output format are + ('*' denotes default): + * stabs ELF32 (i386) stabs debug format for Linux + dwarf elf32 (i386) dwarf debug format for Linux + + +File: nasm.info, Node: Section 2.1.27, Next: Section 2.1.28, Prev: Section 2.1.26, Up: Section 2.1 + +2.1.27. The `--prefix' and `--postfix' Options. +----------------------------------------------- + +The `--prefix' and `--postfix' options prepend or append (respectively) +the given argument to all `global' or `extern' variables. E.g. +`--prefix _' will prepend the underscore to all global and external +variables, as C sometimes (but not always) likes it. + + +File: nasm.info, Node: Section 2.1.28, Next: Section 2.2, Prev: Section 2.1.27, Up: Section 2.1 + +2.1.28. The `NASMENV' Environment Variable +------------------------------------------ + +If you define an environment variable called `NASMENV', the program +will interpret it as a list of extra command-line options, which are +processed before the real command line. You can use this to define +standard search directories for include files, by putting `-i' options +in the `NASMENV' variable. + + The value of the variable is split up at white space, so that the +value `-s -ic:\nasmlib\' will be treated as two separate options. +However, that means that the value `-dNAME="my name"' won't do what you +might want, because it will be split at the space and the NASM +command-line processing will get confused by the two nonsensical words +`-dNAME="my' and `name"'. + + To get round this, NASM provides a feature whereby, if you begin the +`NASMENV' environment variable with some character that isn't a minus +sign, then NASM will treat this character as the separator character for +options. So setting the `NASMENV' variable to the value +`!-s!-ic:\nasmlib\' is equivalent to setting it to `-s -ic:\nasmlib\', +but `!-dNAME="my name"' will work. + + This environment variable was previously called `NASM'. This was +changed with version 0.98.31. + + +File: nasm.info, Node: Section 2.2, Next: Section 2.2.1, Prev: Section 2.1.28, Up: Chapter 2 + +2.2. Quick Start for MASM Users +=============================== + +If you're used to writing programs with MASM, or with TASM in MASM- +compatible (non-Ideal) mode, or with `a86', this section attempts to +outline the major differences between MASM's syntax and NASM's. If +you're not already used to MASM, it's probably worth skipping this +section. + +* Menu: + +* Section 2.2.1:: NASM Is Case-Sensitive +* Section 2.2.2:: NASM Requires Square Brackets For Memory References +* Section 2.2.3:: NASM Doesn't Store Variable Types +* Section 2.2.4:: NASM Doesn't `ASSUME' +* Section 2.2.5:: NASM Doesn't Support Memory Models +* Section 2.2.6:: Floating-Point Differences +* Section 2.2.7:: Other Differences + + +File: nasm.info, Node: Section 2.2.1, Next: Section 2.2.2, Prev: Section 2.2, Up: Section 2.2 + +2.2.1. NASM Is Case-Sensitive +----------------------------- + +One simple difference is that NASM is case-sensitive. It makes a +difference whether you call your label `foo', `Foo' or `FOO'. If you're +assembling to `DOS' or `OS/2' `.OBJ' files, you can invoke the +`UPPERCASE' directive (documented in *note Section 7.4::) to ensure +that all symbols exported to other code modules are forced to be upper +case; but even then, _within_ a single module, NASM will distinguish +between labels differing only in case. + + +File: nasm.info, Node: Section 2.2.2, Next: Section 2.2.3, Prev: Section 2.2.1, Up: Section 2.2 + +2.2.2. NASM Requires Square Brackets For Memory References +---------------------------------------------------------- + +NASM was designed with simplicity of syntax in mind. One of the design +goals of NASM is that it should be possible, as far as is practical, for +the user to look at a single line of NASM code and tell what opcode is +generated by it. You can't do this in MASM: if you declare, for example, + + foo equ 1 + bar dw 2 + + then the two lines of code + + mov ax,foo + mov ax,bar + + generate completely different opcodes, despite having +identical-looking syntaxes. + + NASM avoids this undesirable situation by having a much simpler +syntax for memory references. The rule is simply that any access to the +_contents_ of a memory location requires square brackets around the +address, and any access to the _address_ of a variable doesn't. So an +instruction of the form `mov ax,foo' will _always_ refer to a +compile-time constant, whether it's an `EQU' or the address of a +variable; and to access the _contents_ of the variable `bar', you must +code `mov ax,[bar]'. + + This also means that NASM has no need for MASM's `OFFSET' keyword, +since the MASM code `mov ax,offset bar' means exactly the same thing as +NASM's `mov ax,bar'. If you're trying to get large amounts of MASM code +to assemble sensibly under NASM, you can always code `%idefine offset' +to make the preprocessor treat the `OFFSET' keyword as a no-op. + + This issue is even more confusing in `a86', where declaring a label +with a trailing colon defines it to be a `label' as opposed to a +`variable' and causes `a86' to adopt NASM-style semantics; so in `a86', +`mov ax,var' has different behaviour depending on whether `var' was +declared as `var: dw 0' (a label) or `var dw 0' (a word-size variable). +NASM is very simple by comparison: _everything_ is a label. + + NASM, in the interests of simplicity, also does not support the +hybrid syntaxes supported by MASM and its clones, such as `mov +ax,table[bx]', where a memory reference is denoted by one portion +outside square brackets and another portion inside. The correct syntax +for the above is `mov ax,[table+bx]'. Likewise, `mov ax,es:[di]' is +wrong and `mov ax,[es:di]' is right. + + +File: nasm.info, Node: Section 2.2.3, Next: Section 2.2.4, Prev: Section 2.2.2, Up: Section 2.2 + +2.2.3. NASM Doesn't Store Variable Types +---------------------------------------- + +NASM, by design, chooses not to remember the types of variables you +declare. Whereas MASM will remember, on seeing `var dw 0', that you +declared `var' as a word-size variable, and will then be able to fill +in the ambiguity in the size of the instruction `mov var,2', NASM will +deliberately remember nothing about the symbol `var' except where it +begins, and so you must explicitly code `mov word [var],2'. + + For this reason, NASM doesn't support the `LODS', `MOVS', `STOS', +`SCAS', `CMPS', `INS', or `OUTS' instructions, but only supports the +forms such as `LODSB', `MOVSW', and `SCASD', which explicitly specify +the size of the components of the strings being manipulated. + + +File: nasm.info, Node: Section 2.2.4, Next: Section 2.2.5, Prev: Section 2.2.3, Up: Section 2.2 + +2.2.4. NASM Doesn't `ASSUME' +---------------------------- + +As part of NASM's drive for simplicity, it also does not support the +`ASSUME' directive. NASM will not keep track of what values you choose +to put in your segment registers, and will never _automatically_ +generate a segment override prefix. + + +File: nasm.info, Node: Section 2.2.5, Next: Section 2.2.6, Prev: Section 2.2.4, Up: Section 2.2 + +2.2.5. NASM Doesn't Support Memory Models +----------------------------------------- + +NASM also does not have any directives to support different 16-bit +memory models. The programmer has to keep track of which functions are +supposed to be called with a far call and which with a near call, and +is responsible for putting the correct form of `RET' instruction +(`RETN' or `RETF'; NASM accepts `RET' itself as an alternate form for +`RETN'); in addition, the programmer is responsible for coding CALL FAR +instructions where necessary when calling _external_ functions, and +must also keep track of which external variable definitions are far and +which are near. + + +File: nasm.info, Node: Section 2.2.6, Next: Section 2.2.7, Prev: Section 2.2.5, Up: Section 2.2 + +2.2.6. Floating-Point Differences +--------------------------------- + +NASM uses different names to refer to floating-point registers from +MASM: where MASM would call them `ST(0)', `ST(1)' and so on, and `a86' +would call them simply `0', `1' and so on, NASM chooses to call them +`st0', `st1' etc. + + As of version 0.96, NASM now treats the instructions with `nowait' +forms in the same way as MASM-compatible assemblers. The idiosyncratic +treatment employed by 0.95 and earlier was based on a misunderstanding +by the authors. + + +File: nasm.info, Node: Section 2.2.7, Next: Chapter 3, Prev: Section 2.2.6, Up: Section 2.2 + +2.2.7. Other Differences +------------------------ + +For historical reasons, NASM uses the keyword `TWORD' where MASM and +compatible assemblers use `TBYTE'. + + NASM does not declare uninitialized storage in the same way as MASM: +where a MASM programmer might use `stack db 64 dup (?)', NASM requires +`stack resb 64', intended to be read as `reserve 64 bytes'. For a +limited amount of compatibility, since NASM treats `?' as a valid +character in symbol names, you can code `? equ 0' and then writing `dw +?' will at least do something vaguely useful. `DUP' is still not a +supported syntax, however. + + In addition to all of this, macros and directives work completely +differently to MASM. See *note Chapter 4:: and *note Chapter 6:: for +further details. + + +File: nasm.info, Node: Chapter 3, Next: Section 3.1, Prev: Section 2.2.7, Up: Top + +Chapter 3: The NASM Language +**************************** + +* Menu: + +* Section 3.1:: Layout of a NASM Source Line +* Section 3.2:: Pseudo-Instructions +* Section 3.3:: Effective Addresses +* Section 3.4:: Constants +* Section 3.5:: Expressions +* Section 3.6:: `SEG' and `WRT' +* Section 3.7:: `STRICT': Inhibiting Optimization +* Section 3.8:: Critical Expressions +* Section 3.9:: Local Labels + + +File: nasm.info, Node: Section 3.1, Next: Section 3.2, Prev: Chapter 3, Up: Chapter 3 + +3.1. Layout of a NASM Source Line +================================= + +Like most assemblers, each NASM source line contains (unless it is a +macro, a preprocessor directive or an assembler directive: see *note +Chapter 4:: and *note Chapter 6::) some combination of the four fields + + label: instruction operands ; comment + + As usual, most of these fields are optional; the presence or absence +of any combination of a label, an instruction and a comment is allowed. +Of course, the operand field is either required or forbidden by the +presence and nature of the instruction field. + + NASM uses backslash (\) as the line continuation character; if a +line ends with backslash, the next line is considered to be a part of +the backslash- ended line. + + NASM places no restrictions on white space within a line: labels may +have white space before them, or instructions may have no space before +them, or anything. The colon after a label is also optional. (Note that +this means that if you intend to code `lodsb' alone on a line, and type +`lodab' by accident, then that's still a valid source line which does +nothing but define a label. Running NASM with the command-line option +`-w+orphan-labels' will cause it to warn you if you define a label +alone on a line without a trailing colon.) + + Valid characters in labels are letters, numbers, `_', `$', `#', `@', +`~', `.', and `?'. The only characters which may be used as the _first_ +character of an identifier are letters, `.' (with special meaning: see +*note Section 3.9::), `_' and `?'. An identifier may also be prefixed +with a `$' to indicate that it is intended to be read as an identifier +and not a reserved word; thus, if some other module you are linking +with defines a symbol called `eax', you can refer to `$eax' in NASM +code to distinguish the symbol from the register. Maximum length of an +identifier is 4095 characters. + + The instruction field may contain any machine instruction: Pentium +and P6 instructions, FPU instructions, MMX instructions and even +undocumented instructions are all supported. The instruction may be +prefixed by `LOCK', `REP', `REPE'/`REPZ' or `REPNE'/`REPNZ', in the +usual way. Explicit address-size and operand-size prefixes `A16', +`A32', `A64', `O16' and `O32', `O64' are provided - one example of +their use is given in *note Chapter 10::. You can also use the name of +a segment register as an instruction prefix: coding `es mov [bx],ax' is +equivalent to coding `mov [es:bx],ax'. We recommend the latter syntax, +since it is consistent with other syntactic features of the language, +but for instructions such as `LODSB', which has no operands and yet can +require a segment override, there is no clean syntactic way to proceed +apart from `es lodsb'. + + An instruction is not required to use a prefix: prefixes such as +`CS', `A32', `LOCK' or `REPE' can appear on a line by themselves, and +NASM will just generate the prefix bytes. + + In addition to actual machine instructions, NASM also supports a +number of pseudo-instructions, described in *note Section 3.2::. + + Instruction operands may take a number of forms: they can be +registers, described simply by the register name (e.g. `ax', `bp', +`ebx', `cr0': NASM does not use the `gas'-style syntax in which +register names must be prefixed by a `%' sign), or they can be +effective addresses (see *note Section 3.3::), constants (*note Section +3.4::) or expressions (*note Section 3.5::). + + For x87 floating-point instructions, NASM accepts a wide range of +syntaxes: you can use two-operand forms like MASM supports, or you can +use NASM's native single-operand forms in most cases. For example, you +can code: + + fadd st1 ; this sets st0 := st0 + st1 + fadd st0,st1 ; so does this + + fadd st1,st0 ; this sets st1 := st1 + st0 + fadd to st1 ; so does this + + Almost any x87 floating-point instruction that references memory +must use one of the prefixes `DWORD', `QWORD' or `TWORD' to indicate +what size of memory operand it refers to. + + +File: nasm.info, Node: Section 3.2, Next: Section 3.2.1, Prev: Section 3.1, Up: Chapter 3 + +3.2. Pseudo-Instructions +======================== + +Pseudo-instructions are things which, though not real x86 machine +instructions, are used in the instruction field anyway because that's +the most convenient place to put them. The current pseudo-instructions +are `DB', `DW', `DD', `DQ', `DT', `DO' and `DY'; their uninitialized +counterparts `RESB', `RESW', `RESD', `RESQ', `REST', `RESO' and `RESY'; +the `INCBIN' command, the `EQU' command, and the `TIMES' prefix. + +* Menu: + +* Section 3.2.1:: `DB' and Friends: Declaring Initialized Data +* Section 3.2.2:: `RESB' and Friends: Declaring Uninitialized Data +* Section 3.2.3:: `INCBIN': Including External Binary Files +* Section 3.2.4:: `EQU': Defining Constants +* Section 3.2.5:: `TIMES': Repeating Instructions or Data + + +File: nasm.info, Node: Section 3.2.1, Next: Section 3.2.2, Prev: Section 3.2, Up: Section 3.2 + +3.2.1. `DB' and Friends: Declaring Initialized Data +--------------------------------------------------- + +`DB', `DW', `DD', `DQ', `DT', `DO' and `DY' are used, much as in MASM, +to declare initialized data in the output file. They can be invoked in +a wide range of ways: + + db 0x55 ; just the byte 0x55 + db 0x55,0x56,0x57 ; three bytes in succession + db 'a',0x55 ; character constants are OK + db 'hello',13,10,'$' ; so are string constants + dw 0x1234 ; 0x34 0x12 + dw 'a' ; 0x61 0x00 (it's just a number) + dw 'ab' ; 0x61 0x62 (character constant) + dw 'abc' ; 0x61 0x62 0x63 0x00 (string) + dd 0x12345678 ; 0x78 0x56 0x34 0x12 + dd 1.234567e20 ; floating-point constant + dq 0x123456789abcdef0 ; eight byte constant + dq 1.234567e20 ; double-precision float + dt 1.234567e20 ; extended-precision float + + `DT', `DO' and `DY' do not accept numeric constants as operands. + + +File: nasm.info, Node: Section 3.2.2, Next: Section 3.2.3, Prev: Section 3.2.1, Up: Section 3.2 + +3.2.2. `RESB' and Friends: Declaring Uninitialized Data +------------------------------------------------------- + +`RESB', `RESW', `RESD', `RESQ', `REST', `RESO' and `RESY' are designed +to be used in the BSS section of a module: they declare _uninitialized_ +storage space. Each takes a single operand, which is the number of +bytes, words, doublewords or whatever to reserve. As stated in *note +Section 2.2.7::, NASM does not support the MASM/TASM syntax of +reserving uninitialized space by writing `DW ?' or similar things: this +is what it does instead. The operand to a `RESB'-type +pseudo-instruction is a _critical expression_: see *note Section 3.8::. + + For example: + + buffer: resb 64 ; reserve 64 bytes + wordvar: resw 1 ; reserve a word + realarray resq 10 ; array of ten reals + ymmval: resy 1 ; one YMM register + + +File: nasm.info, Node: Section 3.2.3, Next: Section 3.2.4, Prev: Section 3.2.2, Up: Section 3.2 + +3.2.3. `INCBIN': Including External Binary Files +------------------------------------------------ + +`INCBIN' is borrowed from the old Amiga assembler DevPac: it includes a +binary file verbatim into the output file. This can be handy for (for +example) including graphics and sound data directly into a game +executable file. It can be called in one of these three ways: + + incbin "file.dat" ; include the whole file + incbin "file.dat",1024 ; skip the first 1024 bytes + incbin "file.dat",1024,512 ; skip the first 1024, and + ; actually include at most 512 + + `INCBIN' is both a directive and a standard macro; the standard macro +version searches for the file in the include file search path and adds +the file to the dependency lists. This macro can be overridden if +desired. + + +File: nasm.info, Node: Section 3.2.4, Next: Section 3.2.5, Prev: Section 3.2.3, Up: Section 3.2 + +3.2.4. `EQU': Defining Constants +-------------------------------- + +`EQU' defines a symbol to a given constant value: when `EQU' is used, +the source line must contain a label. The action of `EQU' is to define +the given label name to the value of its (only) operand. This +definition is absolute, and cannot change later. So, for example, + + message db 'hello, world' + msglen equ $-message + + defines `msglen' to be the constant 12. `msglen' may not then be +redefined later. This is not a preprocessor definition either: the +value of `msglen' is evaluated _once_, using the value of `$' (see +*note Section 3.5:: for an explanation of `$') at the point of +definition, rather than being evaluated wherever it is referenced and +using the value of `$' at the point of reference. + + +File: nasm.info, Node: Section 3.2.5, Next: Section 3.3, Prev: Section 3.2.4, Up: Section 3.2 + +3.2.5. `TIMES': Repeating Instructions or Data +---------------------------------------------- + +The `TIMES' prefix causes the instruction to be assembled multiple +times. This is partly present as NASM's equivalent of the `DUP' syntax +supported by MASM-compatible assemblers, in that you can code + + zerobuf: times 64 db 0 + + or similar things; but `TIMES' is more versatile than that. The +argument to `TIMES' is not just a numeric constant, but a numeric +_expression_, so you can do things like + + buffer: db 'hello, world' + times 64-$+buffer db ' ' + + which will store exactly enough spaces to make the total length of +`buffer' up to 64. Finally, `TIMES' can be applied to ordinary +instructions, so you can code trivial unrolled loops in it: + + times 100 movsb + + Note that there is no effective difference between `times 100 resb 1' +and `resb 100', except that the latter will be assembled about 100 +times faster due to the internal structure of the assembler. + + The operand to `TIMES' is a critical expression (*note Section +3.8::). + + Note also that `TIMES' can't be applied to macros: the reason for +this is that `TIMES' is processed after the macro phase, which allows +the argument to `TIMES' to contain expressions such as `64-$+buffer' as +above. To repeat more than one line of code, or a complex macro, use the +preprocessor `%rep' directive. + + +File: nasm.info, Node: Section 3.3, Next: Section 3.4, Prev: Section 3.2.5, Up: Chapter 3 + +3.3. Effective Addresses +======================== + +An effective address is any operand to an instruction which references +memory. Effective addresses, in NASM, have a very simple syntax: they +consist of an expression evaluating to the desired address, enclosed in +square brackets. For example: + + wordvar dw 123 + mov ax,[wordvar] + mov ax,[wordvar+1] + mov ax,[es:wordvar+bx] + + Anything not conforming to this simple system is not a valid memory +reference in NASM, for example `es:wordvar[bx]'. + + More complicated effective addresses, such as those involving more +than one register, work in exactly the same way: + + mov eax,[ebx*2+ecx+offset] + mov ax,[bp+di+8] + + NASM is capable of doing algebra on these effective addresses, so +that things which don't necessarily _look_ legal are perfectly all +right: + + mov eax,[ebx*5] ; assembles as [ebx*4+ebx] + mov eax,[label1*2-label2] ; ie [label1+(label1-label2)] + + Some forms of effective address have more than one assembled form; +in most such cases NASM will generate the smallest form it can. For +example, there are distinct assembled forms for the 32-bit effective +addresses `[eax*2+0]' and `[eax+eax]', and NASM will generally generate +the latter on the grounds that the former requires four bytes to store +a zero offset. + + NASM has a hinting mechanism which will cause `[eax+ebx]' and +`[ebx+eax]' to generate different opcodes; this is occasionally useful +because `[esi+ebp]' and `[ebp+esi]' have different default segment +registers. + + However, you can force NASM to generate an effective address in a +particular form by the use of the keywords `BYTE', `WORD', `DWORD' and +`NOSPLIT'. If you need `[eax+3]' to be assembled using a double-word +offset field instead of the one byte NASM will normally generate, you +can code `[dword eax+3]'. Similarly, you can force NASM to use a byte +offset for a small value which it hasn't seen on the first pass (see +*note Section 3.8:: for an example of such a code fragment) by using +`[byte eax+offset]'. As special cases, `[byte eax]' will code `[eax+0]' +with a byte offset of zero, and `[dword eax]' will code it with a +double-word offset of zero. The normal form, `[eax]', will be coded +with no offset field. + + The form described in the previous paragraph is also useful if you +are trying to access data in a 32-bit segment from within 16 bit code. +For more information on this see the section on mixed-size addressing +(*note Section 10.2::). In particular, if you need to access data with +a known offset that is larger than will fit in a 16-bit value, if you +don't specify that it is a dword offset, nasm will cause the high word +of the offset to be lost. + + Similarly, NASM will split `[eax*2]' into `[eax+eax]' because that +allows the offset field to be absent and space to be saved; in fact, it +will also split `[eax*2+offset]' into `[eax+eax+offset]'. You can +combat this behaviour by the use of the `NOSPLIT' keyword: `[nosplit +eax*2]' will force `[eax*2+0]' to be generated literally. + + In 64-bit mode, NASM will by default generate absolute addresses. The +`REL' keyword makes it produce `RIP'-relative addresses. Since this is +frequently the normally desired behaviour, see the `DEFAULT' directive +(*note Section 6.2::). The keyword `ABS' overrides `REL'. + + +File: nasm.info, Node: Section 3.4, Next: Section 3.4.1, Prev: Section 3.3, Up: Chapter 3 + +3.4. Constants +============== + +NASM understands four different types of constant: numeric, character, +string and floating-point. + +* Menu: + +* Section 3.4.1:: Numeric Constants +* Section 3.4.2:: Character Strings +* Section 3.4.3:: Character Constants +* Section 3.4.4:: String Constants +* Section 3.4.5:: Unicode Strings +* Section 3.4.6:: Floating-Point Constants +* Section 3.4.7:: Packed BCD Constants + + +File: nasm.info, Node: Section 3.4.1, Next: Section 3.4.2, Prev: Section 3.4, Up: Section 3.4 + +3.4.1. Numeric Constants +------------------------ + +A numeric constant is simply a number. NASM allows you to specify +numbers in a variety of number bases, in a variety of ways: you can +suffix `H' or `X', `Q' or `O', and `B' for hexadecimal, octal and +binary respectively, or you can prefix `0x' for hexadecimal in the +style of C, or you can prefix `$' for hexadecimal in the style of +Borland Pascal. Note, though, that the `$' prefix does double duty as a +prefix on identifiers (see *note Section 3.1::), so a hex number +prefixed with a `$' sign must have a digit after the `$' rather than a +letter. In addition, current versions of NASM accept the prefix `0h' +for hexadecimal, `0o' or `0q' for octal, and `0b' for binary. Please +note that unlike C, a `0' prefix by itself does _not_ imply an octal +constant! + + Numeric constants can have underscores (`_') interspersed to break up +long strings. + + Some examples (all producing exactly the same code): + + mov ax,200 ; decimal + mov ax,0200 ; still decimal + mov ax,0200d ; explicitly decimal + mov ax,0d200 ; also decimal + mov ax,0c8h ; hex + mov ax,$0c8 ; hex again: the 0 is required + mov ax,0xc8 ; hex yet again + mov ax,0hc8 ; still hex + mov ax,310q ; octal + mov ax,310o ; octal again + mov ax,0o310 ; octal yet again + mov ax,0q310 ; hex yet again + mov ax,11001000b ; binary + mov ax,1100_1000b ; same binary constant + mov ax,0b1100_1000 ; same binary constant yet again + + +File: nasm.info, Node: Section 3.4.2, Next: Section 3.4.3, Prev: Section 3.4.1, Up: Section 3.4 + +3.4.2. Character Strings +------------------------ + +A character string consists of up to eight characters enclosed in either +single quotes (`'...''), double quotes (`"..."') or backquotes +(``...`'). Single or double quotes are equivalent to NASM (except of +course that surrounding the constant with single quotes allows double +quotes to appear within it and vice versa); the contents of those are +represented verbatim. Strings enclosed in backquotes support C-style +`\'-escapes for special characters. + + The following escape sequences are recognized by backquoted strings: + + \' single quote (') + \" double quote (") + \` backquote (`) + \\ backslash (\) + \? question mark (?) + \a BEL (ASCII 7) + \b BS (ASCII 8) + \t TAB (ASCII 9) + \n LF (ASCII 10) + \v VT (ASCII 11) + \f FF (ASCII 12) + \r CR (ASCII 13) + \e ESC (ASCII 27) + \377 Up to 3 octal digits - literal byte + \xFF Up to 2 hexadecimal digits - literal byte + \u1234 4 hexadecimal digits - Unicode character + \U12345678 8 hexadecimal digits - Unicode character + + All other escape sequences are reserved. Note that `\0', meaning a +`NUL' character (ASCII 0), is a special case of the octal escape +sequence. + + Unicode characters specified with `\u' or `\U' are converted to +UTF-8. For example, the following lines are all equivalent: + + db `\u263a` ; UTF-8 smiley face + db `\xe2\x98\xba` ; UTF-8 smiley face + db 0E2h, 098h, 0BAh ; UTF-8 smiley face + + +File: nasm.info, Node: Section 3.4.3, Next: Section 3.4.4, Prev: Section 3.4.2, Up: Section 3.4 + +3.4.3. Character Constants +-------------------------- + +A character constant consists of a string up to eight bytes long, used +in an expression context. It is treated as if it was an integer. + + A character constant with more than one byte will be arranged with +little-endian order in mind: if you code + + mov eax,'abcd' + + then the constant generated is not `0x61626364', but `0x64636261', +so that if you were then to store the value into memory, it would read +`abcd' rather than `dcba'. This is also the sense of character +constants understood by the Pentium's `CPUID' instruction. + + +File: nasm.info, Node: Section 3.4.4, Next: Section 3.4.5, Prev: Section 3.4.3, Up: Section 3.4 + +3.4.4. String Constants +----------------------- + +String constants are character strings used in the context of some +pseudo- instructions, namely the `DB' family and `INCBIN' (where it +represents a filename.) They are also used in certain preprocessor +directives. + + A string constant looks like a character constant, only longer. It is +treated as a concatenation of maximum-size character constants for the +conditions. So the following are equivalent: + + db 'hello' ; string constant + db 'h','e','l','l','o' ; equivalent character constants + + And the following are also equivalent: + + dd 'ninechars' ; doubleword string constant + dd 'nine','char','s' ; becomes three doublewords + db 'ninechars',0,0,0 ; and really looks like this + + Note that when used in a string-supporting context, quoted strings +are treated as a string constants even if they are short enough to be a +character constant, because otherwise `db 'ab'' would have the same +effect as `db 'a'', which would be silly. Similarly, three-character or +four-character constants are treated as strings when they are operands +to `DW', and so forth. + + +File: nasm.info, Node: Section 3.4.5, Next: Section 3.4.6, Prev: Section 3.4.4, Up: Section 3.4 + +3.4.5. Unicode Strings +---------------------- + +The special operators `__utf16__' and `__utf32__' allows definition of +Unicode strings. They take a string in UTF-8 format and converts it to +(littleendian) UTF-16 or UTF-32, respectively. + + For example: + + %define u(x) __utf16__(x) + %define w(x) __utf32__(x) + + dw u('C:\WINDOWS'), 0 ; Pathname in UTF-16 + dd w(`A + B = \u206a`), 0 ; String in UTF-32 + + `__utf16__' and `__utf32__' can be applied either to strings passed +to the `DB' family instructions, or to character constants in an +expression context. + + +File: nasm.info, Node: Section 3.4.6, Next: Section 3.4.7, Prev: Section 3.4.5, Up: Section 3.4 + +3.4.6. Floating-Point Constants +------------------------------- + +Floating-point constants are acceptable only as arguments to `DB', +`DW', `DD', `DQ', `DT', and `DO', or as arguments to the special +operators `__float8__', `__float16__', `__float32__', `__float64__', +`__float80m__', `__float80e__', `__float128l__', and `__float128h__'. + + Floating-point constants are expressed in the traditional form: +digits, then a period, then optionally more digits, then optionally an +`E' followed by an exponent. The period is mandatory, so that NASM can +distinguish between `dd 1', which declares an integer constant, and `dd +1.0' which declares a floating-point constant. NASM also support +C99-style hexadecimal floating-point: `0x', hexadecimal digits, period, +optionally more hexadeximal digits, then optionally a `P' followed by a +_binary_ (not hexadecimal) exponent in decimal notation. + + Underscores to break up groups of digits are permitted in +floating-point constants as well. + + Some examples: + + db -0.2 ; "Quarter precision" + dw -0.5 ; IEEE 754r/SSE5 half precision + dd 1.2 ; an easy one + dd 1.222_222_222 ; underscores are permitted + dd 0x1p+2 ; 1.0x2^2 = 4.0 + dq 0x1p+32 ; 1.0x2^32 = 4 294 967 296.0 + dq 1.e10 ; 10 000 000 000.0 + dq 1.e+10 ; synonymous with 1.e10 + dq 1.e-10 ; 0.000 000 000 1 + dt 3.141592653589793238462 ; pi + do 1.e+4000 ; IEEE 754r quad precision + + The 8-bit "quarter-precision" floating-point format is +sign:exponent:mantissa = 1:4:3 with an exponent bias of 7. This appears +to be the most frequently used 8-bit floating-point format, although it +is not covered by any formal standard. This is sometimes called a +"minifloat." + + The special operators are used to produce floating-point numbers in +other contexts. They produce the binary representation of a specific +floating- point number as an integer, and can use anywhere integer +constants are used in an expression. `__float80m__' and `__float80e__' +produce the 64-bit mantissa and 16-bit exponent of an 80-bit +floating-point number, and `__float128l__' and `__float128h__' produce +the lower and upper 64-bit halves of a 128-bit floating-point number, +respectively. + + For example: + + mov rax,__float64__(3.141592653589793238462) + + ... would assign the binary representation of pi as a 64-bit +floating point number into `RAX'. This is exactly equivalent to: + + mov rax,0x400921fb54442d18 + + NASM cannot do compile-time arithmetic on floating-point constants. +This is because NASM is designed to be portable - although it always +generates code to run on x86 processors, the assembler itself can run +on any system with an ANSI C compiler. Therefore, the assembler cannot +guarantee the presence of a floating-point unit capable of handling the +Intel number formats, and so for NASM to be able to do floating +arithmetic it would have to include its own complete set of +floating-point routines, which would significantly increase the size of +the assembler for very little benefit. + + The special tokens `__Infinity__', `__QNaN__' (or `__NaN__') and +`__SNaN__' can be used to generate infinities, quiet NaNs, and +signalling NaNs, respectively. These are normally used as macros: + + %define Inf __Infinity__ + %define NaN __QNaN__ + + dq +1.5, -Inf, NaN ; Double-precision constants + + +File: nasm.info, Node: Section 3.4.7, Next: Section 3.5, Prev: Section 3.4.6, Up: Section 3.4 + +3.4.7. Packed BCD Constants +--------------------------- + +x87-style packed BCD constants can be used in the same contexts as +80-bit floating-point numbers. They are suffixed with `p' or prefixed +with `0p', and can include up to 18 decimal digits. + + As with other numeric constants, underscores can be used to separate +digits. + + For example: + + dt 12_345_678_901_245_678p + dt -12_345_678_901_245_678p + dt +0p33 + dt 33p + + +File: nasm.info, Node: Section 3.5, Next: Section 3.5.1, Prev: Section 3.4.7, Up: Chapter 3 + +3.5. Expressions +================ + +Expressions in NASM are similar in syntax to those in C. Expressions are +evaluated as 64-bit integers which are then adjusted to the appropriate +size. + + NASM supports two special tokens in expressions, allowing +calculations to involve the current assembly position: the `$' and `$$' +tokens. `$' evaluates to the assembly position at the beginning of the +line containing the expression; so you can code an infinite loop using +`JMP $'. `$$' evaluates to the beginning of the current section; so you +can tell how far into the section you are by using `($-$$)'. + + The arithmetic operators provided by NASM are listed here, in +increasing order of precedence. + +* Menu: + +* Section 3.5.1:: `|': Bitwise OR Operator +* Section 3.5.2:: `^': Bitwise XOR Operator +* Section 3.5.3:: `&': Bitwise AND Operator +* Section 3.5.4:: `<<' and `>>': Bit Shift Operators +* Section 3.5.5:: `+' and `-': Addition and Subtraction Operators +* Section 3.5.6:: `*', `/', `//', `%' and `%%': Multiplication and Division +* Section 3.5.7:: Unary Operators: `+', `-', `~', `!' and `SEG' + + +File: nasm.info, Node: Section 3.5.1, Next: Section 3.5.2, Prev: Section 3.5, Up: Section 3.5 + +3.5.1. `|': Bitwise OR Operator +------------------------------- + +The `|' operator gives a bitwise OR, exactly as performed by the `OR' +machine instruction. Bitwise OR is the lowest-priority arithmetic +operator supported by NASM. + + +File: nasm.info, Node: Section 3.5.2, Next: Section 3.5.3, Prev: Section 3.5.1, Up: Section 3.5 + +3.5.2. `^': Bitwise XOR Operator +-------------------------------- + +`^' provides the bitwise XOR operation. + + +File: nasm.info, Node: Section 3.5.3, Next: Section 3.5.4, Prev: Section 3.5.2, Up: Section 3.5 + +3.5.3. `&': Bitwise AND Operator +-------------------------------- + +`&' provides the bitwise AND operation. + + +File: nasm.info, Node: Section 3.5.4, Next: Section 3.5.5, Prev: Section 3.5.3, Up: Section 3.5 + +3.5.4. `<<' and `>>': Bit Shift Operators +----------------------------------------- + +`<<' gives a bit-shift to the left, just as it does in C. So `5<<3' +evaluates to 5 times 8, or 40. `>>' gives a bit-shift to the right; in +NASM, such a shift is _always_ unsigned, so that the bits shifted in +from the left-hand end are filled with zero rather than a +sign-extension of the previous highest bit. + + +File: nasm.info, Node: Section 3.5.5, Next: Section 3.5.6, Prev: Section 3.5.4, Up: Section 3.5 + +3.5.5. `+' and `-': Addition and Subtraction Operators +------------------------------------------------------ + +The `+' and `-' operators do perfectly ordinary addition and +subtraction. + + +File: nasm.info, Node: Section 3.5.6, Next: Section 3.5.7, Prev: Section 3.5.5, Up: Section 3.5 + +3.5.6. `*', `/', `//', `%' and `%%': Multiplication and Division +---------------------------------------------------------------- + +`*' is the multiplication operator. `/' and `//' are both division +operators: `/' is unsigned division and `//' is signed division. +Similarly, `%' and `%%' provide unsigned and signed modulo operators +respectively. + + NASM, like ANSI C, provides no guarantees about the sensible +operation of the signed modulo operator. + + Since the `%' character is used extensively by the macro +preprocessor, you should ensure that both the signed and unsigned +modulo operators are followed by white space wherever they appear. + + +File: nasm.info, Node: Section 3.5.7, Next: Section 3.6, Prev: Section 3.5.6, Up: Section 3.5 + +3.5.7. Unary Operators: `+', `-', `~', `!' and `SEG' +---------------------------------------------------- + +The highest-priority operators in NASM's expression grammar are those +which only apply to one argument. `-' negates its operand, `+' does +nothing (it's provided for symmetry with `-'), `~' computes the one's +complement of its operand, `!' is the logical negation operator, and +`SEG' provides the segment address of its operand (explained in more +detail in *note Section 3.6::). + + +File: nasm.info, Node: Section 3.6, Next: Section 3.7, Prev: Section 3.5.7, Up: Chapter 3 + +3.6. `SEG' and `WRT' +==================== + +When writing large 16-bit programs, which must be split into multiple +segments, it is often necessary to be able to refer to the segment part +of the address of a symbol. NASM supports the `SEG' operator to perform +this function. + + The `SEG' operator returns the _preferred_ segment base of a symbol, +defined as the segment base relative to which the offset of the symbol +makes sense. So the code + + mov ax,seg symbol + mov es,ax + mov bx,symbol + + will load `ES:BX' with a valid pointer to the symbol `symbol'. + + Things can be more complex than this: since 16-bit segments and +groups may overlap, you might occasionally want to refer to some symbol +using a different segment base from the preferred one. NASM lets you do +this, by the use of the `WRT' (With Reference To) keyword. So you can +do things like + + mov ax,weird_seg ; weird_seg is a segment base + mov es,ax + mov bx,symbol wrt weird_seg + + to load `ES:BX' with a different, but functionally equivalent, +pointer to the symbol `symbol'. + + NASM supports far (inter-segment) calls and jumps by means of the +syntax `call segment:offset', where `segment' and `offset' both +represent immediate values. So to call a far procedure, you could code +either of + + call (seg procedure):procedure + call weird_seg:(procedure wrt weird_seg) + + (The parentheses are included for clarity, to show the intended +parsing of the above instructions. They are not necessary in practice.) + + NASM supports the syntax `call far procedure' as a synonym for the +first of the above usages. `JMP' works identically to `CALL' in these +examples. + + To declare a far pointer to a data item in a data segment, you must +code + + dw symbol, seg symbol + + NASM supports no convenient synonym for this, though you can always +invent one using the macro processor. + + +File: nasm.info, Node: Section 3.7, Next: Section 3.8, Prev: Section 3.6, Up: Chapter 3 + +3.7. `STRICT': Inhibiting Optimization +====================================== + +When assembling with the optimizer set to level 2 or higher (see *note +Section 2.1.22::), NASM will use size specifiers (`BYTE', `WORD', +`DWORD', `QWORD', `TWORD', `OWORD' or `YWORD'), but will give them the +smallest possible size. The keyword `STRICT' can be used to inhibit +optimization and force a particular operand to be emitted in the +specified size. For example, with the optimizer on, and in `BITS 16' +mode, + + push dword 33 + + is encoded in three bytes `66 6A 21', whereas + + push strict dword 33 + + is encoded in six bytes, with a full dword immediate operand `66 68 +21 00 00 00'. + + With the optimizer off, the same code (six bytes) is generated +whether the `STRICT' keyword was used or not. + + +File: nasm.info, Node: Section 3.8, Next: Section 3.9, Prev: Section 3.7, Up: Chapter 3 + +3.8. Critical Expressions +========================= + +Although NASM has an optional multi-pass optimizer, there are some +expressions which must be resolvable on the first pass. These are called +_Critical Expressions_. + + The first pass is used to determine the size of all the assembled +code and data, so that the second pass, when generating all the code, +knows all the symbol addresses the code refers to. So one thing NASM +can't handle is code whose size depends on the value of a symbol +declared after the code in question. For example, + + times (label-$) db 0 + label: db 'Where am I?' + + The argument to `TIMES' in this case could equally legally evaluate +to anything at all; NASM will reject this example because it cannot +tell the size of the `TIMES' line when it first sees it. It will just +as firmly reject the slightly paradoxical code + + times (label-$+1) db 0 + label: db 'NOW where am I?' + + in which _any_ value for the `TIMES' argument is by definition wrong! + + NASM rejects these examples by means of a concept called a _critical +expression_, which is defined to be an expression whose value is +required to be computable in the first pass, and which must therefore +depend only on symbols defined before it. The argument to the `TIMES' +prefix is a critical expression. + + +File: nasm.info, Node: Section 3.9, Next: Chapter 4, Prev: Section 3.8, Up: Chapter 3 + +3.9. Local Labels +================= + +NASM gives special treatment to symbols beginning with a period. A label +beginning with a single period is treated as a _local_ label, which +means that it is associated with the previous non-local label. So, for +example: + + label1 ; some code + + .loop + ; some more code + + jne .loop + ret + + label2 ; some code + + .loop + ; some more code + + jne .loop + ret + + In the above code fragment, each `JNE' instruction jumps to the line +immediately before it, because the two definitions of `.loop' are kept +separate by virtue of each being associated with the previous non-local +label. + + This form of local label handling is borrowed from the old Amiga +assembler DevPac; however, NASM goes one step further, in allowing +access to local labels from other parts of the code. This is achieved +by means of _defining_ a local label in terms of the previous non-local +label: the first definition of `.loop' above is really defining a +symbol called `label1.loop', and the second defines a symbol called +`label2.loop'. So, if you really needed to, you could write + + label3 ; some more code + ; and some more + + jmp label1.loop + + Sometimes it is useful - in a macro, for instance - to be able to +define a label which can be referenced from anywhere but which doesn't +interfere with the normal local-label mechanism. Such a label can't be +non-local because it would interfere with subsequent definitions of, +and references to, local labels; and it can't be local because the +macro that defined it wouldn't know the label's full name. NASM +therefore introduces a third type of label, which is probably only +useful in macro definitions: if a label begins with the special prefix +`..@', then it does nothing to the local label mechanism. So you could +code + + label1: ; a non-local label + .local: ; this is really label1.local + ..@foo: ; this is a special symbol + label2: ; another non-local label + .local: ; this is really label2.local + + jmp ..@foo ; this will jump three lines up + + NASM has the capacity to define other special symbols beginning with +a double period: for example, `..start' is used to specify the entry +point in the `obj' output format (see *note Section 7.4.6::). + + +File: nasm.info, Node: Chapter 4, Next: Section 4.1, Prev: Section 3.9, Up: Top + +Chapter 4: The NASM Preprocessor +******************************** + +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 `%' sign. + + 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. + +* Menu: + +* Section 4.1:: Single-Line Macros +* Section 4.2:: String Manipulation in Macros +* Section 4.3:: Multi-Line Macros: `%macro' +* Section 4.4:: Conditional Assembly +* Section 4.5:: Preprocessor Loops: `%rep' +* Section 4.6:: Source Files and Dependencies +* Section 4.7:: The Context Stack +* Section 4.8:: Stack Relative Preprocessor Directives +* Section 4.9:: Reporting User-Defined Errors: `%error', `%warning', `%fatal' +* Section 4.10:: Other Preprocessor Directives +* Section 4.11:: Standard Macros + + +File: nasm.info, Node: Section 4.1, Next: Section 4.1.1, Prev: Chapter 4, Up: Chapter 4 + +4.1. Single-Line Macros +======================= + +* Menu: + +* Section 4.1.1:: The Normal Way: `%define' +* Section 4.1.2:: Resolving `%define': `%xdefine' +* Section 4.1.3:: Macro Indirection: `%[...]' +* Section 4.1.4:: Concatenating Single Line Macro Tokens: `%+' +* Section 4.1.5:: The Macro Name Itself: `%?' and `%??' +* Section 4.1.6:: Undefining Single-Line Macros: `%undef' +* Section 4.1.7:: Preprocessor Variables: `%assign' +* Section 4.1.8:: Defining Strings: `%defstr' +* Section 4.1.9:: Defining Tokens: `%deftok' + + +File: nasm.info, Node: Section 4.1.1, Next: Section 4.1.2, Prev: Section 4.1, Up: Section 4.1 + +4.1.1. The Normal Way: `%define' +-------------------------------- + +Single-line macros are defined using the `%define' preprocessor +directive. The definitions work in a similar way to C; so you can do +things like + + %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 `mov ax,1+2*8', even though the +macro `b' wasn't defined at the time of definition of `a'. + + Macros defined with `%define' are case sensitive: after `%define foo +bar', only `foo' will expand to `bar': `Foo' or `FOO' will not. By +using `%idefine' instead of `%define' (the `i' stands for +`insensitive') you can define all the case variants of a macro at once, +so that `%idefine foo bar' would cause `foo', `Foo', `FOO', `fOO' and +so on all to expand to `bar'. + + 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 `a(3)' will expand once, becoming `1+a(3)', and will then +expand no further. This behaviour can be useful: see *note Section 9.1:: +for an example of its use. + + 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 `foo(3)' will become `1+3' whereas +`foo(ebx,2)' will become `1+ebx*2'. However, if you define + + %define foo bar + + then no other definition of `foo' will be accepted: a macro with no +parameters prohibits the definition of the same name as a macro _with_ +parameters, and vice versa. + + 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 `foo' is invoked, it will be expanded +according to the most recent definition. This is particularly useful +when defining single-line macros with `%assign' (see *note Section +4.1.7::). + + You can pre-define single-line macros using the `-d' option on the +NASM command line: see *note Section 2.1.18::. + + +File: nasm.info, Node: Section 4.1.2, Next: Section 4.1.3, Prev: Section 4.1.1, Up: Section 4.1 + +4.1.2. Resolving `%define': `%xdefine' +-------------------------------------- + +To have a reference to an embedded single-line macro resolved at the +time that the embedding macro is _defined_, as opposed to when the +embedding macro is _expanded_, you need a different mechanism to the +one offered by `%define'. The solution is to use `%xdefine', or it's +case-insensitive counterpart `%ixdefine'. + + 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, `val1' is equal to 0, and `val2' is equal to 1. This +is because, when a single-line macro is defined using `%define', it is +expanded only when it is called. As `isFalse' expands to `isTrue', the +expansion will be the current value of `isTrue'. The first time it is +called that is 0, and the second time it is 1. + + If you wanted `isFalse' to expand to the value assigned to the +embedded macro `isTrue' at the time that `isFalse' was defined, you +need to change the above code to use `%xdefine'. + + %xdefine isTrue 1 + %xdefine isFalse isTrue + %xdefine isTrue 0 + + val1: db isFalse + + %xdefine isTrue 1 + + val2: db isFalse + + Now, each time that `isFalse' is called, it expands to 1, as that is +what the embedded macro `isTrue' expanded to at the time that `isFalse' +was defined. + + +File: nasm.info, Node: Section 4.1.3, Next: Section 4.1.4, Prev: Section 4.1.2, Up: Section 4.1 + +4.1.3. Macro Indirection: `%[...]' +---------------------------------- + +The `%[...]' construct can be used to expand macros in contexts where +macro expansion would otherwise not occur, including in the names other +macros. For example, if you have a set of macros named `Foo16', `Foo32' +and `Foo64', you could write: + + mov ax,Foo%[__BITS__] ; The Foo value + + to use the builtin macro `__BITS__' (see *note Section 4.11.5::) to +automatically select between them. Similarly, the two statements: + + %xdefine Bar Quux ; Expands due to %xdefine + %define Bar %[Quux] ; Expands due to %[...] + + have, in fact, exactly the same effect. + + `%[...]' concatenates to adjacent tokens in the same way that multi- +line macro parameters do, see *note Section 4.3.8:: for details. + + +File: nasm.info, Node: Section 4.1.4, Next: Section 4.1.5, Prev: Section 4.1.3, Up: Section 4.1 + +4.1.4. Concatenating Single Line Macro Tokens: `%+' +--------------------------------------------------- + +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 `%+', in order to +disambiguate it from the syntax `%+1' used in multiline macros. + + 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). + + +File: nasm.info, Node: Section 4.1.5, Next: Section 4.1.6, Prev: Section 4.1.4, Up: Section 4.1 + +4.1.5. The Macro Name Itself: `%?' and `%??' +-------------------------------------------- + +The special symbols `%?' and `%??' can be used to reference the macro +name itself inside a macro expansion, this is supported for both +single-and multi-line macros. `%?' refers to the macro name as +_invoked_, whereas `%??' refers to the macro name as _declared_. The +two are always the same for case-sensitive macros, but for +case-insensitive macros, they can differ. + + 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 + + +File: nasm.info, Node: Section 4.1.6, Next: Section 4.1.7, Prev: Section 4.1.5, Up: Section 4.1 + +4.1.6. Undefining Single-Line Macros: `%undef' +---------------------------------------------- + +Single-line macros can be removed with the `%undef' directive. For +example, the following sequence: + + %define foo bar + %undef foo + + mov eax, foo + + will expand to the instruction `mov eax, foo', since after `%undef' +the macro `foo' is no longer defined. + + Macros that would otherwise be pre-defined can be undefined on the +command- line using the `-u' option on the NASM command line: see *note +Section 2.1.19::. + + +File: nasm.info, Node: Section 4.1.7, Next: Section 4.1.8, Prev: Section 4.1.6, Up: Section 4.1 + +4.1.7. Preprocessor Variables: `%assign' +---------------------------------------- + +An alternative way to define single-line macros is by means of the +`%assign' command (and its case-insensitive counterpart `%iassign', +which differs from `%assign' in exactly the same way that `%idefine' +differs from `%define'). + + `%assign' is used to define single-line macros which take no +parameters and have a numeric value. This value can be specified in the +form of an expression, and it will be evaluated once, when the +`%assign' directive is processed. + + Like `%define', macros defined using `%assign' can be re-defined +later, so you can do things like + + %assign i i+1 + + to increment the numeric value of a macro. + + `%assign' is useful for controlling the termination of `%rep' +preprocessor loops: see *note Section 4.5:: for an example of this. +Another use for `%assign' is given in *note Section 8.4:: and *note +Section 9.1::. + + The expression passed to `%assign' is a critical expression (see +*note Section 3.8::), and must also evaluate to a pure number (rather +than a relocatable reference such as a code or data address, or +anything involving a register). + + +File: nasm.info, Node: Section 4.1.8, Next: Section 4.1.9, Prev: Section 4.1.7, Up: Section 4.1 + +4.1.8. Defining Strings: `%defstr' +---------------------------------- + +`%defstr', and its case-insensitive counterpart `%idefstr', define or +redefine a single-line macro without parameters but converts the entire +right-hand side, after macro expansion, to a quoted string before +definition. + + For example: + + %defstr test TEST + + is equivalent to + + %define test 'TEST' + + This can be used, for example, with the `%!' construct (see *note +Section 4.10.2::): + + %defstr PATH %!PATH ; The operating system PATH variable + + +File: nasm.info, Node: Section 4.1.9, Next: Section 4.2, Prev: Section 4.1.8, Up: Section 4.1 + +4.1.9. Defining Tokens: `%deftok' +--------------------------------- + +`%deftok', and its case-insensitive counterpart `%ideftok', define or +redefine a single-line macro without parameters but converts the second +parameter, after string conversion, to a sequence of tokens. + + For example: + + %deftok test 'TEST' + + is equivalent to + + %define test TEST + + +File: nasm.info, Node: Section 4.2, Next: Section 4.2.1, Prev: Section 4.1.9, Up: Chapter 4 + +4.2. String Manipulation in Macros +================================== + +It's often useful to be able to handle strings in macros. NASM supports +a few 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. When producing a string +value, it may change the style of quoting of the input string or +strings, and possibly use `\'-escapes inside ``'-quoted strings. + +* Menu: + +* Section 4.2.1:: Concatenating Strings: `%strcat' +* Section 4.2.2:: String Length: `%strlen' +* Section 4.2.3:: Extracting Substrings: `%substr' + + +File: nasm.info, Node: Section 4.2.1, Next: Section 4.2.2, Prev: Section 4.2, Up: Section 4.2 + +4.2.1. Concatenating Strings: `%strcat' +--------------------------------------- + +The `%strcat' operator concatenates quoted strings and assign them to a +single-line macro. + + For example: + + %strcat alpha "Alpha: ", '12" screen' + + ... would assign the value `'Alpha: 12" screen'' to `alpha'. +Similarly: + + %strcat beta '"foo"\', "'bar'" + + ... would assign the value ``"foo"\\'bar'`' to `beta'. + + The use of commas to separate strings is permitted but optional. + + +File: nasm.info, Node: Section 4.2.2, Next: Section 4.2.3, Prev: Section 4.2.1, Up: Section 4.2 + +4.2.2. String Length: `%strlen' +------------------------------- + +The `%strlen' operator assigns the length of a string to a macro. For +example: + + %strlen charcnt 'my string' + + In this example, `charcnt' would receive the value 9, just as if an +`%assign' had been used. In this example, `'my string'' was a literal +string but it could also have been a single-line macro that expands to +a string, as in the following example: + + %define sometext 'my string' + %strlen charcnt sometext + + As in the first case, this would result in `charcnt' being assigned +the value of 9. + + +File: nasm.info, Node: Section 4.2.3, Next: Section 4.3, Prev: Section 4.2.2, Up: Section 4.2 + +4.2.3. Extracting Substrings: `%substr' +--------------------------------------- + +Individual letters or substrings in strings can be extracted using the +`%substr' operator. An example of its use is probably more useful than +the description: + + %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 `%strlen' (see *note Section 4.2.2::), the first parameter is +the single-line macro to be created and the second is the string. The +third parameter specifies the first character to be selected, and the +optional fourth parameter preceeded by comma) is the length. Note that +the first index is 1, not 0 and the last index is equal to the value +that `%strlen' would assign given the same string. Index values out of +range result in an empty string. A negative length means "until N-1 +characters before the end of string", i.e. `-1' means until end of +string, `-2' until one character before, etc. + + +File: nasm.info, Node: Section 4.3, Next: Section 4.3.1, Prev: Section 4.2.3, Up: Chapter 4 + +4.3. Multi-Line Macros: `%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 `1' after the macro name in the `%macro' line defines the +number of parameters the macro `prologue' expects to receive. The use +of `%1' inside the macro definition refers to the first parameter to +the macro call. With a macro taking more than one parameter, subsequent +parameters would be referred to as `%2', `%3' and so on. + + Multi-line macros, like single-line macros, are case-sensitive, +unless you define them using the alternative directive `%imacro'. + + 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 + +* Menu: + +* Section 4.3.1:: Recursive Multi-Line Macros: `%rmacro' +* Section 4.3.2:: Overloading Multi-Line Macros +* Section 4.3.3:: Macro-Local Labels +* Section 4.3.4:: Greedy Macro Parameters +* Section 4.3.5:: Default Macro Parameters +* Section 4.3.6:: `%0': Macro Parameter Counter +* Section 4.3.7:: `%rotate': Rotating Macro Parameters +* Section 4.3.8:: Concatenating Macro Parameters +* Section 4.3.9:: Condition Codes as Macro Parameters +* Section 4.3.10:: Disabling Listing Expansion +* Section 4.3.11:: Undefining Multi-Line Macros: `%unmacro' +* Section 4.3.12:: Exiting Multi-Line Macros: `%exitmacro' + + +File: nasm.info, Node: Section 4.3.1, Next: Section 4.3.2, Prev: Section 4.3, Up: Section 4.3 + +4.3.1. Recursive Multi-Line Macros: `%rmacro' +--------------------------------------------- + +A multi-line macro cannot be referenced within itself, in order to +prevent accidental infinite recursion. + + Recursive multi-line macros allow for self-referencing, with the +caveat that the user is aware of the existence, use and purpose of +recursive multi-line macros. There is also a generous, but sane, upper +limit to the number of recursions, in order to prevent run-away memory +consumption in case of accidental infinite recursion. + + As with non-recursive multi-line macros, recursive multi-line macros +are case-sensitive, unless you define them using the alternative +directive `%irmacro'. + + +File: nasm.info, Node: Section 4.3.2, Next: Section 4.3.3, Prev: Section 4.3.1, Up: Section 4.3 + +4.3.2. Overloading Multi-Line Macros +------------------------------------ + +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 `push' is now defined to be a macro, and is being invoked +with a number of parameters for which no definition has been given. The +correct code will still be generated, but the assembler will give a +warning. This warning can be disabled by the use of the +`-w-macro-params' command- line option (see *note Section 2.1.24::). + + +File: nasm.info, Node: Section 4.3.3, Next: Section 4.3.4, Prev: Section 4.3.2, Up: Section 4.3 + +4.3.3. Macro-Local Labels +------------------------- + +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 `%%' to the label name. So you can invent an instruction +which executes a `RET' if the `Z' flag is set by doing this: + + %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 `%%skip'. The names NASM invents are of the form +`..@2345.skip', where the number 2345 changes with every macro call. +The `..@' prefix prevents macro-local labels from interfering with the +local label mechanism, as described in *note Section 3.9::. You should +avoid defining your own labels in this form (the `..@' prefix, then a +number, then another period) in case they interfere with macro-local +labels. + + +File: nasm.info, Node: Section 4.3.4, Next: Section 4.3.5, Prev: Section 4.3.3, Up: Section 4.3 + +4.3.4. Greedy Macro Parameters +------------------------------ + +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 `writefile' above will work as expected: the +text before the first comma, `[filehandle]', is used as the first macro +parameter and expanded when `%1' is referred to, and all the subsequent +text is lumped into `%2' and placed after the `db'. + + The greedy nature of the macro is indicated to NASM by the use of the +`+' sign after the parameter count on the `%macro' line. + + 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 `writefile' with 2, 3, 4 or +more parameters. NASM will take this into account when overloading +macros, and will not allow you to define another form of `writefile' +taking 4 parameters (for example). + + 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 *note Section 6.3.1:: for a better way to write the above macro. + + +File: nasm.info, Node: Section 4.3.5, Next: Section 4.3.6, Prev: Section 4.3.4, Up: Section 4.3 + +4.3.5. Default Macro Parameters +------------------------------- + +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 `writefile' macro defined in +*note Section 4.3.4::) can be called with an explicit error message, +which it will display on the error output stream before exiting, or it +can be called with no parameters, in which case it will use the default +error message supplied in the macro definition. + + 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 +`%1' would always be taken from the macro call. `%2', if not specified +by the macro call, would default to `eax', and `%3' if not specified +would default to `[ebx+2]'. + + 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 *note Section 2.1.24:: +for more information. When `quux' is invoked, it receives not one but +two parameters. `something' can be referred to as `%2'. The difference +between passing `something' this way and writing `something' in the +macro body is that with this way `something' is evaluated when the +macro is defined, not when it is expanded. + + 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 `%0' +token (see *note Section 4.3.6::) allows you to determine how many +parameters were really passed to the macro call. + + This defaulting mechanism can be combined with the greedy-parameter +mechanism; so the `die' macro above could be made more powerful, and +more useful, by changing the first line of the definition to + + %macro die 0-1+ "Painful program death has occurred.",13,10 + + The maximum parameter count can be infinite, denoted by `*'. In this +case, of course, it is impossible to provide a _full_ set of default +parameters. Examples of this usage are shown in *note Section 4.3.7::. + + +File: nasm.info, Node: Section 4.3.6, Next: Section 4.3.7, Prev: Section 4.3.5, Up: Section 4.3 + +4.3.6. `%0': Macro Parameter Counter +------------------------------------ + +The parameter reference `%0' will return a numeric constant giving the +number of parameters received, that is, if `%0' is n then `%'n is the +last parameter. `%0' is mostly useful for macros that can take a +variable number of parameters. It can be used as an argument to `%rep' +(see *note Section 4.5::) in order to iterate through all the +parameters of a macro. Examples are given in *note Section 4.3.7::. + + +File: nasm.info, Node: Section 4.3.7, Next: Section 4.3.8, Prev: Section 4.3.6, Up: Section 4.3 + +4.3.7. `%rotate': Rotating Macro Parameters +------------------------------------------- + +Unix shell programmers will be familiar with the `shift' shell command, +which allows the arguments passed to a shell script (referenced as +`$1', `$2' and so on) to be moved left by one place, so that the +argument previously referenced as `$2' becomes available as `$1', and +the argument previously referenced as `$1' is no longer available at +all. + + NASM provides a similar mechanism, in the form of `%rotate'. As its +name suggests, it differs from the Unix `shift' in that no parameters +are lost: parameters rotated off the left end of the argument list +reappear on the right, and vice versa. + + `%rotate' is invoked with a single numeric argument (which may be an +expression). The macro parameters are rotated to the left by that many +places. If the argument to `%rotate' is negative, the macro parameters +are rotated to the right. + + 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 `PUSH' instruction on each of its arguments in +turn, from left to right. It begins by pushing its first argument, +`%1', then invokes `%rotate' to move all the arguments one place to the +left, so that the original second argument is now available as `%1'. +Repeating this procedure as many times as there were arguments +(achieved by supplying `%0' as the argument to `%rep') causes each +argument in turn to be pushed. + + Note also the use of `*' as the maximum parameter count, indicating +that there is no upper limit on the number of parameters you may supply +to the `multipush' macro. + + It would be convenient, when using this macro, to have a `POP' +equivalent, which _didn't_ require the arguments to be given in reverse +order. Ideally, you would write the `multipush' macro call, then +cut-and-paste the line to where the pop needed to be done, and change +the name of the called macro to `multipop', and the macro would take +care of popping the registers in the opposite order from the one in +which they were pushed. + + 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 `%1'. This is then +popped, and the arguments are rotated right again, so the second-to- +last argument becomes `%1'. Thus the arguments are iterated through in +reverse order. + + +File: nasm.info, Node: Section 4.3.8, Next: Section 4.3.9, Prev: Section 4.3.7, Up: Section 4.3 + +4.3.8. Concatenating Macro Parameters +------------------------------------- + +NASM can concatenate macro parameters and macro indirection constructs +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 `%1foo'. + + If you need to append a _digit_ to a macro parameter, for example +defining labels `foo1' and `foo2' when passed the parameter `foo', you +can't code `%11' because that would be taken as the eleventh macro +parameter. Instead, you must code `%{1}1', which will separate the +first `1' (giving the number of the macro parameter) from the second +(literal text to be concatenated to the parameter). + + This concatenation can also be applied to other preprocessor in-line +objects, such as macro-local labels (*note Section 4.3.3::) and +context-local labels (*note Section 4.7.2::). In all cases, ambiguities +in syntax can be resolved by enclosing everything after the `%' sign +and before the literal text in braces: so `%{%foo}bar' concatenates the +text `bar' to the end of the real name of the macro-local label +`%%foo'. (This is unnecessary, since the form NASM uses for the real +names of macro-local labels means that the two usages `%{%foo}bar' and +`%%foobar' would both expand to the same thing anyway; nevertheless, +the capability is there.) + + The single-line macro indirection construct, `%[...]' (*note Section +4.1.3::), behaves the same way as macro parameters for the purpose of +concatenation. + + See also the `%+' operator, *note Section 4.1.4::. + + +File: nasm.info, Node: Section 4.3.9, Next: Section 4.3.10, Prev: Section 4.3.8, Up: Section 4.3 + +4.3.9. Condition Codes as Macro Parameters +------------------------------------------ + +NASM can give special treatment to a macro parameter which contains a +condition code. For a start, you can refer to the macro parameter `%1' +by means of the alternative syntax `%+1', which informs NASM that this +macro parameter is supposed to contain a condition code, and will cause +the preprocessor to report an error message if the macro is called with +a parameter which is _not_ a valid condition code. + + Far more usefully, though, you can refer to the macro parameter by +means of `%-1', which NASM will expand as the _inverse_ condition code. +So the `retz' macro defined in *note Section 4.3.3:: can be replaced by +a general conditional-return macro like this: + + %macro retc 1 + + j%-1 %%skip + ret + %%skip: + + %endmacro + + This macro can now be invoked using calls like `retc ne', which will +cause the conditional-jump instruction in the macro expansion to come +out as `JE', or `retc po' which will make the jump a `JPE'. + + The `%+1' macro-parameter reference is quite happy to interpret the +arguments `CXZ' and `ECXZ' as valid condition codes; however, `%-1' +will report an error if passed either of these, because no inverse +condition code exists. + + +File: nasm.info, Node: Section 4.3.10, Next: Section 4.3.11, Prev: Section 4.3.9, Up: Section 4.3 + +4.3.10. Disabling Listing Expansion +----------------------------------- + +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 `.nolist' qualifier, which you can +include in a macro definition to inhibit the expansion of the macro in +the listing file. The `.nolist' qualifier comes directly after the +number of parameters, like this: + + %macro foo 1.nolist + + Or like this: + + %macro bar 1-5+.nolist a,b,c,d,e,f,g,h + + +File: nasm.info, Node: Section 4.3.11, Next: Section 4.3.12, Prev: Section 4.3.10, Up: Section 4.3 + +4.3.11. Undefining Multi-Line Macros: `%unmacro' +------------------------------------------------ + +Multi-line macros can be removed with the `%unmacro' directive. Unlike +the `%undef' directive, however, `%unmacro' takes an argument +specification, and will only remove exact matches with that argument +specification. + + For example: + + %macro foo 1-3 + ; Do something + %endmacro + %unmacro foo 1-3 + + removes the previously defined macro `foo', but + + %macro bar 1-3 + ; Do something + %endmacro + %unmacro bar 1 + + does _not_ remove the macro `bar', since the argument specification +does not match exactly. + + +File: nasm.info, Node: Section 4.3.12, Next: Section 4.4, Prev: Section 4.3.11, Up: Section 4.3 + +4.3.12. Exiting Multi-Line Macros: `%exitmacro' +----------------------------------------------- + +Multi-line macro expansions can be arbitrarily terminated with the +`%exitmacro' directive. + + For example: + + %macro foo 1-3 + ; Do something + %if<condition> + %exitmacro + %endif + ; Do something + %endmacro + + +File: nasm.info, Node: Section 4.4, Next: Section 4.4.1, Prev: Section 4.3.12, Up: Chapter 4 + +4.4. Conditional Assembly +========================= + +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 `%ifn' and `%elifn' are also supported. + + The `%else' clause is optional, as is the `%elif' clause. You can +have more than one `%elif' clause as well. + + There are a number of variants of the `%if' directive. Each has its +corresponding `%elif', `%ifn', and `%elifn' directives; for example, +the equivalents to the `%ifdef' directive are `%elifdef', `%ifndef', +and `%elifndef'. + +* Menu: + +* Section 4.4.1:: `%ifdef': Testing Single-Line Macro Existence +* Section 4.4.2:: `%ifmacro': Testing Multi-Line Macro Existence +* Section 4.4.3:: `%ifctx': Testing the Context Stack +* Section 4.4.4:: `%if': Testing Arbitrary Numeric Expressions +* Section 4.4.5:: `%ifidn' and `%ifidni': Testing Exact Text Identity +* Section 4.4.6:: `%ifid', `%ifnum', `%ifstr': Testing Token Types +* Section 4.4.7:: `%iftoken': Test for a Single Token +* Section 4.4.8:: `%ifempty': Test for Empty Expansion + + +File: nasm.info, Node: Section 4.4.1, Next: Section 4.4.2, Prev: Section 4.4, Up: Section 4.4 + +4.4.1. `%ifdef': Testing Single-Line Macro Existence +---------------------------------------------------- + +Beginning a conditional-assembly block with the line `%ifdef MACRO' +will assemble the subsequent code if, and only if, a single-line macro +called `MACRO' is defined. If not, then the `%elif' and `%else' blocks +(if any) will be processed instead. + + 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 `-dDEBUG' to create a +version of the program which produced debugging messages, and remove the +option to generate the final release version of the program. + + You can test for a macro _not_ being defined by using `%ifndef' +instead of `%ifdef'. You can also test for macro definitions in `%elif' +blocks by using `%elifdef' and `%elifndef'. + + +File: nasm.info, Node: Section 4.4.2, Next: Section 4.4.3, Prev: Section 4.4.1, Up: Section 4.4 + +4.4.2. `%ifmacro': Testing Multi-Line Macro Existence +----------------------------------------------------- + +The `%ifmacro' directive operates in the same way as the `%ifdef' +directive, except that it checks for the existence of a multi-line +macro. + + 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' is considered true if defining a macro with the given +name and number of arguments would cause a definitions conflict. For +example: + + %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 `%ifnmacro' +instead of `%ifmacro'. Additional tests can be performed in `%elif' +blocks by using `%elifmacro' and `%elifnmacro'. + + +File: nasm.info, Node: Section 4.4.3, Next: Section 4.4.4, Prev: Section 4.4.2, Up: Section 4.4 + +4.4.3. `%ifctx': Testing the Context Stack +------------------------------------------ + +The conditional-assembly construct `%ifctx' will cause the subsequent +code to be assembled if and only if the top context on the +preprocessor's context stack has the same name as one of the arguments. +As with `%ifdef', the inverse and `%elif' forms `%ifnctx', `%elifctx' +and `%elifnctx' are also supported. + + For more details of the context stack, see *note Section 4.7::. For +a sample use of `%ifctx', see *note Section 4.7.5::. + + +File: nasm.info, Node: Section 4.4.4, Next: Section 4.4.5, Prev: Section 4.4.3, Up: Section 4.4 + +4.4.4. `%if': Testing Arbitrary Numeric Expressions +--------------------------------------------------- + +The conditional-assembly construct `%if expr' will cause the subsequent +code to be assembled if and only if the value of the numeric expression +`expr' is non-zero. An example of the use of this feature is in +deciding when to break out of a `%rep' preprocessor loop: see *note +Section 4.5:: for a detailed example. + + The expression given to `%if', and its counterpart `%elif', is a +critical expression (see *note Section 3.8::). + + `%if' extends the normal NASM expression syntax, by providing a set +of relational operators which are not normally available in +expressions. The operators `=', `<', `>', `<=', `>=' and `<>' test +equality, less-than, greater-than, less-or-equal, greater-or-equal and +not-equal respectively. The C-like forms `==' and `!=' are supported as +alternative forms of `=' and `<>'. In addition, low- priority logical +operators `&&', `^^' and `||' are provided, supplying logical AND, +logical XOR and logical OR. These work like the C logical operators +(although C has no logical XOR), in that they always return either 0 or +1, and treat any non-zero input as 1 (so that `^^', for example, +returns 1 if exactly one of its inputs is zero, and 0 otherwise). The +relational operators also return 1 for true and 0 for false. + + Like other `%if' constructs, `%if' has a counterpart `%elif', and +negative forms `%ifn' and `%elifn'. + + +File: nasm.info, Node: Section 4.4.5, Next: Section 4.4.6, Prev: Section 4.4.4, Up: Section 4.4 + +4.4.5. `%ifidn' and `%ifidni': Testing Exact Text Identity +---------------------------------------------------------- + +The construct `%ifidn text1,text2' will cause the subsequent code to be +assembled if and only if `text1' and `text2', after expanding +single-line macros, are identical pieces of text. Differences in white +space are not counted. + + `%ifidni' is similar to `%ifidn', but is case-insensitive. + + For example, the following macro pushes a register or number on the +stack, and allows you to treat `IP' as a real register: + + %macro pushparam 1 + + %ifidni %1,ip + call %%label + %%label: + %else + push %1 + %endif + + %endmacro + + Like other `%if' constructs, `%ifidn' has a counterpart `%elifidn', +and negative forms `%ifnidn' and `%elifnidn'. Similarly, `%ifidni' has +counterparts `%elifidni', `%ifnidni' and `%elifnidni'. + + +File: nasm.info, Node: Section 4.4.6, Next: Section 4.4.7, Prev: Section 4.4.5, Up: Section 4.4 + +4.4.6. `%ifid', `%ifnum', `%ifstr': Testing Token Types +------------------------------------------------------- + +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 `%ifid', taking one parameter +(which may be blank), assembles the subsequent code if and only if the +first token in the parameter exists and is an identifier. `%ifnum' +works similarly, but tests for the token being a numeric constant; +`%ifstr' tests for it being a string. + + For example, the `writefile' macro defined in *note Section 4.3.4:: +can be extended to take advantage of `%ifstr' in the following fashion: + + %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' macro can cope with being called in either of +the following two ways: + + writefile [file], strpointer, length + writefile [file], "hello", 13, 10 + + In the first, `strpointer' is used as the address of an already- +declared string, and `length' is used as its length; in the second, a +string is given to the macro, which therefore declares it itself and +works out the address and length for itself. + + Note the use of `%if' inside the `%ifstr': this is to detect whether +the macro was passed two arguments (so the string would be a single +string constant, and `db %2' would be adequate) or more (in which case, +all but the first two would be lumped together into `%3', and `db +%2,%3' would be required). + + The usual `%elif'..., `%ifn'..., and `%elifn'... versions exist for +each of `%ifid', `%ifnum' and `%ifstr'. + + +File: nasm.info, Node: Section 4.4.7, Next: Section 4.4.8, Prev: Section 4.4.6, Up: Section 4.4 + +4.4.7. `%iftoken': Test for a Single Token +------------------------------------------ + +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 `%+') +versus a multi-token sequence. + + The conditional assembly construct `%iftoken' assembles the +subsequent code if and only if the expanded parameters consist of +exactly one token, possibly surrounded by whitespace. + + For example: + + %iftoken 1 + + will assemble the subsequent code, but + + %iftoken -1 + + will not, since `-1' contains two tokens: the unary minus operator +`-', and the number `1'. + + The usual `%eliftoken', `%ifntoken', and `%elifntoken' variants are +also provided. + + +File: nasm.info, Node: Section 4.4.8, Next: Section 4.5, Prev: Section 4.4.7, Up: Section 4.4 + +4.4.8. `%ifempty': Test for Empty Expansion +------------------------------------------- + +The conditional assembly construct `%ifempty' assembles the subsequent +code if and only if the expanded parameters do not contain any tokens at +all, whitespace excepted. + + The usual `%elifempty', `%ifnempty', and `%elifnempty' variants are +also provided. + + +File: nasm.info, Node: Section 4.5, Next: Section 4.6, Prev: Section 4.4.8, Up: Chapter 4 + +4.5. Preprocessor Loops: `%rep' +=============================== + +NASM's `TIMES' prefix, though useful, cannot be used to invoke a +multi-line macro multiple times, because it is processed by NASM after +macros have already been expanded. Therefore NASM provides another form +of loop, this time at the preprocessor level: `%rep'. + + The directives `%rep' and `%endrep' (`%rep' takes a numeric +argument, which can be an expression; `%endrep' takes no arguments) can +be used to enclose a chunk of code, which is then replicated as many +times as specified by the preprocessor: + + %assign i 0 + %rep 64 + inc word [table+2*i] + %assign i i+1 + %endrep + + This will generate a sequence of 64 `INC' instructions, incrementing +every word of memory from `[table]' to `[table+126]'. + + For more complex termination conditions, or to break out of a repeat +loop part way along, you can use the `%exitrep' directive to terminate +the loop, like this: + + 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 +`%rep'. This is to prevent the possibility of NASM getting into an +infinite loop in the preprocessor, which (on multitasking or multi-user +systems) would typically cause all the system memory to be gradually +used up and other applications to start crashing. + + +File: nasm.info, Node: Section 4.6, Next: Section 4.6.1, Prev: Section 4.5, Up: Chapter 4 + +4.6. Source Files and Dependencies +================================== + +These commands allow you to split your sources into multiple files. + +* Menu: + +* Section 4.6.1:: `%include': Including Other Files +* Section 4.6.2:: `%pathsearch': Search the Include Path +* Section 4.6.3:: `%depend': Add Dependent Files +* Section 4.6.4:: `%use': Include Standard Macro Package + + +File: nasm.info, Node: Section 4.6.1, Next: Section 4.6.2, Prev: Section 4.6, Up: Section 4.6 + +4.6.1. `%include': Including Other Files +---------------------------------------- + +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' directive: + + %include "macros.mac" + + will include the contents of the file `macros.mac' into the source +file containing the `%include' directive. + + 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 `-i' option. + + The standard C idiom for preventing a file being included more than +once is just as applicable in NASM: if the file `macros.mac' has the +form + + %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 `MACROS_MAC' will already be defined. + + You can force a file to be included even if there is no `%include' +directive that explicitly includes it, by using the `-p' option on the +NASM command line (see *note Section 2.1.17::). + + +File: nasm.info, Node: Section 4.6.2, Next: Section 4.6.3, Prev: Section 4.6.1, Up: Section 4.6 + +4.6.2. `%pathsearch': Search the Include Path +--------------------------------------------- + +The `%pathsearch' directive takes a single-line macro name and a +filename, and declare or redefines the specified single-line macro to be +the include-path-resolved version of the filename, if the file exists +(otherwise, it is passed unchanged.) + + For example, + + %pathsearch MyFoo "foo.bin" + + ... with `-Ibins/' in the include path may end up defining the macro +`MyFoo' to be `"bins/foo.bin"'. + + +File: nasm.info, Node: Section 4.6.3, Next: Section 4.6.4, Prev: Section 4.6.2, Up: Section 4.6 + +4.6.3. `%depend': Add Dependent Files +------------------------------------- + +The `%depend' directive takes a filename and adds it to the list of +files to be emitted as dependency generation when the `-M' options and +its relatives (see *note Section 2.1.4::) are used. It produces no +output. + + This is generally used in conjunction with `%pathsearch'. For +example, a simplified version of the standard macro wrapper for the +`INCBIN' directive looks like: + + %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 `dep', +then adds it to the dependency lists, and finally issues the assembler- +level `INCBIN' directive. + + +File: nasm.info, Node: Section 4.6.4, Next: Section 4.7, Prev: Section 4.6.3, Up: Section 4.6 + +4.6.4. `%use': Include Standard Macro Package +--------------------------------------------- + +The `%use' directive is similar to `%include', but rather than +including the contents of a file, it includes a named standard macro +package. The standard macro packages are part of NASM, and are +described in *note Chapter 5::. + + Unlike the `%include' directive, package names for the `%use' +directive do not require quotes, but quotes are permitted. In NASM 2.04 +and 2.05 the unquoted form would be macro-expanded; this is no longer +true. Thus, the following lines are equivalent: + + %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 +`__USE_'_package_`__' is also defined, see *note Section 4.11.8::. + + +File: nasm.info, Node: Section 4.7, Next: Section 4.7.1, Prev: Section 4.6.4, Up: Chapter 4 + +4.7. The Context Stack +====================== + +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 `REPEAT' ... `UNTIL' +loop, in which the expansion of the `REPEAT' macro would need to be +able to refer to a label which the `UNTIL' macro had defined. However, +for such a macro you would also want to be able to nest these loops. + + 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' directive, and remove one using `%pop'. You can define labels +that are local to a particular context on the stack. + +* Menu: + +* Section 4.7.1:: `%push' and `%pop': Creating and Removing Contexts +* Section 4.7.2:: Context-Local Labels +* Section 4.7.3:: Context-Local Single-Line Macros +* Section 4.7.4:: `%repl': Renaming a Context +* Section 4.7.5:: Example Use of the Context Stack: Block IFs + + +File: nasm.info, Node: Section 4.7.1, Next: Section 4.7.2, Prev: Section 4.7, Up: Section 4.7 + +4.7.1. `%push' and `%pop': Creating and Removing Contexts +--------------------------------------------------------- + +The `%push' directive is used to create a new context and place it on +the top of the context stack. `%push' takes an optional argument, which +is the name of the context. For example: + + %push foobar + + This pushes a new context called `foobar' on the stack. You can have +several contexts on the stack with the same name: they can still be +distinguished. If no name is given, the context is unnamed (this is +normally used when both the `%push' and the `%pop' are inside a single +macro definition.) + + The directive `%pop', taking one optional argument, removes the top +context from the context stack and destroys it, along with any labels +associated with it. If an argument is given, it must match the name of +the current context, otherwise it will issue an error. + + +File: nasm.info, Node: Section 4.7.2, Next: Section 4.7.3, Prev: Section 4.7.1, Up: Section 4.7 + +4.7.2. Context-Local Labels +--------------------------- + +Just as the usage `%%foo' defines a label which is local to the +particular macro call in which it is used, the usage `%$foo' is used to +define a label which is local to the context on the top of the context +stack. So the `REPEAT' and `UNTIL' example given above could be +implemented by means of: + + %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 `AL'. + + If you need to define, or access, labels local to the context _below_ +the top one on the stack, you can use `%$$foo', or `%$$$foo' for the +context below that, and so on. + + +File: nasm.info, Node: Section 4.7.3, Next: Section 4.7.4, Prev: Section 4.7.2, Up: Section 4.7 + +4.7.3. Context-Local Single-Line Macros +--------------------------------------- + +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 `%$localmac' to be local to the top +context on the stack. Of course, after a subsequent `%push', it can +then still be accessed by the name `%$$localmac'. + + +File: nasm.info, Node: Section 4.7.4, Next: Section 4.7.5, Prev: Section 4.7.3, Up: Section 4.7 + +4.7.4. `%repl': Renaming a Context +---------------------------------- + +If you need to change the name of the top context on the stack (in +order, for example, to have it respond differently to `%ifctx'), you can +execute a `%pop' followed by a `%push'; but this will have the side +effect of destroying all context-local labels and macros associated +with the context that was just popped. + + NASM provides the directive `%repl', which _replaces_ a context with +a different name, without touching the associated macros and labels. +So you could replace the destructive code + + %pop + %push newname + + with the non-destructive version `%repl newname'. + + +File: nasm.info, Node: Section 4.7.5, Next: Section 4.8, Prev: Section 4.7.4, Up: Section 4.7 + +4.7.5. Example Use of the Context Stack: Block IFs +-------------------------------------------------- + +This example makes use of almost all the context-stack features, +including the conditional-assembly construct `%ifctx', to implement a +block IF statement as a set of macros. + + %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 `REPEAT' and `UNTIL' macros given +in *note Section 4.7.2::, because it uses conditional assembly to check +that the macros are issued in the right order (for example, not calling +`endif' before `if') and issues a `%error' if they're not. + + In addition, the `endif' macro has to be able to cope with the two +distinct cases of either directly following an `if', or following an +`else'. It achieves this, again, by using conditional assembly to do +different things depending on whether the context on top of the stack is +`if' or `else'. + + The `else' macro has to preserve the context on the stack, in order +to have the `%$ifnot' referred to by the `if' macro be the same as the +one defined by the `endif' macro, but has to change the context's name +so that `endif' will know there was an intervening `else'. It does +this by the use of `%repl'. + + 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-`IF' macros handle nesting quite happily, by means of +pushing another context, describing the inner `if', on top of the one +describing the outer `if'; thus `else' and `endif' always refer to the +last unmatched `if' or `else'. + + +File: nasm.info, Node: Section 4.8, Next: Section 4.8.1, Prev: Section 4.7.5, Up: Chapter 4 + +4.8. Stack Relative Preprocessor Directives +=========================================== + +The following preprocessor directives provide a way to use labels to +refer to local variables allocated on the stack. + + * `%arg' (see *note Section 4.8.1::) + + * `%stacksize' (see *note Section 4.8.2::) + + * `%local' (see *note Section 4.8.3::) + +* Menu: + +* Section 4.8.1:: `%arg' Directive +* Section 4.8.2:: `%stacksize' Directive +* Section 4.8.3:: `%local' Directive + + +File: nasm.info, Node: Section 4.8.1, Next: Section 4.8.2, Prev: Section 4.8, Up: Section 4.8 + +4.8.1. `%arg' Directive +----------------------- + +The `%arg' directive is used to simplify the handling of parameters +passed on the stack. Stack based parameter passing is used by many high +level languages, including C, C++ and Pascal. + + While NASM has macros which attempt to duplicate this functionality +(see *note 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 `%arg' without any external macros: + + 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 *note 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 *note Section 4.7.1:: for an +explanation of `push' and `pop' and the use of context stacks. + + +File: nasm.info, Node: Section 4.8.2, Next: Section 4.8.3, Prev: Section 4.8.1, Up: Section 4.8 + +4.8.2. `%stacksize' Directive +----------------------------- + +The `%stacksize' directive is used in conjunction with the `%arg' (see +*note Section 4.8.1::) and the `%local' (see *note Section 4.8.3::) +directives. It tells NASM the default size to use for subsequent `%arg' +and `%local' directives. The `%stacksize' directive takes one required +argument which is one of `flat', `flat64', `large' or `small'. + + %stacksize flat + + This form causes NASM to use stack-based parameter addressing +relative to `ebp' and it assumes that a near form of call was used to +get to this label (i.e. that `eip' is on the stack). + + %stacksize flat64 + + This form causes NASM to use stack-based parameter addressing +relative to `rbp' and it assumes that a near form of call was used to +get to this label (i.e. that `rip' is on the stack). + + %stacksize large + + This form uses `bp' to do stack-based parameter addressing and +assumes that a far form of call was used to get to this address (i.e. +that `ip' and `cs' are on the stack). + + %stacksize small + + This form also uses `bp' to address stack parameters, but it is +different from `large' because it also assumes that the old value of bp +is pushed onto the stack (i.e. it expects an `ENTER' instruction). In +other words, it expects that `bp', `ip' and `cs' are on the top of the +stack, underneath any local space which may have been allocated by +`ENTER'. This form is probably most useful when used in combination +with the `%local' directive (see *note Section 4.8.3::). + + +File: nasm.info, Node: Section 4.8.3, Next: Section 4.9, Prev: Section 4.8.2, Up: Section 4.8 + +4.8.3. `%local' Directive +------------------------- + +The `%local' directive is used to simplify the use of local temporary +stack variables allocated in a stack frame. Automatic local variables +in C are an example of this kind of variable. The `%local' directive is +most useful when used with the `%stacksize' (see *note Section 4.8.2:: +and is also compatible with the `%arg' directive (see *note Section +4.8.1::). It allows simplified reference to variables on the stack which +have been allocated typically by using the `ENTER' instruction. An +example of its use is the following: + + 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 `%$localsize' variable is used internally by the `%local' +directive and _must_ be defined within the current context before the +`%local' directive may be used. Failure to do so will result in one +expression syntax error for each `%local' variable declared. It then +may be used in the construction of an appropriately sized ENTER +instruction as shown in the example. + + +File: nasm.info, Node: Section 4.9, Next: Section 4.10, Prev: Section 4.8.3, Up: Chapter 4 + +4.9. Reporting User-Defined Errors: `%error', `%warning', `%fatal' +================================================================== + +The preprocessor directive `%error' will cause NASM to report an error +if it occurs in assembled code. So if other users are going to try to +assemble your source files, you can ensure that they define the right +macros by means of code like this: + + %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, `%warning' issues a warning, but allows assembly to +continue: + + %ifdef F1 + ; do some setup + %elifdef F2 + ; do some different setup + %else + %warning "Neither F1 nor F2 was defined, assuming F1." + %define F1 + %endif + + `%error' and `%warning' are issued only on the final assembly pass. +This makes them safe to use in conjunction with tests that depend on +symbol values. + + `%fatal' terminates assembly immediately, regardless of pass. This is +useful when there is no point in continuing the assembly further, and +doing so is likely just going to cause a spew of confusing error +messages. + + It is optional for the message string after `%error', `%warning' or +`%fatal' to be quoted. If it is _not_, then single-line macros are +expanded in it, which can be used to display more information to the +user. For example: + + %if foo > 64 + %assign foo_over foo-64 + %error foo is foo_over bytes too large + %endif + + +File: nasm.info, Node: Section 4.10, Next: Section 4.10.1, Prev: Section 4.9, Up: Chapter 4 + +4.10. Other Preprocessor Directives +=================================== + +NASM also has preprocessor directives which allow access to information +from external sources. Currently they include: + + * `%line' enables NASM to correctly handle the output of another + preprocessor (see *note Section 4.10.1::). + + * `%!' enables NASM to read in the value of an environment variable, + which can then be used in your program (see *note Section + 4.10.2::). + +* Menu: + +* Section 4.10.1:: `%line' Directive +* Section 4.10.2:: `%!'`<env>': Read an environment variable. + + +File: nasm.info, Node: Section 4.10.1, Next: Section 4.10.2, Prev: Section 4.10, Up: Section 4.10 + +4.10.1. `%line' Directive +------------------------- + +The `%line' directive is used to notify NASM that the input line +corresponds to a specific line number in another file. Typically this +other file would be an original source file, with the current NASM +input being the output of a pre-processor. The `%line' directive allows +NASM to output messages which indicate the line number of the original +source file, instead of the file that is being read by NASM. + + This preprocessor directive is not generally of use to programmers, +by may be of interest to preprocessor authors. The usage of the `%line' +preprocessor directive is as follows: + + %line nnn[+mmm] [filename] + + In this directive, `nnn' identifies the line of the original source +file which this line corresponds to. `mmm' is an optional parameter +which specifies a line increment value; each line of the input file +read in is considered to correspond to `mmm' lines of the original +source file. Finally, `filename' is an optional parameter which +specifies the file name of the original source file. + + After reading a `%line' preprocessor directive, NASM will report all +file name and line numbers relative to the values specified therein. + + +File: nasm.info, Node: Section 4.10.2, Next: Section 4.11, Prev: Section 4.10.1, Up: Section 4.10 + +4.10.2. `%!'`<env>': Read an environment variable. +-------------------------------------------------- + +The `%!<env>' directive makes it possible to read the value of an +environment variable at assembly time. This could, for example, be used +to store the contents of an environment variable into a string, which +could be used at some other point in your code. + + For example, suppose that you have an environment variable `FOO', and +you want the contents of `FOO' to be embedded in your program. You +could do that as follows: + + %defstr FOO %!FOO + + See *note Section 4.1.8:: for notes on the `%defstr' directive. + + +File: nasm.info, Node: Section 4.11, Next: Section 4.11.1, Prev: Section 4.10.2, Up: Chapter 4 + +4.11. 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. + + Most user-level assembler directives (see *note Chapter 6::) are +implemented as macros which invoke primitive directives; these are +described in *note Chapter 6::. The rest of the standard macro set is +described here. + +* Menu: + +* Section 4.11.1:: NASM Version Macros +* Section 4.11.2:: `__NASM_VERSION_ID__': NASM Version ID +* Section 4.11.3:: `__NASM_VER__': NASM Version string +* Section 4.11.4:: `__FILE__' and `__LINE__': File Name and Line Number +* Section 4.11.5:: `__BITS__': Current BITS Mode +* Section 4.11.6:: `__OUTPUT_FORMAT__': Current Output Format +* Section 4.11.7:: Assembly Date and Time Macros +* Section 4.11.8:: `__USE_'_package_`__': Package Include Test +* Section 4.11.9:: `__PASS__': Assembly Pass +* Section 4.11.10:: `STRUC' and `ENDSTRUC': Declaring Structure Data Types +* Section 4.11.11:: `ISTRUC', `AT' and `IEND': Declaring Instances of Structures +* Section 4.11.12:: `ALIGN' and `ALIGNB': Data Alignment + + +File: nasm.info, Node: Section 4.11.1, Next: Section 4.11.2, Prev: Section 4.11, Up: Section 4.11 + +4.11.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_. + + +File: nasm.info, Node: Section 4.11.2, Next: Section 4.11.3, Prev: Section 4.11.1, Up: Section 4.11 + +4.11.2. `__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. + + +File: nasm.info, Node: Section 4.11.3, Next: Section 4.11.4, Prev: Section 4.11.2, Up: Section 4.11 + +4.11.3. `__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" + + +File: nasm.info, Node: Section 4.11.4, Next: Section 4.11.5, Prev: Section 4.11.3, Up: Section 4.11 + +4.11.4. `__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. + + +File: nasm.info, Node: Section 4.11.5, Next: Section 4.11.6, Prev: Section 4.11.4, Up: Section 4.11 + +4.11.5. `__BITS__': Current BITS 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. + + +File: nasm.info, Node: Section 4.11.6, Next: Section 4.11.7, Prev: Section 4.11.5, Up: Section 4.11 + +4.11.6. `__OUTPUT_FORMAT__': Current Output Format +-------------------------------------------------- + +The `__OUTPUT_FORMAT__' standard macro holds the current Output Format, +as given by the `-f' option or NASM's default. Type `nasm -hf' for a +list. + + %ifidn __OUTPUT_FORMAT__, win32 + %define NEWLINE 13, 10 + %elifidn __OUTPUT_FORMAT__, elf32 + %define NEWLINE 10 + %endif + + +File: nasm.info, Node: Section 4.11.7, Next: Section 4.11.8, Prev: Section 4.11.6, Up: Section 4.11 + +4.11.7. Assembly Date and Time Macros +------------------------------------- + +NASM provides a variety of macros that represent the timestamp of the +assembly session. + + * The `__DATE__' and `__TIME__' macros give the assembly date and + time as strings, in ISO 8601 format (`"YYYY-MM-DD"' and + `"HH:MM:SS"', respectively.) + + * The `__DATE_NUM__' and `__TIME_NUM__' macros give the assembly + date and time in numeric form; in the format `YYYYMMDD' and + `HHMMSS' respectively. + + * The `__UTC_DATE__' and `__UTC_TIME__' macros give the assembly + date and time in universal time (UTC) as strings, in ISO 8601 + format (`"YYYY-MM-DD"' and `"HH:MM:SS"', respectively.) If the host + platform doesn't provide UTC time, these macros are undefined. + + * The `__UTC_DATE_NUM__' and `__UTC_TIME_NUM__' macros give the + assembly date and time universal time (UTC) in numeric form; in + the format `YYYYMMDD' and `HHMMSS' respectively. If the host + platform doesn't provide UTC time, these macros are undefined. + + * The `__POSIX_TIME__' macro is defined as a number containing the + number of seconds since the POSIX epoch, 1 January 1970 00:00:00 + UTC; excluding any leap seconds. This is computed using UTC time + if available on the host platform, otherwise it is computed using + the local time as if it was UTC. + + 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 + + +File: nasm.info, Node: Section 4.11.8, Next: Section 4.11.9, Prev: Section 4.11.7, Up: Section 4.11 + +4.11.8. `__USE_'_package_`__': Package Include Test +--------------------------------------------------- + +When a standard macro package (see *note Chapter 5::) is included with +the `%use' directive (see *note Section 4.6.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 *note Section +5.1::), then the macro `__USE_ALTREG__' is defined. + + +File: nasm.info, Node: Section 4.11.9, Next: Section 4.11.10, Prev: Section 4.11.8, Up: Section 4.11 + +4.11.9. `__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 *note Section 2.1.4::) 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._ + + +File: nasm.info, Node: Section 4.11.10, Next: Section 4.11.11, Prev: Section 4.11.9, Up: Section 4.11 + +4.11.10. `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 + + +File: nasm.info, Node: Section 4.11.11, Next: Section 4.11.12, Prev: Section 4.11.10, Up: Section 4.11 + +4.11.11. `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 + + +File: nasm.info, Node: Section 4.11.12, Next: Chapter 5, Prev: Section 4.11.11, Up: Section 4.11 + +4.11.12. `ALIGN' and `ALIGNB': 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'. + + See also the `smartalign' standard macro package, *note Section +5.2::. + + +File: nasm.info, Node: Chapter 5, Next: Section 5.1, Prev: Section 4.11.12, Up: Top + +Chapter 5: Standard Macro Packages +********************************** + +The `%use' directive (see *note Section 4.6.4::) includes one of the +standard macro packages included with the NASM distribution and compiled +into the NASM binary. It operates like the `%include' directive (see +*note Section 4.6.1::), but the included contents is provided by NASM +itself. + + The names of standard macro packages are case insensitive, and can be +quoted or not. + +* Menu: + +* Section 5.1:: `altreg': Alternate Register Names +* Section 5.2:: `smartalign': Smart `ALIGN' Macro + + +File: nasm.info, Node: Section 5.1, Next: Section 5.2, Prev: Chapter 5, Up: Chapter 5 + +5.1. `altreg': Alternate Register Names +======================================= + +The `altreg' standard macro package provides alternate register names. +It provides numeric register names for all registers (not just `R8'- +`R15'), the Intel-defined aliases `R8L'-`R15L' for the low bytes of +register (as opposed to the NASM/AMD standard names `R8B'- `R15B'), and +the names `R0H'-`R3H' (by analogy with `R0L'-`R3L') for `AH', `CH', +`DH', and `BH'. + + Example use: + + %use altreg + + proc: + mov r0l,r3h ; mov al,bh + ret + + See also *note Section 11.1::. + + +File: nasm.info, Node: Section 5.2, Next: Chapter 6, Prev: Section 5.1, Up: Chapter 5 + +5.2. `smartalign': Smart `ALIGN' Macro +====================================== + +The `smartalign' standard macro package provides for an `ALIGN' macro +which is more powerful than the default (and backwards-compatible) one +(see *note Section 4.11.12::). When the `smartalign' package is +enabled, when `ALIGN' is used without a second argument, NASM will +generate a sequence of instructions more efficient than a series of +`NOP'. Furthermore, if the padding exceeds a specific threshold, then +NASM will generate a jump over the entire padding sequence. + + The specific instructions generated can be controlled with the new +`ALIGNMODE' macro. This macro takes two parameters: one mode, and an +optional jump threshold override. The modes are as follows: + + * `generic': Works on all x86 CPUs and should have reasonable + performance. The default jump threshold is 8. This is the default. + + * `nop': Pad out with `NOP' instructions. The only difference + compared to the standard `ALIGN' macro is that NASM can still jump + over a large padding area. The default jump threshold is 16. + + * `k7': Optimize for the AMD K7 (Athlon/Althon XP). These + instructions should still work on all x86 CPUs. The default jump + threshold is 16. + + * `k8': Optimize for the AMD K8 (Opteron/Althon 64). These + instructions should still work on all x86 CPUs. The default jump + threshold is 16. + + * `p6': Optimize for Intel CPUs. This uses the long `NOP' + instructions first introduced in Pentium Pro. This is incompatible + with all CPUs of family 5 or lower, as well as some VIA CPUs and + several virtualization solutions. The default jump threshold is 16. + + The macro `__ALIGNMODE__' is defined to contain the current alignment +mode. A number of other macros beginning with `__ALIGN_' are used +internally by this macro package. + + +File: nasm.info, Node: Chapter 6, Next: Section 6.1, Prev: Section 5.2, Up: Top + +Chapter 6: Assembler Directives +******************************* + +NASM, though it attempts to avoid the bureaucracy of assemblers like +MASM and TASM, is nevertheless forced to support a _few_ directives. +These are described in this chapter. + + NASM's directives come in two types: _user-level_ directives and +_primitive_ directives. Typically, each directive has a user-level form +and a primitive form. In almost all cases, we recommend that users use +the user-level forms of the directives, which are implemented as macros +which call the primitive forms. + + Primitive directives are enclosed in square brackets; user-level +directives are not. + + In addition to the universal directives described in this chapter, +each object file format can optionally supply extra directives in order +to control particular features of that file format. These +_format-specific_ directives are documented along with the formats that +implement them, in *note Chapter 7::. + +* Menu: + +* Section 6.1:: `BITS': Specifying Target Processor Mode +* Section 6.2:: `DEFAULT': Change the assembler defaults +* Section 6.3:: `SECTION' or `SEGMENT': Changing and Defining Sections +* Section 6.4:: `ABSOLUTE': Defining Absolute Labels +* Section 6.5:: `EXTERN': Importing Symbols from Other Modules +* Section 6.6:: `GLOBAL': Exporting Symbols to Other Modules +* Section 6.7:: `COMMON': Defining Common Data Areas +* Section 6.8:: `CPU': Defining CPU Dependencies +* Section 6.9:: `FLOAT': Handling of floating-point constants + + +File: nasm.info, Node: Section 6.1, Next: Section 6.1.1, Prev: Chapter 6, Up: Chapter 6 + +6.1. `BITS': Specifying Target Processor Mode +============================================= + +The `BITS' directive specifies whether NASM should generate code +designed to run on a processor operating in 16-bit mode, 32-bit mode or +64- bit mode. The syntax is `BITS XX', where XX is 16, 32 or 64. + + In most cases, you should not need to use `BITS' explicitly. The +`aout', `coff', `elf', `macho', `win32' and `win64' object formats, +which are designed for use in 32-bit or 64-bit operating systems, all +cause NASM to select 32-bit or 64-bit mode, respectively, by default. +The `obj' object format allows you to specify each segment you define +as either `USE16' or `USE32', and NASM will set its operating mode +accordingly, so the use of the `BITS' directive is once again +unnecessary. + + The most likely reason for using the `BITS' directive is to write 32- +bit or 64-bit code in a flat binary file; this is because the `bin' +output format defaults to 16-bit mode in anticipation of it being used +most frequently to write DOS `.COM' programs, DOS `.SYS' device drivers +and boot loader software. + + You do _not_ need to specify `BITS 32' merely in order to use 32- +bit instructions in a 16-bit DOS program; if you do, the assembler will +generate incorrect code because it will be writing code targeted at a +32- bit platform, to be run on a 16-bit one. + + When NASM is in `BITS 16' mode, instructions which use 32-bit data +are prefixed with an 0x66 byte, and those referring to 32-bit addresses +have an 0x67 prefix. In `BITS 32' mode, the reverse is true: 32-bit +instructions require no prefixes, whereas instructions using 16-bit data +need an 0x66 and those working on 16-bit addresses need an 0x67. + + When NASM is in `BITS 64' mode, most instructions operate the same as +they do for `BITS 32' mode. However, there are 8 more general and SSE +registers, and 16-bit addressing is no longer supported. + + The default address size is 64 bits; 32-bit addressing can be +selected with the 0x67 prefix. The default operand size is still 32 +bits, however, and the 0x66 prefix selects 16-bit operand size. The +`REX' prefix is used both to select 64-bit operand size, and to access +the new registers. NASM automatically inserts REX prefixes when +necessary. + + When the `REX' prefix is used, the processor does not know how to +address the AH, BH, CH or DH (high 8-bit legacy) registers. Instead, it +is possible to access the the low 8-bits of the SP, BP SI and DI +registers as SPL, BPL, SIL and DIL, respectively; but only when the REX +prefix is used. + + The `BITS' directive has an exactly equivalent primitive form, +`[BITS 16]', `[BITS 32]' and `[BITS 64]'. The user-level form is a +macro which has no function other than to call the primitive form. + + Note that the space is neccessary, e.g. `BITS32' will _not_ work! + +* Menu: + +* Section 6.1.1:: `USE16' & `USE32': Aliases for BITS + + +File: nasm.info, Node: Section 6.1.1, Next: Section 6.2, Prev: Section 6.1, Up: Section 6.1 + +6.1.1. `USE16' & `USE32': Aliases for BITS +------------------------------------------ + +The ``USE16'' and ``USE32'' directives can be used in place of ``BITS +16'' and ``BITS 32'', for compatibility with other assemblers. + + +File: nasm.info, Node: Section 6.2, Next: Section 6.3, Prev: Section 6.1.1, Up: Chapter 6 + +6.2. `DEFAULT': Change the assembler defaults +============================================= + +The `DEFAULT' directive changes the assembler defaults. Normally, NASM +defaults to a mode where the programmer is expected to explicitly +specify most features directly. However, this is occationally +obnoxious, as the explicit form is pretty much the only one one wishes +to use. + + Currently, the only `DEFAULT' that is settable is whether or not +registerless instructions in 64-bit mode are `RIP'-relative or not. By +default, they are absolute unless overridden with the `REL' specifier +(see *note Section 3.3::). However, if `DEFAULT REL' is specified, +`REL' is default, unless overridden with the `ABS' specifier, _except +when used with an FS or GS segment override_. + + The special handling of `FS' and `GS' overrides are due to the fact +that these registers are generally used as thread pointers or other +special functions in 64-bit mode, and generating `RIP'-relative +addresses would be extremely confusing. + + `DEFAULT REL' is disabled with `DEFAULT ABS'. + + +File: nasm.info, Node: Section 6.3, Next: Section 6.3.1, Prev: Section 6.2, Up: Chapter 6 + +6.3. `SECTION' or `SEGMENT': Changing and Defining Sections +=========================================================== + +The `SECTION' directive (`SEGMENT' is an exactly equivalent synonym) +changes which section of the output file the code you write will be +assembled into. In some object file formats, the number and names of +sections are fixed; in others, the user may make up as many as they +wish. Hence `SECTION' may sometimes give an error message, or may +define a new section, if you try to switch to a section that does not +(yet) exist. + + The Unix object formats, and the `bin' object format (but see *note +Section 7.1.3::, all support the standardized section names `.text', +`.data' and `.bss' for the code, data and uninitialized-data sections. +The `obj' format, by contrast, does not recognize these section names +as being special, and indeed will strip off the leading period of any +section name that has one. + +* Menu: + +* Section 6.3.1:: The `__SECT__' Macro + + +File: nasm.info, Node: Section 6.3.1, Next: Section 6.4, Prev: Section 6.3, Up: Section 6.3 + +6.3.1. The `__SECT__' Macro +--------------------------- + +The `SECTION' directive is unusual in that its user-level form +functions differently from its primitive form. The primitive form, +`[SECTION xyz]', simply switches the current target section to the one +given. The user-level form, `SECTION xyz', however, first defines the +single-line macro `__SECT__' to be the primitive `[SECTION]' directive +which it is about to issue, and then issues it. So the user-level +directive + + SECTION .text + + expands to the two lines + + %define __SECT__ [SECTION .text] + [SECTION .text] + + Users may find it useful to make use of this in their own macros. For +example, the `writefile' macro defined in *note Section 4.3.4:: can be +usefully rewritten in the following more sophisticated form: + + %macro writefile 2+ + + [section .data] + + %%str: db %2 + %%endstr: + + __SECT__ + + mov dx,%%str + mov cx,%%endstr-%%str + mov bx,%1 + mov ah,0x40 + int 0x21 + + %endmacro + + This form of the macro, once passed a string to output, first +switches temporarily to the data section of the file, using the +primitive form of the `SECTION' directive so as not to modify +`__SECT__'. It then declares its string in the data section, and then +invokes `__SECT__' to switch back to _whichever_ section the user was +previously working in. It thus avoids the need, in the previous version +of the macro, to include a `JMP' instruction to jump over the data, and +also does not fail if, in a complicated `OBJ' format module, the user +could potentially be assembling the code in any of several separate code +sections. + + +File: nasm.info, Node: Section 6.4, Next: Section 6.5, Prev: Section 6.3.1, Up: Chapter 6 + +6.4. `ABSOLUTE': Defining Absolute Labels +========================================= + +The `ABSOLUTE' directive can be thought of as an alternative form of +`SECTION': it causes the subsequent code to be directed at no physical +section, but at the hypothetical section starting at the given absolute +address. The only instructions you can use in this mode are the `RESB' +family. + + `ABSOLUTE' is used as follows: + + absolute 0x1A + + kbuf_chr resw 1 + kbuf_free resw 1 + kbuf resw 16 + + This example describes a section of the PC BIOS data area, at segment +address 0x40: the above code defines `kbuf_chr' to be 0x1A, `kbuf_free' +to be 0x1C, and `kbuf' to be 0x1E. + + The user-level form of `ABSOLUTE', like that of `SECTION', redefines +the `__SECT__' macro when it is invoked. + + `STRUC' and `ENDSTRUC' are defined as macros which use `ABSOLUTE' +(and also `__SECT__'). + + `ABSOLUTE' doesn't have to take an absolute constant as an argument: +it can take an expression (actually, a critical expression: see *note +Section 3.8::) and it can be a value in a segment. For example, a TSR +can re-use its setup code as run-time BSS like this: + + org 100h ; it's a .COM program + + jmp setup ; setup code comes last + + ; the resident part of the TSR goes here + setup: + ; now write the code that installs the TSR here + + absolute setup + + runtimevar1 resw 1 + runtimevar2 resd 20 + + tsr_end: + + This defines some variables `on top of' the setup code, so that +after the setup has finished running, the space it took up can be +re-used as data storage for the running TSR. The symbol `tsr_end' can +be used to calculate the total size of the part of the TSR that needs +to be made resident. + + +File: nasm.info, Node: Section 6.5, Next: Section 6.6, Prev: Section 6.4, Up: Chapter 6 + +6.5. `EXTERN': Importing Symbols from Other Modules +=================================================== + +`EXTERN' is similar to the MASM directive `EXTRN' and the C keyword +`extern': it is used to declare a symbol which is not defined anywhere +in the module being assembled, but is assumed to be defined in some +other module and needs to be referred to by this one. Not every +object-file format can support external variables: the `bin' format +cannot. + + The `EXTERN' directive takes as many arguments as you like. Each +argument is the name of a symbol: + + extern _printf + extern _sscanf,_fscanf + + Some object-file formats provide extra features to the `EXTERN' +directive. In all cases, the extra features are used by suffixing a +colon to the symbol name followed by object-format specific text. For +example, the `obj' format allows you to declare that the default +segment base of an external should be the group `dgroup' by means of +the directive + + extern _variable:wrt dgroup + + The primitive form of `EXTERN' differs from the user-level form only +in that it can take only one argument at a time: the support for +multiple arguments is implemented at the preprocessor level. + + You can declare the same variable as `EXTERN' more than once: NASM +will quietly ignore the second and later redeclarations. You can't +declare a variable as `EXTERN' as well as something else, though. + + +File: nasm.info, Node: Section 6.6, Next: Section 6.7, Prev: Section 6.5, Up: Chapter 6 + +6.6. `GLOBAL': Exporting Symbols to Other Modules +================================================= + +`GLOBAL' is the other end of `EXTERN': if one module declares a symbol +as `EXTERN' and refers to it, then in order to prevent linker errors, +some other module must actually _define_ the symbol and declare it as +`GLOBAL'. Some assemblers use the name `PUBLIC' for this purpose. + + The `GLOBAL' directive applying to a symbol must appear _before_ the +definition of the symbol. + + `GLOBAL' uses the same syntax as `EXTERN', except that it must refer +to symbols which _are_ defined in the same module as the `GLOBAL' +directive. For example: + + global _main + _main: + ; some code + + `GLOBAL', like `EXTERN', allows object formats to define private +extensions by means of a colon. The `elf' object format, for example, +lets you specify whether global data items are functions or data: + + global hashlookup:function, hashtable:data + + Like `EXTERN', the primitive form of `GLOBAL' differs from the +user-level form only in that it can take only one argument at a time. + + +File: nasm.info, Node: Section 6.7, Next: Section 6.8, Prev: Section 6.6, Up: Chapter 6 + +6.7. `COMMON': Defining Common Data Areas +========================================= + +The `COMMON' directive is used to declare _common variables_. A common +variable is much like a global variable declared in the uninitialized +data section, so that + + common intvar 4 + + is similar in function to + + global intvar + section .bss + + intvar resd 1 + + The difference is that if more than one module defines the same +common variable, then at link time those variables will be _merged_, and +references to `intvar' in all modules will point at the same piece of +memory. + + Like `GLOBAL' and `EXTERN', `COMMON' supports object-format specific +extensions. For example, the `obj' format allows common variables to be +NEAR or FAR, and the `elf' format allows you to specify the alignment +requirements of a common variable: + + common commvar 4:near ; works in OBJ + common intarray 100:4 ; works in ELF: 4 byte aligned + + Once again, like `EXTERN' and `GLOBAL', the primitive form of +`COMMON' differs from the user-level form only in that it can take only +one argument at a time. + + +File: nasm.info, Node: Section 6.8, Next: Section 6.9, Prev: Section 6.7, Up: Chapter 6 + +6.8. `CPU': Defining CPU Dependencies +===================================== + +The `CPU' directive restricts assembly to those instructions which are +available on the specified CPU. + + Options are: + + * `CPU 8086' Assemble only 8086 instruction set + + * `CPU 186' Assemble instructions up to the 80186 instruction set + + * `CPU 286' Assemble instructions up to the 286 instruction set + + * `CPU 386' Assemble instructions up to the 386 instruction set + + * `CPU 486' 486 instruction set + + * `CPU 586' Pentium instruction set + + * `CPU PENTIUM' Same as 586 + + * `CPU 686' P6 instruction set + + * `CPU PPRO' Same as 686 + + * `CPU P2' Same as 686 + + * `CPU P3' Pentium III (Katmai) instruction sets + + * `CPU KATMAI' Same as P3 + + * `CPU P4' Pentium 4 (Willamette) instruction set + + * `CPU WILLAMETTE' Same as P4 + + * `CPU PRESCOTT' Prescott instruction set + + * `CPU X64' x86-64 (x64/AMD64/Intel 64) instruction set + + * `CPU IA64' IA64 CPU (in x86 mode) instruction set + + All options are case insensitive. All instructions will be selected +only if they apply to the selected CPU or lower. By default, all +instructions are available. + + +File: nasm.info, Node: Section 6.9, Next: Chapter 7, Prev: Section 6.8, Up: Chapter 6 + +6.9. `FLOAT': Handling of floating-point constants +================================================== + +By default, floating-point constants are rounded to nearest, and IEEE +denormals are supported. The following options can be set to alter this +behaviour: + + * `FLOAT DAZ' Flush denormals to zero + + * `FLOAT NODAZ' Do not flush denormals to zero (default) + + * `FLOAT NEAR' Round to nearest (default) + + * `FLOAT UP' Round up (toward +Infinity) + + * `FLOAT DOWN' Round down (toward -Infinity) + + * `FLOAT ZERO' Round toward zero + + * `FLOAT DEFAULT' Restore default settings + + The standard macros `__FLOAT_DAZ__', `__FLOAT_ROUND__', and +`__FLOAT__' contain the current state, as long as the programmer has +avoided the use of the brackeded primitive form, (`[FLOAT]'). + + `__FLOAT__' contains the full set of floating-point settings; this +value can be saved away and invoked later to restore the setting. + + +File: nasm.info, Node: Chapter 7, Next: Section 7.1, Prev: Section 6.9, Up: Top + +Chapter 7: Output Formats +************************* + +NASM is a portable assembler, designed to be able to compile on any +ANSI C- supporting platform and produce output to run on a variety of +Intel x86 operating systems. For this reason, it has a large number of +available output formats, selected using the `-f' option on the NASM +command line. Each of these formats, along with its extensions to the +base NASM syntax, is detailed in this chapter. + + As stated in *note Section 2.1.1::, NASM chooses a default name for +your output file based on the input file name and the chosen output +format. This will be generated by removing the extension (`.asm', `.s', +or whatever you like to use) from the input file name, and substituting +an extension defined by the output format. The extensions are given +with each format below. + +* Menu: + +* Section 7.1:: `bin': Flat-Form Binary Output +* Section 7.2:: `ith': Intel Hex Output +* Section 7.3:: `srec': Motorola S-Records Output +* Section 7.4:: `obj': Microsoft OMF Object Files +* Section 7.5:: `win32': Microsoft Win32 Object Files +* Section 7.6:: `win64': Microsoft Win64 Object Files +* Section 7.7:: `coff': Common Object File Format +* Section 7.8:: `macho32' and `macho64': Mach Object File Format +* Section 7.9:: `elf32' and `elf64': Executable and Linkable Format Object Files +* Section 7.10:: `aout': Linux `a.out' Object Files +* Section 7.11:: `aoutb': NetBSD/FreeBSD/OpenBSD `a.out' Object Files +* Section 7.12:: `as86': Minix/Linux `as86' Object Files +* Section 7.13:: `rdf': Relocatable Dynamic Object File Format +* Section 7.14:: `dbg': Debugging Format + + +File: nasm.info, Node: Section 7.1, Next: Section 7.1.1, Prev: Chapter 7, Up: Chapter 7 + +7.1. `bin': Flat-Form Binary Output +=================================== + +The `bin' format does not produce object files: it generates nothing in +the output file except the code you wrote. Such `pure binary' files are +used by MS-DOS: `.COM' executables and `.SYS' device drivers are pure +binary files. Pure binary output is also useful for operating system +and boot loader development. + + The `bin' format supports multiple section names. For details of how +NASM handles sections in the `bin' format, see *note Section 7.1.3::. + + Using the `bin' format puts NASM by default into 16-bit mode (see +*note Section 6.1::). In order to use `bin' to write 32-bit or 64-bit +code, such as an OS kernel, you need to explicitly issue the `BITS 32' +or `BITS 64' directive. + + `bin' has no default output file name extension: instead, it leaves +your file name as it is once the original extension has been removed. +Thus, the default is for NASM to assemble `binprog.asm' into a binary +file called `binprog'. + +* Menu: + +* Section 7.1.1:: `ORG': Binary File Program Origin +* Section 7.1.2:: `bin' Extensions to the `SECTION' Directive +* Section 7.1.3:: Multisection Support for the `bin' Format +* Section 7.1.4:: Map Files + + +File: nasm.info, Node: Section 7.1.1, Next: Section 7.1.2, Prev: Section 7.1, Up: Section 7.1 + +7.1.1. `ORG': Binary File Program Origin +---------------------------------------- + +The `bin' format provides an additional directive to the list given in +*note Chapter 6::: `ORG'. The function of the `ORG' directive is to +specify the origin address which NASM will assume the program begins at +when it is loaded into memory. + + For example, the following code will generate the longword +`0x00000104': + + org 0x100 + dd label + label: + + Unlike the `ORG' directive provided by MASM-compatible assemblers, +which allows you to jump around in the object file and overwrite code +you have already generated, NASM's `ORG' does exactly what the directive +says: _origin_. Its sole function is to specify one offset which is +added to all internal address references within the section; it does not +permit any of the trickery that MASM's version does. See *note Section +12.1.3:: for further comments. + + +File: nasm.info, Node: Section 7.1.2, Next: Section 7.1.3, Prev: Section 7.1.1, Up: Section 7.1 + +7.1.2. `bin' Extensions to the `SECTION' Directive +-------------------------------------------------- + +The `bin' output format extends the `SECTION' (or `SEGMENT') directive +to allow you to specify the alignment requirements of segments. This +is done by appending the `ALIGN' qualifier to the end of the +section-definition line. For example, + + section .data align=16 + + switches to the section `.data' and also specifies that it must be +aligned on a 16-byte boundary. + + The parameter to `ALIGN' specifies how many low bits of the section +start address must be forced to zero. The alignment value given may be +any power of two. + + +File: nasm.info, Node: Section 7.1.3, Next: Section 7.1.4, Prev: Section 7.1.2, Up: Section 7.1 + +7.1.3. Multisection Support for the `bin' Format +------------------------------------------------ + +The `bin' format allows the use of multiple sections, of arbitrary +names, besides the "known" `.text', `.data', and `.bss' names. + + * Sections may be designated `progbits' or `nobits'. Default is + `progbits' (except `.bss', which defaults to `nobits', of course). + + * Sections can be aligned at a specified boundary following the + previous section with `align=', or at an arbitrary byte-granular + position with `start='. + + * Sections can be given a virtual start address, which will be used + for the calculation of all memory references within that section + with `vstart='. + + * Sections can be ordered using `follows='`<section>' or + `vfollows='`<section>' as an alternative to specifying an explicit + start address. + + * Arguments to `org', `start', `vstart', and `align=' are critical + expressions. See *note Section 3.8::. E.g. `align=(1 << + ALIGN_SHIFT)' - `ALIGN_SHIFT' must be defined before it is used + here. + + * Any code which comes before an explicit `SECTION' directive is + directed by default into the `.text' section. + + * If an `ORG' statement is not given, `ORG 0' is used by default. + + * The `.bss' section will be placed after the last `progbits' + section, unless `start=', `vstart=', `follows=', or `vfollows=' + has been specified. + + * All sections are aligned on dword boundaries, unless a different + alignment has been specified. + + * Sections may not overlap. + + * NASM creates the `section.<secname>.start' for each section, which + may be used in your code. + + +File: nasm.info, Node: Section 7.1.4, Next: Section 7.2, Prev: Section 7.1.3, Up: Section 7.1 + +7.1.4. Map Files +---------------- + +Map files can be generated in `-f bin' format by means of the `[map]' +option. Map types of `all' (default), `brief', `sections', `segments', +or `symbols' may be specified. Output may be directed to `stdout' +(default), `stderr', or a specified file. E.g. `[map symbols +myfile.map]'. No "user form" exists, the square brackets must be used. + + +File: nasm.info, Node: Section 7.2, Next: Section 7.3, Prev: Section 7.1.4, Up: Chapter 7 + +7.2. `ith': Intel Hex Output +============================ + +The `ith' file format produces Intel hex-format files. Just as the +`bin' format, this is a flat memory image format with no support for +relocation or linking. It is usually used with ROM programmers and +similar utilities. + + All extensions supported by the `bin' file format is also supported +by the `ith' file format. + + `ith' provides a default output file-name extension of `.ith'. + + +File: nasm.info, Node: Section 7.3, Next: Section 7.4, Prev: Section 7.2, Up: Chapter 7 + +7.3. `srec': Motorola S-Records Output +====================================== + +The `srec' file format produces Motorola S-records files. Just as the +`bin' format, this is a flat memory image format with no support for +relocation or linking. It is usually used with ROM programmers and +similar utilities. + + All extensions supported by the `bin' file format is also supported +by the `srec' file format. + + `srec' provides a default output file-name extension of `.srec'. + + +File: nasm.info, Node: Section 7.4, Next: Section 7.4.1, Prev: Section 7.3, Up: Chapter 7 + +7.4. `obj': Microsoft OMF Object Files +====================================== + +The `obj' file format (NASM calls it `obj' rather than `omf' for +historical reasons) is the one produced by MASM and TASM, which is +typically fed to 16-bit DOS linkers to produce `.EXE' files. It is also +the format used by OS/2. + + `obj' provides a default output file-name extension of `.obj'. + + `obj' is not exclusively a 16-bit format, though: NASM has full +support for the 32-bit extensions to the format. In particular, 32-bit +`obj' format files are used by Borland's Win32 compilers, instead of +using Microsoft's newer `win32' object file format. + + The `obj' format does not define any special segment names: you can +call your segments anything you like. Typical names for segments in +`obj' format files are `CODE', `DATA' and `BSS'. + + If your source file contains code before specifying an explicit +`SEGMENT' directive, then NASM will invent its own segment called +`__NASMDEFSEG' for you. + + When you define a segment in an `obj' file, NASM defines the segment +name as a symbol as well, so that you can access the segment address of +the segment. So, for example: + + segment data + + dvar: dw 1234 + + segment code + + function: + mov ax,data ; get segment address of data + mov ds,ax ; and move it into DS + inc word [dvar] ; now this reference will work + ret + + The `obj' format also enables the use of the `SEG' and `WRT' +operators, so that you can write code which does things like + + extern foo + + mov ax,seg foo ; get preferred segment of foo + mov ds,ax + mov ax,data ; a different segment + mov es,ax + mov ax,[ds:foo] ; this accesses `foo' + mov [es:foo wrt data],bx ; so does this + +* Menu: + +* Section 7.4.1:: `obj' Extensions to the `SEGMENT' Directive +* Section 7.4.2:: `GROUP': Defining Groups of Segments +* Section 7.4.3:: `UPPERCASE': Disabling Case Sensitivity in Output +* Section 7.4.4:: `IMPORT': Importing DLL Symbols +* Section 7.4.5:: `EXPORT': Exporting DLL Symbols +* Section 7.4.6:: `..start': Defining the Program Entry Point +* Section 7.4.7:: `obj' Extensions to the `EXTERN' Directive +* Section 7.4.8:: `obj' Extensions to the `COMMON' Directive + + +File: nasm.info, Node: Section 7.4.1, Next: Section 7.4.2, Prev: Section 7.4, Up: Section 7.4 + +7.4.1. `obj' Extensions to the `SEGMENT' Directive +-------------------------------------------------- + +The `obj' output format extends the `SEGMENT' (or `SECTION') directive +to allow you to specify various properties of the segment you are +defining. This is done by appending extra qualifiers to the end of the +segment-definition line. For example, + + segment code private align=16 + + defines the segment `code', but also declares it to be a private +segment, and requires that the portion of it described in this code +module must be aligned on a 16-byte boundary. + + The available qualifiers are: + + * `PRIVATE', `PUBLIC', `COMMON' and `STACK' specify the combination + characteristics of the segment. `PRIVATE' segments do not get + combined with any others by the linker; `PUBLIC' and `STACK' + segments get concatenated together at link time; and `COMMON' + segments all get overlaid on top of each other rather than stuck + end-to-end. + + * `ALIGN' is used, as shown above, to specify how many low bits of + the segment start address must be forced to zero. The alignment + value given may be any power of two from 1 to 4096; in reality, + the only values supported are 1, 2, 4, 16, 256 and 4096, so if 8 + is specified it will be rounded up to 16, and 32, 64 and 128 will + all be rounded up to 256, and so on. Note that alignment to + 4096-byte boundaries is a PharLap extension to the format and may + not be supported by all linkers. + + * `CLASS' can be used to specify the segment class; this feature + indicates to the linker that segments of the same class should be + placed near each other in the output file. The class name can be + any word, e.g. `CLASS=CODE'. + + * `OVERLAY', like `CLASS', is specified with an arbitrary word as an + argument, and provides overlay information to an overlay-capable + linker. + + * Segments can be declared as `USE16' or `USE32', which has the + effect of recording the choice in the object file and also + ensuring that NASM's default assembly mode when assembling in that + segment is 16-bit or 32-bit respectively. + + * When writing OS/2 object files, you should declare 32-bit segments + as `FLAT', which causes the default segment base for anything in + the segment to be the special group `FLAT', and also defines the + group if it is not already defined. + + * The `obj' file format also allows segments to be declared as + having a pre-defined absolute segment address, although no linkers + are currently known to make sensible use of this feature; + nevertheless, NASM allows you to declare a segment such as + `SEGMENT SCREEN ABSOLUTE=0xB800' if you need to. The `ABSOLUTE' + and `ALIGN' keywords are mutually exclusive. + + NASM's default segment attributes are `PUBLIC', `ALIGN=1', no class, +no overlay, and `USE16'. + + +File: nasm.info, Node: Section 7.4.2, Next: Section 7.4.3, Prev: Section 7.4.1, Up: Section 7.4 + +7.4.2. `GROUP': Defining Groups of Segments +------------------------------------------- + +The `obj' format also allows segments to be grouped, so that a single +segment register can be used to refer to all the segments in a group. +NASM therefore supplies the `GROUP' directive, whereby you can code + + segment data + + ; some data + + segment bss + + ; some uninitialized data + + group dgroup data bss + + which will define a group called `dgroup' to contain the segments +`data' and `bss'. Like `SEGMENT', `GROUP' causes the group name to be +defined as a symbol, so that you can refer to a variable `var' in the +`data' segment as `var wrt data' or as `var wrt dgroup', depending on +which segment value is currently in your segment register. + + If you just refer to `var', however, and `var' is declared in a +segment which is part of a group, then NASM will default to giving you +the offset of `var' from the beginning of the _group_, not the +_segment_. Therefore `SEG var', also, will return the group base rather +than the segment base. + + NASM will allow a segment to be part of more than one group, but will +generate a warning if you do this. Variables declared in a segment +which is part of more than one group will default to being relative to +the first group that was defined to contain the segment. + + A group does not have to contain any segments; you can still make +`WRT' references to a group which does not contain the variable you are +referring to. OS/2, for example, defines the special group `FLAT' with +no segments in it. + + +File: nasm.info, Node: Section 7.4.3, Next: Section 7.4.4, Prev: Section 7.4.2, Up: Section 7.4 + +7.4.3. `UPPERCASE': Disabling Case Sensitivity in Output +-------------------------------------------------------- + +Although NASM itself is case sensitive, some OMF linkers are not; +therefore it can be useful for NASM to output single-case object files. +The `UPPERCASE' format-specific directive causes all segment, group and +symbol names that are written to the object file to be forced to upper +case just before being written. Within a source file, NASM is still +case- sensitive; but the object file can be written entirely in upper +case if desired. + + `UPPERCASE' is used alone on a line; it requires no parameters. + + +File: nasm.info, Node: Section 7.4.4, Next: Section 7.4.5, Prev: Section 7.4.3, Up: Section 7.4 + +7.4.4. `IMPORT': Importing DLL Symbols +-------------------------------------- + +The `IMPORT' format-specific directive defines a symbol to be imported +from a DLL, for use if you are writing a DLL's import library in NASM. +You still need to declare the symbol as `EXTERN' as well as using the +`IMPORT' directive. + + The `IMPORT' directive takes two required parameters, separated by +white space, which are (respectively) the name of the symbol you wish to +import and the name of the library you wish to import it from. For +example: + + import WSAStartup wsock32.dll + + A third optional parameter gives the name by which the symbol is +known in the library you are importing it from, in case this is not the +same as the name you wish the symbol to be known by to your code once +you have imported it. For example: + + import asyncsel wsock32.dll WSAAsyncSelect + + +File: nasm.info, Node: Section 7.4.5, Next: Section 7.4.6, Prev: Section 7.4.4, Up: Section 7.4 + +7.4.5. `EXPORT': Exporting DLL Symbols +-------------------------------------- + +The `EXPORT' format-specific directive defines a global symbol to be +exported as a DLL symbol, for use if you are writing a DLL in NASM. You +still need to declare the symbol as `GLOBAL' as well as using the +`EXPORT' directive. + + `EXPORT' takes one required parameter, which is the name of the +symbol you wish to export, as it was defined in your source file. An +optional second parameter (separated by white space from the first) +gives the _external_ name of the symbol: the name by which you wish the +symbol to be known to programs using the DLL. If this name is the same +as the internal name, you may leave the second parameter off. + + Further parameters can be given to define attributes of the exported +symbol. These parameters, like the second, are separated by white +space. If further parameters are given, the external name must also be +specified, even if it is the same as the internal name. The available +attributes are: + + * `resident' indicates that the exported name is to be kept resident + by the system loader. This is an optimisation for frequently used + symbols imported by name. + + * `nodata' indicates that the exported symbol is a function which + does not make use of any initialized data. + + * `parm=NNN', where `NNN' is an integer, sets the number of + parameter words for the case in which the symbol is a call gate + between 32- bit and 16-bit segments. + + * An attribute which is just a number indicates that the symbol + should be exported with an identifying number (ordinal), and gives + the desired number. + + For example: + + export myfunc + export myfunc TheRealMoreFormalLookingFunctionName + export myfunc myfunc 1234 ; export by ordinal + export myfunc myfunc resident parm=23 nodata + + +File: nasm.info, Node: Section 7.4.6, Next: Section 7.4.7, Prev: Section 7.4.5, Up: Section 7.4 + +7.4.6. `..start': Defining the Program Entry Point +-------------------------------------------------- + +`OMF' linkers require exactly one of the object files being linked to +define the program entry point, where execution will begin when the +program is run. If the object file that defines the entry point is +assembled using NASM, you specify the entry point by declaring the +special symbol `..start' at the point where you wish execution to begin. + + +File: nasm.info, Node: Section 7.4.7, Next: Section 7.4.8, Prev: Section 7.4.6, Up: Section 7.4 + +7.4.7. `obj' Extensions to the `EXTERN' Directive +------------------------------------------------- + +If you declare an external symbol with the directive + + extern foo + + then references such as `mov ax,foo' will give you the offset of +`foo' from its preferred segment base (as specified in whichever module +`foo' is actually defined in). So to access the contents of `foo' you +will usually need to do something like + + mov ax,seg foo ; get preferred segment base + mov es,ax ; move it into ES + mov ax,[es:foo] ; and use offset `foo' from it + + This is a little unwieldy, particularly if you know that an external +is going to be accessible from a given segment or group, say `dgroup'. +So if `DS' already contained `dgroup', you could simply code + + mov ax,[foo wrt dgroup] + + However, having to type this every time you want to access `foo' can +be a pain; so NASM allows you to declare `foo' in the alternative form + + extern foo:wrt dgroup + + This form causes NASM to pretend that the preferred segment base of +`foo' is in fact `dgroup'; so the expression `seg foo' will now return +`dgroup', and the expression `foo' is equivalent to `foo wrt dgroup'. + + This default-`WRT' mechanism can be used to make externals appear to +be relative to any group or segment in your program. It can also be +applied to common variables: see *note Section 7.4.8::. + + +File: nasm.info, Node: Section 7.4.8, Next: Section 7.5, Prev: Section 7.4.7, Up: Section 7.4 + +7.4.8. `obj' Extensions to the `COMMON' Directive +------------------------------------------------- + +The `obj' format allows common variables to be either near or far; NASM +allows you to specify which your variables should be by the use of the +syntax + + common nearvar 2:near ; `nearvar' is a near common + common farvar 10:far ; and `farvar' is far + + Far common variables may be greater in size than 64Kb, and so the OMF +specification says that they are declared as a number of _elements_ of +a given size. So a 10-byte far common variable could be declared as ten +one-byte elements, five two-byte elements, two five-byte elements or one +ten-byte element. + + Some `OMF' linkers require the element size, as well as the variable +size, to match when resolving common variables declared in more than one +module. Therefore NASM must allow you to specify the element size on +your far common variables. This is done by the following syntax: + + common c_5by2 10:far 5 ; two five-byte elements + common c_2by5 10:far 2 ; five two-byte elements + + If no element size is specified, the default is 1. Also, the `FAR' +keyword is not required when an element size is specified, since only +far commons may have element sizes at all. So the above declarations +could equivalently be + + common c_5by2 10:5 ; two five-byte elements + common c_2by5 10:2 ; five two-byte elements + + In addition to these extensions, the `COMMON' directive in `obj' +also supports default-`WRT' specification like `EXTERN' does (explained +in *note Section 7.4.7::). So you can also declare things like + + common foo 10:wrt dgroup + common bar 16:far 2:wrt data + common baz 24:wrt data:6 + + +File: nasm.info, Node: Section 7.5, Next: Section 7.5.1, Prev: Section 7.4.8, Up: Chapter 7 + +7.5. `win32': Microsoft Win32 Object Files +========================================== + +The `win32' output format generates Microsoft Win32 object files, +suitable for passing to Microsoft linkers such as Visual C++. Note that +Borland Win32 compilers do not use this format, but use `obj' instead +(see *note Section 7.4::). + + `win32' provides a default output file-name extension of `.obj'. + + Note that although Microsoft say that Win32 object files follow the +`COFF' (Common Object File Format) standard, the object files produced +by Microsoft Win32 compilers are not compatible with COFF linkers such +as DJGPP's, and vice versa. This is due to a difference of opinion over +the precise semantics of PC-relative relocations. To produce COFF files +suitable for DJGPP, use NASM's `coff' output format; conversely, the +`coff' format does not produce object files that Win32 linkers can +generate correct output from. + +* Menu: + +* Section 7.5.1:: `win32' Extensions to the `SECTION' Directive +* Section 7.5.2:: `win32': Safe Structured Exception Handling + + +File: nasm.info, Node: Section 7.5.1, Next: Section 7.5.2, Prev: Section 7.5, Up: Section 7.5 + +7.5.1. `win32' Extensions to the `SECTION' Directive +---------------------------------------------------- + +Like the `obj' format, `win32' allows you to specify additional +information on the `SECTION' directive line, to control the type and +properties of sections you declare. Section types and properties are +generated automatically by NASM for the standard section names `.text', +`.data' and `.bss', but may still be overridden by these qualifiers. + + The available qualifiers are: + + * `code', or equivalently `text', defines the section to be a code + section. This marks the section as readable and executable, but not + writable, and also indicates to the linker that the type of the + section is code. + + * `data' and `bss' define the section to be a data section, + analogously to `code'. Data sections are marked as readable and + writable, but not executable. `data' declares an initialized data + section, whereas `bss' declares an uninitialized data section. + + * `rdata' declares an initialized data section that is readable but + not writable. Microsoft compilers use this section to place + constants in it. + + * `info' defines the section to be an informational section, which is + not included in the executable file by the linker, but may (for + example) pass information _to_ the linker. For example, declaring + an `info'-type section called `.drectve' causes the linker to + interpret the contents of the section as command-line options. + + * `align=', used with a trailing number as in `obj', gives the + alignment requirements of the section. The maximum you may specify + is 64: the Win32 object file format contains no means to request a + greater section alignment than this. If alignment is not + explicitly specified, the defaults are 16-byte alignment for code + sections, 8-byte alignment for rdata sections and 4-byte alignment + for data (and BSS) sections. Informational sections get a default + alignment of 1 byte (no alignment), though the value does not + matter. + + The defaults assumed by NASM if you do not specify the above +qualifiers are: + + section .text code align=16 + section .data data align=4 + section .rdata rdata align=8 + section .bss bss align=4 + + Any other section name is treated by default like `.text'. + + +File: nasm.info, Node: Section 7.5.2, Next: Section 7.6, Prev: Section 7.5.1, Up: Section 7.5 + +7.5.2. `win32': Safe Structured Exception Handling +-------------------------------------------------- + +Among other improvements in Windows XP SP2 and Windows Server 2003 +Microsoft has introduced concept of "safe structured exception +handling." General idea is to collect handlers' entry points in +designated read-only table and have alleged entry point verified +against this table prior exception control is passed to the handler. In +order for an executable module to be equipped with such "safe exception +handler table," all object modules on linker command line has to comply +with certain criteria. If one single module among them does not, then +the table in question is omitted and above mentioned run-time checks +will not be performed for application in question. Table omission is by +default silent and therefore can be easily overlooked. One can instruct +linker to refuse to produce binary without such table by passing +`/safeseh' command line option. + + Without regard to this run-time check merits it's natural to expect +NASM to be capable of generating modules suitable for `/safeseh' +linking. From developer's viewpoint the problem is two-fold: + + * how to adapt modules not deploying exception handlers of their own; + + * how to adapt/develop modules utilizing custom exception handling; + + Former can be easily achieved with any NASM version by adding +following line to source code: + + $@feat.00 equ 1 + + As of version 2.03 NASM adds this absolute symbol automatically. If +it's not already present to be precise. I.e. if for whatever reason +developer would choose to assign another value in source file, it would +still be perfectly possible. + + Registering custom exception handler on the other hand requires +certain "magic." As of version 2.03 additional directive is implemented, +`safeseh', which instructs the assembler to produce appropriately +formatted input data for above mentioned "safe exception handler table." +Its typical use would be: + + section .text + extern _MessageBoxA@16 + %if __NASM_VERSION_ID__ >= 0x02030000 + safeseh handler ; register handler as "safe handler" + %endif + handler: + push DWORD 1 ; MB_OKCANCEL + push DWORD caption + push DWORD text + push DWORD 0 + call _MessageBoxA@16 + sub eax,1 ; incidentally suits as return value + ; for exception handler + ret + global _main + _main: + push DWORD handler + push DWORD [fs:0] + mov DWORD [fs:0],esp ; engage exception handler + xor eax,eax + mov eax,DWORD[eax] ; cause exception + pop DWORD [fs:0] ; disengage exception handler + add esp,4 + ret + text: db 'OK to rethrow, CANCEL to generate core dump',0 + caption:db 'SEGV',0 + + section .drectve info + db '/defaultlib:user32.lib /defaultlib:msvcrt.lib ' + + As you might imagine, it's perfectly possible to produce .exe binary +with "safe exception handler table" and yet engage unregistered +exception handler. Indeed, handler is engaged by simply manipulating +`[fs:0]' location at run-time, something linker has no power over, +run-time that is. It should be explicitly mentioned that such failure +to register handler's entry point with `safeseh' directive has +undesired side effect at run- time. If exception is raised and +unregistered handler is to be executed, the application is abruptly +terminated without any notification whatsoever. One can argue that +system could at least have logged some kind "non-safe exception handler +in x.exe at address n" message in event log, but no, literally no +notification is provided and user is left with no clue on what caused +application failure. + + Finally, all mentions of linker in this paragraph refer to Microsoft +linker version 7.x and later. Presence of `@feat.00' symbol and input +data for "safe exception handler table" causes no backward +incompatibilities and "safeseh" modules generated by NASM 2.03 and +later can still be linked by earlier versions or non-Microsoft linkers. + + +File: nasm.info, Node: Section 7.6, Next: Section 7.6.1, Prev: Section 7.5.2, Up: Chapter 7 + +7.6. `win64': Microsoft Win64 Object Files +========================================== + +The `win64' output format generates Microsoft Win64 object files, which +is nearly 100% identical to the `win32' object format (*note Section +7.5::) with the exception that it is meant to target 64-bit code and +the x86-64 platform altogether. This object file is used exactly the +same as the `win32' object format (*note Section 7.5::), in NASM, with +regard to this exception. + +* Menu: + +* Section 7.6.1:: `win64': Writing Position-Independent Code +* Section 7.6.2:: `win64': Structured Exception Handling + + +File: nasm.info, Node: Section 7.6.1, Next: Section 7.6.2, Prev: Section 7.6, Up: Section 7.6 + +7.6.1. `win64': Writing Position-Independent Code +------------------------------------------------- + +While `REL' takes good care of RIP-relative addressing, there is one +aspect that is easy to overlook for a Win64 programmer: indirect +references. Consider a switch dispatch table: + + jmp QWORD[dsptch+rax*8] + ... + dsptch: dq case0 + dq case1 + ... + + Even novice Win64 assembler programmer will soon realize that the +code is not 64-bit savvy. Most notably linker will refuse to link it +with "`'ADDR32' relocation to '.text' invalid without +/LARGEADDRESSAWARE:NO'". So [s]he will have to split jmp instruction +as following: + + lea rbx,[rel dsptch] + jmp QWORD[rbx+rax*8] + + What happens behind the scene is that effective address in `lea' is +encoded relative to instruction pointer, or in perfectly position- +independent manner. But this is only part of the problem! Trouble is +that in .dll context `caseN' relocations will make their way to the +final module and might have to be adjusted at .dll load time. To be +specific when it can't be loaded at preferred address. And when this +occurs, pages with such relocations will be rendered private to current +process, which kind of undermines the idea of sharing .dll. But no +worry, it's trivial to fix: + + lea rbx,[rel dsptch] + add rbx,QWORD[rbx+rax*8] + jmp rbx + ... + dsptch: dq case0-dsptch + dq case1-dsptch + ... + + NASM version 2.03 and later provides another alternative, `wrt +..imagebase' operator, which returns offset from base address of the +current image, be it .exe or .dll module, therefore the name. For those +acquainted with PE-COFF format base address denotes start of +`IMAGE_DOS_HEADER' structure. Here is how to implement switch with +these image-relative references: + + lea rbx,[rel dsptch] + mov eax,DWORD[rbx+rax*4] + sub rbx,dsptch wrt ..imagebase + add rbx,rax + jmp rbx + ... + dsptch: dd case0 wrt ..imagebase + dd case1 wrt ..imagebase + + One can argue that the operator is redundant. Indeed, snippet before +last works just fine with any NASM version and is not even Windows +specific... The real reason for implementing `wrt ..imagebase' will +become apparent in next paragraph. + + It should be noted that `wrt ..imagebase' is defined as 32-bit +operand only: + + dd label wrt ..imagebase ; ok + dq label wrt ..imagebase ; bad + mov eax,label wrt ..imagebase ; ok + mov rax,label wrt ..imagebase ; bad + + +File: nasm.info, Node: Section 7.6.2, Next: Section 7.7, Prev: Section 7.6.1, Up: Section 7.6 + +7.6.2. `win64': Structured Exception Handling +--------------------------------------------- + +Structured exception handing in Win64 is completely different matter +from Win32. Upon exception program counter value is noted, and +linker-generated table comprising start and end addresses of all the +functions [in given executable module] is traversed and compared to the +saved program counter. Thus so called `UNWIND_INFO' structure is +identified. If it's not found, then offending subroutine is assumed to +be "leaf" and just mentioned lookup procedure is attempted for its +caller. In Win64 leaf function is such function that does not call any +other function _nor_ modifies any Win64 non-volatile registers, +including stack pointer. The latter ensures that it's possible to +identify leaf function's caller by simply pulling the value from the +top of the stack. + + While majority of subroutines written in assembler are not calling +any other function, requirement for non-volatile registers' +immutability leaves developer with not more than 7 registers and no +stack frame, which is not necessarily what [s]he counted with. +Customarily one would meet the requirement by saving non-volatile +registers on stack and restoring them upon return, so what can go +wrong? If [and only if] an exception is raised at run-time and no +`UNWIND_INFO' structure is associated with such "leaf" function, the +stack unwind procedure will expect to find caller's return address on +the top of stack immediately followed by its frame. Given that +developer pushed caller's non-volatile registers on stack, would the +value on top point at some code segment or even addressable space? Well, +developer can attempt copying caller's return address to the top of +stack and this would actually work in some very specific circumstances. +But unless developer can guarantee that these circumstances are always +met, it's more appropriate to assume worst case scenario, i.e. stack +unwind procedure going berserk. Relevant question is what happens then? +Application is abruptly terminated without any notification whatsoever. +Just like in Win32 case, one can argue that system could at least have +logged "unwind procedure went berserk in x.exe at address n" in event +log, but no, no trace of failure is left. + + Now, when we understand significance of the `UNWIND_INFO' structure, +let's discuss what's in it and/or how it's processed. First of all it is +checked for presence of reference to custom language-specific exception +handler. If there is one, then it's invoked. Depending on the return +value, execution flow is resumed (exception is said to be "handled"), +_or_ rest of `UNWIND_INFO' structure is processed as following. Beside +optional reference to custom handler, it carries information about +current callee's stack frame and where non-volatile registers are saved. +Information is detailed enough to be able to reconstruct contents of +caller's non-volatile registers upon call to current callee. And so +caller's context is reconstructed, and then unwind procedure is +repeated, i.e. another `UNWIND_INFO' structure is associated, this +time, with caller's instruction pointer, which is then checked for +presence of reference to language-specific handler, etc. The procedure +is recursively repeated till exception is handled. As last resort +system "handles" it by generating memory core dump and terminating the +application. + + As for the moment of this writing NASM unfortunately does not +facilitate generation of above mentioned detailed information about +stack frame layout. But as of version 2.03 it implements building +blocks for generating structures involved in stack unwinding. As +simplest example, here is how to deploy custom exception handler for +leaf function: + + default rel + section .text + extern MessageBoxA + handler: + sub rsp,40 + mov rcx,0 + lea rdx,[text] + lea r8,[caption] + mov r9,1 ; MB_OKCANCEL + call MessageBoxA + sub eax,1 ; incidentally suits as return value + ; for exception handler + add rsp,40 + ret + global main + main: + xor rax,rax + mov rax,QWORD[rax] ; cause exception + ret + main_end: + text: db 'OK to rethrow, CANCEL to generate core dump',0 + caption:db 'SEGV',0 + + section .pdata rdata align=4 + dd main wrt ..imagebase + dd main_end wrt ..imagebase + dd xmain wrt ..imagebase + section .xdata rdata align=8 + xmain: db 9,0,0,0 + dd handler wrt ..imagebase + section .drectve info + db '/defaultlib:user32.lib /defaultlib:msvcrt.lib ' + + What you see in `.pdata' section is element of the "table comprising +start and end addresses of function" along with reference to associated +`UNWIND_INFO' structure. And what you see in `.xdata' section is +`UNWIND_INFO' structure describing function with no frame, but with +designated exception handler. References are _required_ to be image- +relative (which is the real reason for implementing `wrt ..imagebase' +operator). It should be noted that `rdata align=n', as well as `wrt +..imagebase', are optional in these two segments' contexts, i.e. can +be omitted. Latter means that _all_ 32-bit references, not only above +listed required ones, placed into these two segments turn out image- +relative. Why is it important to understand? Developer is allowed to +append handler-specific data to `UNWIND_INFO' structure, and if [s]he +adds a 32-bit reference, then [s]he will have to remember to adjust its +value to obtain the real pointer. + + As already mentioned, in Win64 terms leaf function is one that does +not call any other function _nor_ modifies any non-volatile register, +including stack pointer. But it's not uncommon that assembler programmer +plans to utilize every single register and sometimes even have variable +stack frame. Is there anything one can do with bare building blocks? +I.e. besides manually composing fully-fledged `UNWIND_INFO' structure, +which would surely be considered error-prone? Yes, there is. Recall that +exception handler is called first, before stack layout is analyzed. As +it turned out, it's perfectly possible to manipulate current callee's +context in custom handler in manner that permits further stack +unwinding. General idea is that handler would not actually "handle" the +exception, but instead restore callee's context, as it was at its entry +point and thus mimic leaf function. In other words, handler would +simply undertake part of unwinding procedure. Consider following +example: + + function: + mov rax,rsp ; copy rsp to volatile register + push r15 ; save non-volatile registers + push rbx + push rbp + mov r11,rsp ; prepare variable stack frame + sub r11,rcx + and r11,-64 + mov QWORD[r11],rax ; check for exceptions + mov rsp,r11 ; allocate stack frame + mov QWORD[rsp],rax ; save original rsp value + magic_point: + ... + mov r11,QWORD[rsp] ; pull original rsp value + mov rbp,QWORD[r11-24] + mov rbx,QWORD[r11-16] + mov r15,QWORD[r11-8] + mov rsp,r11 ; destroy frame + ret + + The keyword is that up to `magic_point' original `rsp' value remains +in chosen volatile register and no non-volatile register, except for +`rsp', is modified. While past `magic_point' `rsp' remains constant +till the very end of the `function'. In this case custom +language-specific exception handler would look like this: + + EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame, + CONTEXT *context,DISPATCHER_CONTEXT *disp) + { ULONG64 *rsp; + if (context->Rip<(ULONG64)magic_point) + rsp = (ULONG64 *)context->Rax; + else + { rsp = ((ULONG64 **)context->Rsp)[0]; + context->Rbp = rsp[-3]; + context->Rbx = rsp[-2]; + context->R15 = rsp[-1]; + } + context->Rsp = (ULONG64)rsp; + + memcpy (disp->ContextRecord,context,sizeof(CONTEXT)); + RtlVirtualUnwind(UNW_FLAG_NHANDLER,disp->ImageBase, + dips->ControlPc,disp->FunctionEntry,disp->ContextRecord, + &disp->HandlerData,&disp->EstablisherFrame,NULL); + return ExceptionContinueSearch; + } + + As custom handler mimics leaf function, corresponding `UNWIND_INFO' +structure does not have to contain any information about stack frame and +its layout. + + +File: nasm.info, Node: Section 7.7, Next: Section 7.8, Prev: Section 7.6.2, Up: Chapter 7 + +7.7. `coff': Common Object File Format +====================================== + +The `coff' output type produces `COFF' object files suitable for +linking with the DJGPP linker. + + `coff' provides a default output file-name extension of `.o'. + + The `coff' format supports the same extensions to the `SECTION' +directive as `win32' does, except that the `align' qualifier and the +`info' section type are not supported. + + +File: nasm.info, Node: Section 7.8, Next: Section 7.9, Prev: Section 7.7, Up: Chapter 7 + +7.8. `macho32' and `macho64': Mach Object File Format +===================================================== + +The `macho32' and `macho64' output formts produces `Mach-O' object +files suitable for linking with the MacOS X linker. `macho' is a +synonym for `macho32'. + + `macho' provides a default output file-name extension of `.o'. + + +File: nasm.info, Node: Section 7.9, Next: Section 7.9.1, Prev: Section 7.8, Up: Chapter 7 + +7.9. `elf32' and `elf64': Executable and Linkable Format Object Files +===================================================================== + +The `elf32' and `elf64' output formats generate `ELF32 and ELF64' +(Executable and Linkable Format) object files, as used by Linux as well +as Unix System V, including Solaris x86, UnixWare and SCO Unix. `elf' +provides a default output file-name extension of `.o'. `elf' is a +synonym for `elf32'. + +* Menu: + +* Section 7.9.1:: ELF specific directive `osabi' +* Section 7.9.2:: `elf' Extensions to the `SECTION' Directive +* Section 7.9.3:: Position-Independent Code: `elf' Special Symbols and `WRT' +* Section 7.9.4:: Thread Local Storage: `elf' Special Symbols and `WRT' +* Section 7.9.5:: `elf' Extensions to the `GLOBAL' Directive +* Section 7.9.6:: `elf' Extensions to the `COMMON' Directive +* Section 7.9.7:: 16-bit code and ELF +* Section 7.9.8:: Debug formats and ELF + + +File: nasm.info, Node: Section 7.9.1, Next: Section 7.9.2, Prev: Section 7.9, Up: Section 7.9 + +7.9.1. ELF specific directive `osabi' +------------------------------------- + +The ELF header specifies the application binary interface for the target +operating system (OSABI). This field can be set by using the `osabi' +directive with the numeric value (0-255) of the target system. If this +directive is not used, the default value will be "UNIX System V ABI" (0) +which will work on most systems which support ELF. + + +File: nasm.info, Node: Section 7.9.2, Next: Section 7.9.3, Prev: Section 7.9.1, Up: Section 7.9 + +7.9.2. `elf' Extensions to the `SECTION' Directive +-------------------------------------------------- + +Like the `obj' format, `elf' allows you to specify additional +information on the `SECTION' directive line, to control the type and +properties of sections you declare. Section types and properties are +generated automatically by NASM for the standard section names, but may +still be overridden by these qualifiers. + + The available qualifiers are: + + * `alloc' defines the section to be one which is loaded into memory + when the program is run. `noalloc' defines it to be one which is + not, such as an informational or comment section. + + * `exec' defines the section to be one which should have execute + permission when the program is run. `noexec' defines it as one + which should not. + + * `write' defines the section to be one which should be writable when + the program is run. `nowrite' defines it as one which should not. + + * `progbits' defines the section to be one with explicit contents + stored in the object file: an ordinary code or data section, for + example, `nobits' defines the section to be one with no explicit + contents given, such as a BSS section. + + * `align=', used with a trailing number as in `obj', gives the + alignment requirements of the section. + + * `tls' defines the section to be one which contains thread local + variables. + + The defaults assumed by NASM if you do not specify the above +qualifiers are: + + section .text progbits alloc exec nowrite align=16 + section .rodata progbits alloc noexec nowrite align=4 + section .lrodata progbits alloc noexec nowrite align=4 + section .data progbits alloc noexec write align=4 + section .ldata progbits alloc noexec write align=4 + section .bss nobits alloc noexec write align=4 + section .lbss nobits alloc noexec write align=4 + section .tdata progbits alloc noexec write align=4 tls + section .tbss nobits alloc noexec write align=4 tls + section .comment progbits noalloc noexec nowrite align=1 + section other progbits alloc noexec nowrite align=1 + + (Any section name other than those in the above table is treated by +default like `other' in the above table. Please note that section names +are case sensitive.) + + +File: nasm.info, Node: Section 7.9.3, Next: Section 7.9.4, Prev: Section 7.9.2, Up: Section 7.9 + +7.9.3. Position-Independent Code: `elf' Special Symbols and `WRT' +----------------------------------------------------------------- + +The `ELF' specification contains enough features to allow position- +independent code (PIC) to be written, which makes ELF shared libraries +very flexible. However, it also means NASM has to be able to generate a +variety of ELF specific relocation types in ELF object files, if it is +to be an assembler which can write PIC. + + Since `ELF' does not support segment-base references, the `WRT' +operator is not used for its normal purpose; therefore NASM's `elf' +output format makes use of `WRT' for a different purpose, namely the +PIC-specific relocation types. + + `elf' defines five special symbols which you can use as the +right-hand side of the `WRT' operator to obtain PIC relocation types. +They are `..gotpc', `..gotoff', `..got', `..plt' and `..sym'. Their +functions are summarized here: + + * Referring to the symbol marking the global offset table base using + `wrt ..gotpc' will end up giving the distance from the beginning of + the current section to the global offset table. + (`_GLOBAL_OFFSET_TABLE_' is the standard symbol name used to refer + to the GOT.) So you would then need to add `$$' to the result to + get the real address of the GOT. + + * Referring to a location in one of your own sections using `wrt + ..gotoff' will give the distance from the beginning of the GOT to + the specified location, so that adding on the address of the GOT + would give the real address of the location you wanted. + + * Referring to an external or global symbol using `wrt ..got' causes + the linker to build an entry _in_ the GOT containing the address + of the symbol, and the reference gives the distance from the + beginning of the GOT to the entry; so you can add on the address + of the GOT, load from the resulting address, and end up with the + address of the symbol. + + * Referring to a procedure name using `wrt ..plt' causes the linker + to build a procedure linkage table entry for the symbol, and the + reference gives the address of the PLT entry. You can only use + this in contexts which would generate a PC-relative relocation + normally (i.e. as the destination for `CALL' or `JMP'), since ELF + contains no relocation type to refer to PLT entries absolutely. + + * Referring to a symbol name using `wrt ..sym' causes NASM to write + an ordinary relocation, but instead of making the relocation + relative to the start of the section and then adding on the offset + to the symbol, it will write a relocation record aimed directly at + the symbol in question. The distinction is a necessary one due to + a peculiarity of the dynamic linker. + + A fuller explanation of how to use these relocation types to write +shared libraries entirely in NASM is given in *note Section 9.2::. + + +File: nasm.info, Node: Section 7.9.4, Next: Section 7.9.5, Prev: Section 7.9.3, Up: Section 7.9 + +7.9.4. Thread Local Storage: `elf' Special Symbols and `WRT' +------------------------------------------------------------ + + * In ELF32 mode, referring to an external or global symbol using + `wrt ..tlsie' causes the linker to build an entry _in_ the GOT + containing the offset of the symbol within the TLS block, so you + can access the value of the symbol with code such as: + + mov eax,[tid wrt ..tlsie] + mov [gs:eax],ebx + + * In ELF64 mode, referring to an external or global symbol using + `wrt ..gottpoff' causes the linker to build an entry _in_ the GOT + containing the offset of the symbol within the TLS block, so you + can access the value of the symbol with code such as: + + mov rax,[rel tid wrt ..gottpoff] + mov rcx,[fs:rax] + + +File: nasm.info, Node: Section 7.9.5, Next: Section 7.9.6, Prev: Section 7.9.4, Up: Section 7.9 + +7.9.5. `elf' Extensions to the `GLOBAL' Directive +------------------------------------------------- + +`ELF' object files can contain more information about a global symbol +than just its address: they can contain the size of the symbol and its +type as well. These are not merely debugger conveniences, but are +actually necessary when the program being written is a shared library. +NASM therefore supports some extensions to the `GLOBAL' directive, +allowing you to specify these features. + + You can specify whether a global variable is a function or a data +object by suffixing the name with a colon and the word `function' or +`data'. (`object' is a synonym for `data'.) For example: + + global hashlookup:function, hashtable:data + + exports the global symbol `hashlookup' as a function and `hashtable' +as a data object. + + Optionally, you can control the ELF visibility of the symbol. Just +add one of the visibility keywords: `default', `internal', `hidden', or +`protected'. The default is `default' of course. For example, to make +`hashlookup' hidden: + + global hashlookup:function hidden + + You can also specify the size of the data associated with the +symbol, as a numeric expression (which may involve labels, and even +forward references) after the type specifier. Like this: + + global hashtable:data (hashtable.end - hashtable) + + hashtable: + db this,that,theother ; some data here + .end: + + This makes NASM automatically calculate the length of the table and +place that information into the `ELF' symbol table. + + Declaring the type and size of global symbols is necessary when +writing shared library code. For more information, see *note Section +9.2.4::. + + +File: nasm.info, Node: Section 7.9.6, Next: Section 7.9.7, Prev: Section 7.9.5, Up: Section 7.9 + +7.9.6. `elf' Extensions to the `COMMON' Directive +------------------------------------------------- + +`ELF' also allows you to specify alignment requirements on common +variables. This is done by putting a number (which must be a power of +two) after the name and size of the common variable, separated (as +usual) by a colon. For example, an array of doublewords would benefit +from 4-byte alignment: + + common dwordarray 128:4 + + This declares the total size of the array to be 128 bytes, and +requires that it be aligned on a 4-byte boundary. + + +File: nasm.info, Node: Section 7.9.7, Next: Section 7.9.8, Prev: Section 7.9.6, Up: Section 7.9 + +7.9.7. 16-bit code and ELF +-------------------------- + +The `ELF32' specification doesn't provide relocations for 8- and 16- +bit values, but the GNU `ld' linker adds these as an extension. NASM +can generate GNU-compatible relocations, to allow 16-bit code to be +linked as ELF using GNU `ld'. If NASM is used with the +`-w+gnu-elf-extensions' option, a warning is issued when one of these +relocations is generated. + + +File: nasm.info, Node: Section 7.9.8, Next: Section 7.10, Prev: Section 7.9.7, Up: Section 7.9 + +7.9.8. Debug formats and ELF +---------------------------- + +`ELF32' and `ELF64' provide debug information in `STABS' and `DWARF' +formats. Line number information is generated for all executable +sections, but please note that only the ".text" section is executable +by default. + + +File: nasm.info, Node: Section 7.10, Next: Section 7.11, Prev: Section 7.9.8, Up: Chapter 7 + +7.10. `aout': Linux `a.out' Object Files +======================================== + +The `aout' format generates `a.out' object files, in the form used by +early Linux systems (current Linux systems use ELF, see *note Section +7.9::.) These differ from other `a.out' object files in that the magic +number in the first four bytes of the file is different; also, some +implementations of `a.out', for example NetBSD's, support +position-independent code, which Linux's implementation does not. + + `a.out' provides a default output file-name extension of `.o'. + + `a.out' is a very simple object format. It supports no special +directives, no special symbols, no use of `SEG' or `WRT', and no +extensions to any standard directives. It supports only the three +standard section names `.text', `.data' and `.bss'. + + +File: nasm.info, Node: Section 7.11, Next: Section 7.12, Prev: Section 7.10, Up: Chapter 7 + +7.11. `aoutb': NetBSD/FreeBSD/OpenBSD `a.out' Object Files +========================================================== + +The `aoutb' format generates `a.out' object files, in the form used by +the various free `BSD Unix' clones, `NetBSD', `FreeBSD' and `OpenBSD'. +For simple object files, this object format is exactly the same as +`aout' except for the magic number in the first four bytes of the file. +However, the `aoutb' format supports position-independent code in the +same way as the `elf' format, so you can use it to write `BSD' shared +libraries. + + `aoutb' provides a default output file-name extension of `.o'. + + `aoutb' supports no special directives, no special symbols, and only +the three standard section names `.text', `.data' and `.bss'. However, +it also supports the same use of `WRT' as `elf' does, to provide +position-independent code relocation types. See *note Section 7.9.3:: +for full documentation of this feature. + + `aoutb' also supports the same extensions to the `GLOBAL' directive +as `elf' does: see *note Section 7.9.5:: for documentation of this. + + +File: nasm.info, Node: Section 7.12, Next: Section 7.13, Prev: Section 7.11, Up: Chapter 7 + +7.12. `as86': Minix/Linux `as86' Object Files +============================================= + +The Minix/Linux 16-bit assembler `as86' has its own non-standard object +file format. Although its companion linker `ld86' produces something +close to ordinary `a.out' binaries as output, the object file format +used to communicate between `as86' and `ld86' is not itself `a.out'. + + NASM supports this format, just in case it is useful, as `as86'. +`as86' provides a default output file-name extension of `.o'. + + `as86' is a very simple object format (from the NASM user's point of +view). It supports no special directives, no use of `SEG' or `WRT', and +no extensions to any standard directives. It supports only the three +standard section names `.text', `.data' and `.bss'. The only special +symbol supported is `..start'. + + +File: nasm.info, Node: Section 7.13, Next: Section 7.13.1, Prev: Section 7.12, Up: Chapter 7 + +7.13. `rdf': Relocatable Dynamic Object File Format +=================================================== + +The `rdf' output format produces `RDOFF' object files. `RDOFF' +(Relocatable Dynamic Object File Format) is a home-grown object-file +format, designed alongside NASM itself and reflecting in its file +format the internal structure of the assembler. + + `RDOFF' is not used by any well-known operating systems. Those +writing their own systems, however, may well wish to use `RDOFF' as +their object format, on the grounds that it is designed primarily for +simplicity and contains very little file-header bureaucracy. + + The Unix NASM archive, and the DOS archive which includes sources, +both contain an `rdoff' subdirectory holding a set of RDOFF utilities: +an RDF linker, an `RDF' static-library manager, an RDF file dump +utility, and a program which will load and execute an RDF executable +under Linux. + + `rdf' supports only the standard section names `.text', `.data' and +`.bss'. + +* Menu: + +* Section 7.13.1:: Requiring a Library: The `LIBRARY' Directive +* Section 7.13.2:: Specifying a Module Name: The `MODULE' Directive +* Section 7.13.3:: `rdf' Extensions to the `GLOBAL' Directive +* Section 7.13.4:: `rdf' Extensions to the `EXTERN' Directive + + +File: nasm.info, Node: Section 7.13.1, Next: Section 7.13.2, Prev: Section 7.13, Up: Section 7.13 + +7.13.1. Requiring a Library: The `LIBRARY' Directive +---------------------------------------------------- + +`RDOFF' contains a mechanism for an object file to demand a given +library to be linked to the module, either at load time or run time. +This is done by the `LIBRARY' directive, which takes one argument which +is the name of the module: + + library mylib.rdl + + +File: nasm.info, Node: Section 7.13.2, Next: Section 7.13.3, Prev: Section 7.13.1, Up: Section 7.13 + +7.13.2. Specifying a Module Name: The `MODULE' Directive +-------------------------------------------------------- + +Special `RDOFF' header record is used to store the name of the module. +It can be used, for example, by run-time loader to perform dynamic +linking. `MODULE' directive takes one argument which is the name of +current module: + + module mymodname + + Note that when you statically link modules and tell linker to strip +the symbols from output file, all module names will be stripped too. To +avoid it, you should start module names with `$', like: + + module $kernel.core + + +File: nasm.info, Node: Section 7.13.3, Next: Section 7.13.4, Prev: Section 7.13.2, Up: Section 7.13 + +7.13.3. `rdf' Extensions to the `GLOBAL' Directive +-------------------------------------------------- + +`RDOFF' global symbols can contain additional information needed by the +static linker. You can mark a global symbol as exported, thus telling +the linker do not strip it from target executable or library file. Like +in `ELF', you can also specify whether an exported symbol is a procedure +(function) or data object. + + Suffixing the name with a colon and the word `export' you make the +symbol exported: + + global sys_open:export + + To specify that exported symbol is a procedure (function), you add +the word `proc' or `function' after declaration: + + global sys_open:export proc + + Similarly, to specify exported data object, add the word `data' or +`object' to the directive: + + global kernel_ticks:export data + + +File: nasm.info, Node: Section 7.13.4, Next: Section 7.14, Prev: Section 7.13.3, Up: Section 7.13 + +7.13.4. `rdf' Extensions to the `EXTERN' Directive +-------------------------------------------------- + +By default the `EXTERN' directive in `RDOFF' declares a "pure external" +symbol (i.e. the static linker will complain if such a symbol is not +resolved). To declare an "imported" symbol, which must be resolved +later during a dynamic linking phase, `RDOFF' offers an additional +`import' modifier. As in `GLOBAL', you can also specify whether an +imported symbol is a procedure (function) or data object. For example: + + library $libc + extern _open:import + extern _printf:import proc + extern _errno:import data + + Here the directive `LIBRARY' is also included, which gives the +dynamic linker a hint as to where to find requested symbols. + + +File: nasm.info, Node: Section 7.14, Next: Chapter 8, Prev: Section 7.13.4, Up: Chapter 7 + +7.14. `dbg': Debugging Format +============================= + +The `dbg' output format is not built into NASM in the default +configuration. If you are building your own NASM executable from the +sources, you can define `OF_DBG' in `output/outform.h' or on the +compiler command line, and obtain the `dbg' output format. + + The `dbg' format does not output an object file as such; instead, it +outputs a text file which contains a complete list of all the +transactions between the main body of NASM and the output-format back +end module. It is primarily intended to aid people who want to write +their own output drivers, so that they can get a clearer idea of the +various requests the main program makes of the output driver, and in +what order they happen. + + For simple files, one can easily use the `dbg' format like this: + + nasm -f dbg filename.asm + + which will generate a diagnostic file called `filename.dbg'. However, +this will not work well on files which were designed for a different +object format, because each object format defines its own macros +(usually user- level forms of directives), and those macros will not be +defined in the `dbg' format. Therefore it can be useful to run NASM +twice, in order to do the preprocessing with the native object format +selected: + + nasm -e -f rdf -o rdfprog.i rdfprog.asm + nasm -a -f dbg rdfprog.i + + This preprocesses `rdfprog.asm' into `rdfprog.i', keeping the `rdf' +object format selected in order to make sure RDF special directives are +converted into primitive form correctly. Then the preprocessed source +is fed through the `dbg' format to generate the final diagnostic output. + + This workaround will still typically not work for programs intended +for `obj' format, because the `obj' `SEGMENT' and `GROUP' directives +have side effects of defining the segment and group names as symbols; +`dbg' will not do this, so the program will not assemble. You will have +to work around that by defining the symbols yourself (using `EXTERN', +for example) if you really need to get a `dbg' trace of an +`obj'-specific source file. + + `dbg' accepts any section name and any directives at all, and logs +them all to its output file. + + +File: nasm.info, Node: Chapter 8, Next: Section 8.1, Prev: Section 7.14, Up: Top + +Chapter 8: Writing 16-bit Code (DOS, Windows 3/3.1) +*************************************************** + +This chapter attempts to cover some of the common issues encountered +when writing 16-bit code to run under `MS-DOS' or `Windows 3.x'. It +covers how to link programs to produce `.EXE' or `.COM' files, how to +write `.SYS' device drivers, and how to interface assembly language +code with 16-bit C compilers and with Borland Pascal. + +* Menu: + +* Section 8.1:: Producing `.EXE' Files +* Section 8.2:: Producing `.COM' Files +* Section 8.3:: Producing `.SYS' Files +* Section 8.4:: Interfacing to 16-bit C Programs +* Section 8.5:: Interfacing to Borland Pascal Programs + + +File: nasm.info, Node: Section 8.1, Next: Section 8.1.1, Prev: Chapter 8, Up: Chapter 8 + +8.1. Producing `.EXE' Files +=========================== + +Any large program written under DOS needs to be built as a `.EXE' file: +only `.EXE' files have the necessary internal structure required to +span more than one 64K segment. Windows programs, also, have to be built +as `.EXE' files, since Windows does not support the `.COM' format. + + In general, you generate `.EXE' files by using the `obj' output +format to produce one or more `.OBJ' files, and then linking them +together using a linker. However, NASM also supports the direct +generation of simple DOS `.EXE' files using the `bin' output format (by +using `DB' and `DW' to construct the `.EXE' file header), and a macro +package is supplied to do this. Thanks to Yann Guidon for contributing +the code for this. + + NASM may also support `.EXE' natively as another output format in +future releases. + +* Menu: + +* Section 8.1.1:: Using the `obj' Format To Generate `.EXE' Files +* Section 8.1.2:: Using the `bin' Format To Generate `.EXE' Files + + +File: nasm.info, Node: Section 8.1.1, Next: Section 8.1.2, Prev: Section 8.1, Up: Section 8.1 + +8.1.1. Using the `obj' Format To Generate `.EXE' Files +------------------------------------------------------ + +This section describes the usual method of generating `.EXE' files by +linking `.OBJ' files together. + + Most 16-bit programming language packages come with a suitable +linker; if you have none of these, there is a free linker called VAL, +available in `LZH' archive format from `x2ftp.oulu.fi'. An LZH archiver +can be found at `ftp.simtel.net'. There is another `free' linker +(though this one doesn't come with sources) called FREELINK, available +from `www.pcorner.com'. A third, `djlink', written by DJ Delorie, is +available at `www.delorie.com'. A fourth linker, `ALINK', written by +Anthony A.J. Williams, is available at `alink.sourceforge.net'. + + When linking several `.OBJ' files into a `.EXE' file, you should +ensure that exactly one of them has a start point defined (using the +`..start' special symbol defined by the `obj' format: see *note Section +7.4.6::). If no module defines a start point, the linker will not know +what value to give the entry-point field in the output file header; if +more than one defines a start point, the linker will not know _which_ +value to use. + + An example of a NASM source file which can be assembled to a `.OBJ' +file and linked on its own to a `.EXE' is given here. It demonstrates +the basic principles of defining a stack, initialising the segment +registers, and declaring a start point. This file is also provided in +the `test' subdirectory of the NASM archives, under the name +`objexe.asm'. + + segment code + + ..start: + mov ax,data + mov ds,ax + mov ax,stack + mov ss,ax + mov sp,stacktop + + This initial piece of code sets up `DS' to point to the data segment, +and initializes `SS' and `SP' to point to the top of the provided +stack. Notice that interrupts are implicitly disabled for one +instruction after a move into `SS', precisely for this situation, so +that there's no chance of an interrupt occurring between the loads of +`SS' and `SP' and not having a stack to execute on. + + Note also that the special symbol `..start' is defined at the +beginning of this code, which means that will be the entry point into +the resulting executable file. + + mov dx,hello + mov ah,9 + int 0x21 + + The above is the main program: load `DS:DX' with a pointer to the +greeting message (`hello' is implicitly relative to the segment `data', +which was loaded into `DS' in the setup code, so the full pointer is +valid), and call the DOS print-string function. + + mov ax,0x4c00 + int 0x21 + + This terminates the program using another DOS system call. + + segment data + + hello: db 'hello, world', 13, 10, '$' + + The data segment contains the string we want to display. + + segment stack stack + resb 64 + stacktop: + + The above code declares a stack segment containing 64 bytes of +uninitialized stack space, and points `stacktop' at the top of it. The +directive `segment stack stack' defines a segment _called_ `stack', and +also of _type_ `STACK'. The latter is not necessary to the correct +running of the program, but linkers are likely to issue warnings or +errors if your program has no segment of type `STACK'. + + The above file, when assembled into a `.OBJ' file, will link on its +own to a valid `.EXE' file, which when run will print `hello, world' +and then exit. + + +File: nasm.info, Node: Section 8.1.2, Next: Section 8.2, Prev: Section 8.1.1, Up: Section 8.1 + +8.1.2. Using the `bin' Format To Generate `.EXE' Files +------------------------------------------------------ + +The `.EXE' file format is simple enough that it's possible to build a +`.EXE' file by writing a pure-binary program and sticking a 32-byte +header on the front. This header is simple enough that it can be +generated using `DB' and `DW' commands by NASM itself, so that you can +use the `bin' output format to directly generate `.EXE' files. + + Included in the NASM archives, in the `misc' subdirectory, is a file +`exebin.mac' of macros. It defines three macros: `EXE_begin', +`EXE_stack' and `EXE_end'. + + To produce a `.EXE' file using this method, you should start by using +`%include' to load the `exebin.mac' macro package into your source +file. You should then issue the `EXE_begin' macro call (which takes no +arguments) to generate the file header data. Then write code as normal +for the `bin' format - you can use all three standard sections `.text', +`.data' and `.bss'. At the end of the file you should call the +`EXE_end' macro (again, no arguments), which defines some symbols to +mark section sizes, and these symbols are referred to in the header +code generated by `EXE_begin'. + + In this model, the code you end up writing starts at `0x100', just +like a `.COM' file - in fact, if you strip off the 32-byte header from +the resulting `.EXE' file, you will have a valid `.COM' program. All +the segment bases are the same, so you are limited to a 64K program, +again just like a `.COM' file. Note that an `ORG' directive is issued +by the `EXE_begin' macro, so you should not explicitly issue one of +your own. + + You can't directly refer to your segment base value, unfortunately, +since this would require a relocation in the header, and things would +get a lot more complicated. So you should get your segment base by +copying it out of `CS' instead. + + On entry to your `.EXE' file, `SS:SP' are already set up to point to +the top of a 2Kb stack. You can adjust the default stack size of 2Kb by +calling the `EXE_stack' macro. For example, to change the stack size of +your program to 64 bytes, you would call `EXE_stack 64'. + + A sample program which generates a `.EXE' file in this way is given +in the `test' subdirectory of the NASM archive, as `binexe.asm'. + + +File: nasm.info, Node: Section 8.2, Next: Section 8.2.1, Prev: Section 8.1.2, Up: Chapter 8 + +8.2. Producing `.COM' Files +=========================== + +While large DOS programs must be written as `.EXE' files, small ones +are often better written as `.COM' files. `.COM' files are pure binary, +and therefore most easily produced using the `bin' output format. + +* Menu: + +* Section 8.2.1:: Using the `bin' Format To Generate `.COM' Files +* Section 8.2.2:: Using the `obj' Format To Generate `.COM' Files + + +File: nasm.info, Node: Section 8.2.1, Next: Section 8.2.2, Prev: Section 8.2, Up: Section 8.2 + +8.2.1. Using the `bin' Format To Generate `.COM' Files +------------------------------------------------------ + +`.COM' files expect to be loaded at offset `100h' into their segment +(though the segment may change). Execution then begins at `100h', i.e. +right at the start of the program. So to write a `.COM' program, you +would create a source file looking like + + org 100h + + section .text + + start: + ; put your code here + + section .data + + ; put data items here + + section .bss + + ; put uninitialized data here + + The `bin' format puts the `.text' section first in the file, so you +can declare data or BSS items before beginning to write code if you +want to and the code will still end up at the front of the file where it +belongs. + + The BSS (uninitialized data) section does not take up space in the +`.COM' file itself: instead, addresses of BSS items are resolved to +point at space beyond the end of the file, on the grounds that this +will be free memory when the program is run. Therefore you should not +rely on your BSS being initialized to all zeros when you run. + + To assemble the above program, you should use a command line like + + nasm myprog.asm -fbin -o myprog.com + + The `bin' format would produce a file called `myprog' if no explicit +output file name were specified, so you have to override it and give +the desired file name. + + +File: nasm.info, Node: Section 8.2.2, Next: Section 8.3, Prev: Section 8.2.1, Up: Section 8.2 + +8.2.2. Using the `obj' Format To Generate `.COM' Files +------------------------------------------------------ + +If you are writing a `.COM' program as more than one module, you may +wish to assemble several `.OBJ' files and link them together into a +`.COM' program. You can do this, provided you have a linker capable of +outputting `.COM' files directly (TLINK does this), or alternatively a +converter program such as `EXE2BIN' to transform the `.EXE' file output +from the linker into a `.COM' file. + + If you do this, you need to take care of several things: + + * The first object file containing code should start its code + segment with a line like `RESB 100h'. This is to ensure that the + code begins at offset `100h' relative to the beginning of the code + segment, so that the linker or converter program does not have to + adjust address references within the file when generating the + `.COM' file. Other assemblers use an `ORG' directive for this + purpose, but `ORG' in NASM is a format-specific directive to the + `bin' output format, and does not mean the same thing as it does + in MASM-compatible assemblers. + + * You don't need to define a stack segment. + + * All your segments should be in the same group, so that every time + your code or data references a symbol offset, all offsets are + relative to the same segment base. This is because, when a `.COM' + file is loaded, all the segment registers contain the same value. + + +File: nasm.info, Node: Section 8.3, Next: Section 8.4, Prev: Section 8.2.2, Up: Chapter 8 + +8.3. Producing `.SYS' Files +=========================== + +MS-DOS device drivers - `.SYS' files - are pure binary files, similar +to `.COM' files, except that they start at origin zero rather than +`100h'. Therefore, if you are writing a device driver using the `bin' +format, you do not need the `ORG' directive, since the default origin +for `bin' is zero. Similarly, if you are using `obj', you do not need +the `RESB 100h' at the start of your code segment. + + `.SYS' files start with a header structure, containing pointers to +the various routines inside the driver which do the work. This +structure should be defined at the start of the code segment, even +though it is not actually code. + + For more information on the format of `.SYS' files, and the data +which has to go in the header structure, a list of books is given in the +Frequently Asked Questions list for the newsgroup +`comp.os.msdos.programmer'. + + +File: nasm.info, Node: Section 8.4, Next: Section 8.4.1, Prev: Section 8.3, Up: Chapter 8 + +8.4. Interfacing to 16-bit C Programs +===================================== + +This section covers the basics of writing assembly routines that call, +or are called from, C programs. To do this, you would typically write an +assembly module as a `.OBJ' file, and link it with your C modules to +produce a mixed-language program. + +* Menu: + +* Section 8.4.1:: External Symbol Names +* Section 8.4.2:: Memory Models +* Section 8.4.3:: Function Definitions and Function Calls +* Section 8.4.4:: Accessing Data Items +* Section 8.4.5:: `c16.mac': Helper Macros for the 16-bit C Interface + + +File: nasm.info, Node: Section 8.4.1, Next: Section 8.4.2, Prev: Section 8.4, Up: Section 8.4 + +8.4.1. External Symbol Names +---------------------------- + +C compilers have the convention that the names of all global symbols +(functions or data) they define are formed by prefixing an underscore to +the name as it appears in the C program. So, for example, the function +a C programmer thinks of as `printf' appears to an assembly language +programmer as `_printf'. This means that in your assembly programs, you +can define symbols without a leading underscore, and not have to worry +about name clashes with C symbols. + + If you find the underscores inconvenient, you can define macros to +replace the `GLOBAL' and `EXTERN' directives as follows: + + %macro cglobal 1 + + global _%1 + %define %1 _%1 + + %endmacro + + %macro cextern 1 + + extern _%1 + %define %1 _%1 + + %endmacro + + (These forms of the macros only take one argument at a time; a `%rep' +construct could solve this.) + + If you then declare an external like this: + + cextern printf + + then the macro will expand it as + + extern _printf + %define printf _printf + + Thereafter, you can reference `printf' as if it was a symbol, and the +preprocessor will put the leading underscore on where necessary. + + The `cglobal' macro works similarly. You must use `cglobal' before +defining the symbol in question, but you would have had to do that +anyway if you used `GLOBAL'. + + Also see *note Section 2.1.27::. + + +File: nasm.info, Node: Section 8.4.2, Next: Section 8.4.3, Prev: Section 8.4.1, Up: Section 8.4 + +8.4.2. Memory Models +-------------------- + +NASM contains no mechanism to support the various C memory models +directly; you have to keep track yourself of which one you are writing +for. This means you have to keep track of the following things: + + * In models using a single code segment (tiny, small and compact), + functions are near. This means that function pointers, when stored + in data segments or pushed on the stack as function arguments, are + 16 bits long and contain only an offset field (the `CS' register + never changes its value, and always gives the segment part of the + full function address), and that functions are called using + ordinary near `CALL' instructions and return using `RETN' (which, + in NASM, is synonymous with `RET' anyway). This means both that + you should write your own routines to return with `RETN', and that + you should call external C routines with near `CALL' instructions. + + * In models using more than one code segment (medium, large and + huge), functions are far. This means that function pointers are 32 + bits long (consisting of a 16-bit offset followed by a 16-bit + segment), and that functions are called using `CALL FAR' (or `CALL + seg:offset') and return using `RETF'. Again, you should therefore + write your own routines to return with `RETF' and use `CALL FAR' + to call external routines. + + * In models using a single data segment (tiny, small and medium), + data pointers are 16 bits long, containing only an offset field + (the `DS' register doesn't change its value, and always gives the + segment part of the full data item address). + + * In models using more than one data segment (compact, large and + huge), data pointers are 32 bits long, consisting of a 16-bit + offset followed by a 16- bit segment. You should still be careful + not to modify `DS' in your routines without restoring it + afterwards, but `ES' is free for you to use to access the contents + of 32-bit data pointers you are passed. + + * The huge memory model allows single data items to exceed 64K in + size. In all other memory models, you can access the whole of a + data item just by doing arithmetic on the offset field of the + pointer you are given, whether a segment field is present or not; + in huge model, you have to be more careful of your pointer + arithmetic. + + * In most memory models, there is a _default_ data segment, whose + segment address is kept in `DS' throughout the program. This data + segment is typically the same segment as the stack, kept in `SS', + so that functions' local variables (which are stored on the stack) + and global data items can both be accessed easily without changing + `DS'. Particularly large data items are typically stored in other + segments. However, some memory models (though not the standard + ones, usually) allow the assumption that `SS' and `DS' hold the + same value to be removed. Be careful about functions' local + variables in this latter case. + + In models with a single code segment, the segment is called `_TEXT', +so your code segment must also go by this name in order to be linked +into the same place as the main code segment. In models with a single +data segment, or with a default data segment, it is called `_DATA'. + + +File: nasm.info, Node: Section 8.4.3, Next: Section 8.4.4, Prev: Section 8.4.2, Up: Section 8.4 + +8.4.3. Function Definitions and Function Calls +---------------------------------------------- + +The C calling convention in 16-bit programs is as follows. In the +following description, the words _caller_ and _callee_ are used to +denote the function doing the calling and the function which gets +called. + + * The caller pushes the function's parameters on the stack, one after + another, in reverse order (right to left, so that the first + argument specified to the function is pushed last). + + * The caller then executes a `CALL' instruction to pass control to + the callee. This `CALL' is either near or far depending on the + memory model. + + * The callee receives control, and typically (although this is not + actually necessary, in functions which do not need to access their + parameters) starts by saving the value of `SP' in `BP' so as to be + able to use `BP' as a base pointer to find its parameters on the + stack. However, the caller was probably doing this too, so part + of the calling convention states that `BP' must be preserved by + any C function. Hence the callee, if it is going to set up `BP' as + a _frame pointer_, must push the previous value first. + + * The callee may then access its parameters relative to `BP'. The + word at `[BP]' holds the previous value of `BP' as it was pushed; + the next word, at `[BP+2]', holds the offset part of the return + address, pushed implicitly by `CALL'. In a small-model (near) + function, the parameters start after that, at `[BP+4]'; in a + large-model (far) function, the segment part of the return address + lives at `[BP+4]', and the parameters begin at `[BP+6]'. The + leftmost parameter of the function, since it was pushed last, is + accessible at this offset from `BP'; the others follow, at + successively greater offsets. Thus, in a function such as `printf' + which takes a variable number of parameters, the pushing of the + parameters in reverse order means that the function knows where to + find its first parameter, which tells it the number and type of + the remaining ones. + + * The callee may also wish to decrease `SP' further, so as to + allocate space on the stack for local variables, which will then + be accessible at negative offsets from `BP'. + + * The callee, if it wishes to return a value to the caller, should + leave the value in `AL', `AX' or `DX:AX' depending on the size of + the value. Floating-point results are sometimes (depending on the + compiler) returned in `ST0'. + + * Once the callee has finished processing, it restores `SP' from + `BP' if it had allocated local stack space, then pops the previous + value of `BP', and returns via `RETN' or `RETF' depending on + memory model. + + * When the caller regains control from the callee, the function + parameters are still on the stack, so it typically adds an + immediate constant to `SP' to remove them (instead of executing a + number of slow `POP' instructions). Thus, if a function is + accidentally called with the wrong number of parameters due to a + prototype mismatch, the stack will still be returned to a sensible + state since the caller, which _knows_ how many parameters it + pushed, does the removing. + + It is instructive to compare this calling convention with that for +Pascal programs (described in *note Section 8.5.1::). Pascal has a +simpler convention, since no functions have variable numbers of +parameters. Therefore the callee knows how many parameters it should +have been passed, and is able to deallocate them from the stack itself +by passing an immediate argument to the `RET' or `RETF' instruction, so +the caller does not have to do it. Also, the parameters are pushed in +left-to- right order, not right-to-left, which means that a compiler +can give better guarantees about sequence points without performance +suffering. + + Thus, you would define a function in C style in the following way. +The following example is for small model: + + global _myfunc + + _myfunc: + push bp + mov bp,sp + sub sp,0x40 ; 64 bytes of local stack space + mov bx,[bp+4] ; first parameter to function + + ; some more code + + mov sp,bp ; undo "sub sp,0x40" above + pop bp + ret + + For a large-model function, you would replace `RET' by `RETF', and +look for the first parameter at `[BP+6]' instead of `[BP+4]'. Of +course, if one of the parameters is a pointer, then the offsets of +_subsequent_ parameters will change depending on the memory model as +well: far pointers take up four bytes on the stack when passed as a +parameter, whereas near pointers take up two. + + At the other end of the process, to call a C function from your +assembly code, you would do something like this: + + extern _printf + + ; and then, further down... + + push word [myint] ; one of my integer variables + push word mystring ; pointer into my data segment + call _printf + add sp,byte 4 ; `byte' saves space + + ; then those data items... + + segment _DATA + + myint dw 1234 + mystring db 'This number -> %d <- should be 1234',10,0 + + This piece of code is the small-model assembly equivalent of the C +code + + int myint = 1234; + printf("This number -> %d <- should be 1234\n", myint); + + In large model, the function-call code might look more like this. In +this example, it is assumed that `DS' already holds the segment base of +the segment `_DATA'. If not, you would have to initialize it first. + + push word [myint] + push word seg mystring ; Now push the segment, and... + push word mystring ; ... offset of "mystring" + call far _printf + add sp,byte 6 + + The integer value still takes up one word on the stack, since large +model does not affect the size of the `int' data type. The first +argument (pushed last) to `printf', however, is a data pointer, and +therefore has to contain a segment and offset part. The segment should +be stored second in memory, and therefore must be pushed first. (Of +course, `PUSH DS' would have been a shorter instruction than `PUSH WORD +SEG mystring', if `DS' was set up as the above example assumed.) Then +the actual call becomes a far call, since functions expect far calls in +large model; and `SP' has to be increased by 6 rather than 4 afterwards +to make up for the extra word of parameters. + + +File: nasm.info, Node: Section 8.4.4, Next: Section 8.4.5, Prev: Section 8.4.3, Up: Section 8.4 + +8.4.4. Accessing Data Items +--------------------------- + +To get at the contents of C variables, or to declare variables which C +can access, you need only declare the names as `GLOBAL' or `EXTERN'. +(Again, the names require leading underscores, as stated in *note +Section 8.4.1::.) Thus, a C variable declared as `int i' can be +accessed from assembler as + + extern _i + + mov ax,[_i] + + And to declare your own integer variable which C programs can access +as `extern int j', you do this (making sure you are assembling in the +`_DATA' segment, if necessary): + + global _j + + _j dw 0 + + To access a C array, you need to know the size of the components of +the array. For example, `int' variables are two bytes long, so if a C +program declares an array as `int a[10]', you can access `a[3]' by +coding `mov ax,[_a+6]'. (The byte offset 6 is obtained by multiplying +the desired array index, 3, by the size of the array element, 2.) The +sizes of the C base types in 16-bit compilers are: 1 for `char', 2 for +`short' and `int', 4 for `long' and `float', and 8 for `double'. + + To access a C data structure, you need to know the offset from the +base of the structure to the field you are interested in. You can +either do this by converting the C structure definition into a NASM +structure definition (using `STRUC'), or by calculating the one offset +and using just that. + + To do either of these, you should read your C compiler's manual to +find out how it organizes data structures. NASM gives no special +alignment to structure members in its own `STRUC' macro, so you have to +specify alignment yourself if the C compiler generates it. Typically, +you might find that a structure like + + struct { + char c; + int i; + } foo; + + might be four bytes long rather than three, since the `int' field +would be aligned to a two-byte boundary. However, this sort of feature +tends to be a configurable option in the C compiler, either using +command- line options or `#pragma' lines, so you have to find out how +your own compiler does it. + + +File: nasm.info, Node: Section 8.4.5, Next: Section 8.5, Prev: Section 8.4.4, Up: Section 8.4 + +8.4.5. `c16.mac': Helper Macros for the 16-bit C Interface +---------------------------------------------------------- + +Included in the NASM archives, in the `misc' directory, is a file +`c16.mac' of macros. It defines three macros: `proc', `arg' and +`endproc'. These are intended to be used for C-style procedure +definitions, and they automate a lot of the work involved in keeping +track of the calling convention. + + (An alternative, TASM compatible form of `arg' is also now built into +NASM's preprocessor. See *note Section 4.8:: for details.) + + An example of an assembly function using the macro set is given here: + + proc _nearproc + + %$i arg + %$j arg + mov ax,[bp + %$i] + mov bx,[bp + %$j] + add ax,[bx] + + endproc + + This defines `_nearproc' to be a procedure taking two arguments, the +first (`i') an integer and the second (`j') a pointer to an integer. It +returns `i + *j'. + + Note that the `arg' macro has an `EQU' as the first line of its +expansion, and since the label before the macro call gets prepended to +the first line of the expanded macro, the `EQU' works, defining `%$i' +to be an offset from `BP'. A context-local variable is used, local to +the context pushed by the `proc' macro and popped by the `endproc' +macro, so that the same argument name can be used in later procedures. +Of course, you don't _have_ to do that. + + The macro set produces code for near functions (tiny, small and +compact- model code) by default. You can have it generate far functions +(medium, large and huge-model code) by means of coding `%define +FARCODE'. This changes the kind of return instruction generated by +`endproc', and also changes the starting point for the argument +offsets. The macro set contains no intrinsic dependency on whether data +pointers are far or not. + + `arg' can take an optional parameter, giving the size of the +argument. If no size is given, 2 is assumed, since it is likely that +many function parameters will be of type `int'. + + The large-model equivalent of the above function would look like +this: + + %define FARCODE + + proc _farproc + + %$i arg + %$j arg 4 + mov ax,[bp + %$i] + mov bx,[bp + %$j] + mov es,[bp + %$j + 2] + add ax,[bx] + + endproc + + This makes use of the argument to the `arg' macro to define a +parameter of size 4, because `j' is now a far pointer. When we load +from `j', we must load a segment and an offset. + + +File: nasm.info, Node: Section 8.5, Next: Section 8.5.1, Prev: Section 8.4.5, Up: Chapter 8 + +8.5. Interfacing to Borland Pascal Programs +=========================================== + +Interfacing to Borland Pascal programs is similar in concept to +interfacing to 16-bit C programs. The differences are: + + * The leading underscore required for interfacing to C programs is + not required for Pascal. + + * The memory model is always large: functions are far, data pointers + are far, and no data item can be more than 64K long. (Actually, + some functions are near, but only those functions that are local + to a Pascal unit and never called from outside it. All assembly + functions that Pascal calls, and all Pascal functions that + assembly routines are able to call, are far.) However, all static + data declared in a Pascal program goes into the default data + segment, which is the one whose segment address will be in `DS' + when control is passed to your assembly code. The only things that + do not live in the default data segment are local variables (they + live in the stack segment) and dynamically allocated variables. + All data _pointers_, however, are far. + + * The function calling convention is different - described below. + + * Some data types, such as strings, are stored differently. + + * There are restrictions on the segment names you are allowed to use + - Borland Pascal will ignore code or data declared in a segment it + doesn't like the name of. The restrictions are described below. + +* Menu: + +* Section 8.5.1:: The Pascal Calling Convention +* Section 8.5.2:: Borland Pascal Segment Name Restrictions +* Section 8.5.3:: Using `c16.mac' With Pascal Programs + + +File: nasm.info, Node: Section 8.5.1, Next: Section 8.5.2, Prev: Section 8.5, Up: Section 8.5 + +8.5.1. The Pascal Calling Convention +------------------------------------ + +The 16-bit Pascal calling convention is as follows. In the following +description, the words _caller_ and _callee_ are used to denote the +function doing the calling and the function which gets called. + + * The caller pushes the function's parameters on the stack, one after + another, in normal order (left to right, so that the first argument + specified to the function is pushed first). + + * The caller then executes a far `CALL' instruction to pass control + to the callee. + + * The callee receives control, and typically (although this is not + actually necessary, in functions which do not need to access their + parameters) starts by saving the value of `SP' in `BP' so as to be + able to use `BP' as a base pointer to find its parameters on the + stack. However, the caller was probably doing this too, so part + of the calling convention states that `BP' must be preserved by + any function. Hence the callee, if it is going to set up `BP' as a + frame pointer, must push the previous value first. + + * The callee may then access its parameters relative to `BP'. The + word at `[BP]' holds the previous value of `BP' as it was pushed. + The next word, at `[BP+2]', holds the offset part of the return + address, and the next one at `[BP+4]' the segment part. The + parameters begin at `[BP+6]'. The rightmost parameter of the + function, since it was pushed last, is accessible at this offset + from `BP'; the others follow, at successively greater offsets. + + * The callee may also wish to decrease `SP' further, so as to + allocate space on the stack for local variables, which will then + be accessible at negative offsets from `BP'. + + * The callee, if it wishes to return a value to the caller, should + leave the value in `AL', `AX' or `DX:AX' depending on the size of + the value. Floating-point results are returned in `ST0'. Results + of type `Real' (Borland's own custom floating-point data type, not + handled directly by the FPU) are returned in `DX:BX:AX'. To return + a result of type `String', the caller pushes a pointer to a + temporary string before pushing the parameters, and the callee + places the returned string value at that location. The pointer is + not a parameter, and should not be removed from the stack by the + `RETF' instruction. + + * Once the callee has finished processing, it restores `SP' from + `BP' if it had allocated local stack space, then pops the previous + value of `BP', and returns via `RETF'. It uses the form of `RETF' + with an immediate parameter, giving the number of bytes taken up + by the parameters on the stack. This causes the parameters to be + removed from the stack as a side effect of the return instruction. + + * When the caller regains control from the callee, the function + parameters have already been removed from the stack, so it needs + to do nothing further. + + Thus, you would define a function in Pascal style, taking two +`Integer'-type parameters, in the following way: + + global myfunc + + myfunc: push bp + mov bp,sp + sub sp,0x40 ; 64 bytes of local stack space + mov bx,[bp+8] ; first parameter to function + mov bx,[bp+6] ; second parameter to function + + ; some more code + + mov sp,bp ; undo "sub sp,0x40" above + pop bp + retf 4 ; total size of params is 4 + + At the other end of the process, to call a Pascal function from your +assembly code, you would do something like this: + + extern SomeFunc + + ; and then, further down... + + push word seg mystring ; Now push the segment, and... + push word mystring ; ... offset of "mystring" + push word [myint] ; one of my variables + call far SomeFunc + + This is equivalent to the Pascal code + + procedure SomeFunc(String: PChar; Int: Integer); + SomeFunc(@mystring, myint); + + +File: nasm.info, Node: Section 8.5.2, Next: Section 8.5.3, Prev: Section 8.5.1, Up: Section 8.5 + +8.5.2. Borland Pascal Segment Name Restrictions +----------------------------------------------- + +Since Borland Pascal's internal unit file format is completely different +from `OBJ', it only makes a very sketchy job of actually reading and +understanding the various information contained in a real `OBJ' file +when it links that in. Therefore an object file intended to be linked +to a Pascal program must obey a number of restrictions: + + * Procedures and functions must be in a segment whose name is either + `CODE', `CSEG', or something ending in `_TEXT'. + + * initialized data must be in a segment whose name is either `CONST' + or something ending in `_DATA'. + + * Uninitialized data must be in a segment whose name is either + `DATA', `DSEG', or something ending in `_BSS'. + + * Any other segments in the object file are completely ignored. + `GROUP' directives and segment attributes are also ignored. + + +File: nasm.info, Node: Section 8.5.3, Next: Chapter 9, Prev: Section 8.5.2, Up: Section 8.5 + +8.5.3. Using `c16.mac' With Pascal Programs +------------------------------------------- + +The `c16.mac' macro package, described in *note Section 8.4.5::, can +also be used to simplify writing functions to be called from Pascal +programs, if you code `%define PASCAL'. This definition ensures that +functions are far (it implies `FARCODE'), and also causes procedure +return instructions to be generated with an operand. + + Defining `PASCAL' does not change the code which calculates the +argument offsets; you must declare your function's arguments in reverse +order. For example: + + %define PASCAL + + proc _pascalproc + + %$j arg 4 + %$i arg + mov ax,[bp + %$i] + mov bx,[bp + %$j] + mov es,[bp + %$j + 2] + add ax,[bx] + + endproc + + This defines the same routine, conceptually, as the example in *note +Section 8.4.5::: it defines a function taking two arguments, an integer +and a pointer to an integer, which returns the sum of the integer and +the contents of the pointer. The only difference between this code and +the large-model C version is that `PASCAL' is defined instead of +`FARCODE', and that the arguments are declared in reverse order. + + +File: nasm.info, Node: Chapter 9, Next: Section 9.1, Prev: Section 8.5.3, Up: Top + +Chapter 9: Writing 32-bit Code (Unix, Win32, DJGPP) +*************************************************** + +This chapter attempts to cover some of the common issues involved when +writing 32-bit code, to run under Win32 or Unix, or to be linked with C +code generated by a Unix-style C compiler such as DJGPP. It covers how +to write assembly code to interface with 32-bit C routines, and how to +write position-independent code for shared libraries. + + Almost all 32-bit code, and in particular all code running under +`Win32', `DJGPP' or any of the PC Unix variants, runs in _flat_ memory +model. This means that the segment registers and paging have already +been set up to give you the same 32-bit 4Gb address space no matter +what segment you work relative to, and that you should ignore all +segment registers completely. When writing flat-model application code, +you never need to use a segment override or modify any segment +register, and the code-section addresses you pass to `CALL' and `JMP' +live in the same address space as the data-section addresses you access +your variables by and the stack-section addresses you access local +variables and procedure parameters by. Every address is 32 bits long +and contains only an offset part. + +* Menu: + +* Section 9.1:: Interfacing to 32-bit C Programs +* Section 9.2:: Writing NetBSD/FreeBSD/OpenBSD and Linux/ELF Shared Libraries + + +File: nasm.info, Node: Section 9.1, Next: Section 9.1.1, Prev: Chapter 9, Up: Chapter 9 + +9.1. Interfacing to 32-bit C Programs +===================================== + +A lot of the discussion in *note Section 8.4::, about interfacing to +16-bit C programs, still applies when working in 32 bits. The absence +of memory models or segmentation worries simplifies things a lot. + +* Menu: + +* Section 9.1.1:: External Symbol Names +* Section 9.1.2:: Function Definitions and Function Calls +* Section 9.1.3:: Accessing Data Items +* Section 9.1.4:: `c32.mac': Helper Macros for the 32-bit C Interface + + +File: nasm.info, Node: Section 9.1.1, Next: Section 9.1.2, Prev: Section 9.1, Up: Section 9.1 + +9.1.1. External Symbol Names +---------------------------- + +Most 32-bit C compilers share the convention used by 16-bit compilers, +that the names of all global symbols (functions or data) they define +are formed by prefixing an underscore to the name as it appears in the +C program. However, not all of them do: the `ELF' specification states +that C symbols do _not_ have a leading underscore on their +assembly-language names. + + The older Linux `a.out' C compiler, all `Win32' compilers, `DJGPP', +and `NetBSD' and `FreeBSD', all use the leading underscore; for these +compilers, the macros `cextern' and `cglobal', as given in *note +Section 8.4.1::, will still work. For `ELF', though, the leading +underscore should not be used. + + See also *note Section 2.1.27::. + + +File: nasm.info, Node: Section 9.1.2, Next: Section 9.1.3, Prev: Section 9.1.1, Up: Section 9.1 + +9.1.2. Function Definitions and Function Calls +---------------------------------------------- + +The C calling convention in 32-bit programs is as follows. In the +following description, the words _caller_ and _callee_ are used to +denote the function doing the calling and the function which gets +called. + + * The caller pushes the function's parameters on the stack, one after + another, in reverse order (right to left, so that the first + argument specified to the function is pushed last). + + * The caller then executes a near `CALL' instruction to pass control + to the callee. + + * The callee receives control, and typically (although this is not + actually necessary, in functions which do not need to access their + parameters) starts by saving the value of `ESP' in `EBP' so as to + be able to use `EBP' as a base pointer to find its parameters on + the stack. However, the caller was probably doing this too, so + part of the calling convention states that `EBP' must be preserved + by any C function. Hence the callee, if it is going to set up + `EBP' as a frame pointer, must push the previous value first. + + * The callee may then access its parameters relative to `EBP'. The + doubleword at `[EBP]' holds the previous value of `EBP' as it was + pushed; the next doubleword, at `[EBP+4]', holds the return + address, pushed implicitly by `CALL'. The parameters start after + that, at `[EBP+8]'. The leftmost parameter of the function, since + it was pushed last, is accessible at this offset from `EBP'; the + others follow, at successively greater offsets. Thus, in a + function such as `printf' which takes a variable number of + parameters, the pushing of the parameters in reverse order means + that the function knows where to find its first parameter, which + tells it the number and type of the remaining ones. + + * The callee may also wish to decrease `ESP' further, so as to + allocate space on the stack for local variables, which will then + be accessible at negative offsets from `EBP'. + + * The callee, if it wishes to return a value to the caller, should + leave the value in `AL', `AX' or `EAX' depending on the size of the + value. Floating-point results are typically returned in `ST0'. + + * Once the callee has finished processing, it restores `ESP' from + `EBP' if it had allocated local stack space, then pops the previous + value of `EBP', and returns via `RET' (equivalently, `RETN'). + + * When the caller regains control from the callee, the function + parameters are still on the stack, so it typically adds an + immediate constant to `ESP' to remove them (instead of executing a + number of slow `POP' instructions). Thus, if a function is + accidentally called with the wrong number of parameters due to a + prototype mismatch, the stack will still be returned to a sensible + state since the caller, which _knows_ how many parameters it + pushed, does the removing. + + There is an alternative calling convention used by Win32 programs for +Windows API calls, and also for functions called _by_ the Windows API +such as window procedures: they follow what Microsoft calls the +`__stdcall' convention. This is slightly closer to the Pascal +convention, in that the callee clears the stack by passing a parameter +to the `RET' instruction. However, the parameters are still pushed in +right-to-left order. + + Thus, you would define a function in C style in the following way: + + global _myfunc + + _myfunc: + push ebp + mov ebp,esp + sub esp,0x40 ; 64 bytes of local stack space + mov ebx,[ebp+8] ; first parameter to function + + ; some more code + + leave ; mov esp,ebp / pop ebp + ret + + At the other end of the process, to call a C function from your +assembly code, you would do something like this: + + extern _printf + + ; and then, further down... + + push dword [myint] ; one of my integer variables + push dword mystring ; pointer into my data segment + call _printf + add esp,byte 8 ; `byte' saves space + + ; then those data items... + + segment _DATA + + myint dd 1234 + mystring db 'This number -> %d <- should be 1234',10,0 + + This piece of code is the assembly equivalent of the C code + + int myint = 1234; + printf("This number -> %d <- should be 1234\n", myint); + |