summaryrefslogtreecommitdiff
path: root/doc/nasmdoc.txt
diff options
context:
space:
mode:
authorJinkun Jang <jinkun.jang@samsung.com>2013-03-12 15:14:36 +0900
committerJinkun Jang <jinkun.jang@samsung.com>2013-03-12 15:14:36 +0900
commit993d65531741fccf26fc10fc5789a5c9fca8c5ae (patch)
tree996be9095a97ff2aac0d98963b6044d47a0ec60c /doc/nasmdoc.txt
parent65c26d26fb72cec0d43d199c72ed27513d17f4c9 (diff)
downloadnasm-tizen_2.1.tar.gz
nasm-tizen_2.1.tar.bz2
nasm-tizen_2.1.zip
Diffstat (limited to 'doc/nasmdoc.txt')
-rw-r--r--doc/nasmdoc.txt12394
1 files changed, 12394 insertions, 0 deletions
diff --git a/doc/nasmdoc.txt b/doc/nasmdoc.txt
new file mode 100644
index 0000000..5a7286b
--- /dev/null
+++ b/doc/nasmdoc.txt
@@ -0,0 +1,12394 @@
+ The Netwide Assembler: NASM
+ ===========================
+
+Chapter 1: Introduction
+-----------------------
+
+ 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.
+
+ 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.
+
+ 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.
+
+ 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
+ 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.
+
+ 1.3 Installation
+
+ 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.
+
+ 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.
+
+Chapter 2: Running NASM
+-----------------------
+
+ 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.
+
+ 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 section 2.1.22.
+
+ 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'.
+
+ 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 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.
+
+ 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
+
+ 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.
+
+ 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
+
+ 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
+
+ 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.
+
+ 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.
+
+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.
+
+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
+ 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 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 section 7.14.
+
+2.1.12 The `-g' Option: Enabling Debug Information.
+
+ This option can be used to generate debugging information in the
+ specified format. See 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_.
+
+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, section 7.5.
+
+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 section 2.1.20.
+
+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, section 2.1.14.
+
+2.1.16 The `-i' Option: Include File Search Directories
+
+ When NASM sees the `%include' or `%pathsearch' directive in a source
+ file (see section 4.6.1, section 4.6.2 or 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 section
+ 2.1.28).
+
+ For Makefile compatibility with many C compilers, this option can
+ also be specified as `-I'.
+
+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'.
+
+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'.
+
+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'.
+
+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, section 2.1.14.
+
+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.
+
+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 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 section 2.1.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')
+
+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 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 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
+ 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 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.
+
+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.
+
+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
+
+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.
+
+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.
+
+ 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.
+
+ 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 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.
+
+ 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.
+
+ 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.
+
+ 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.
+
+ 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.
+
+ 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.
+
+ 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 chapter 4 and chapter 6 for further
+ details.
+
+Chapter 3: The NASM Language
+----------------------------
+
+ 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
+ chapter 4 and 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 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 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 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 section 3.3), constants (section 3.4) or
+ expressions (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.
+
+ 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.
+
+ 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.
+
+ 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 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 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
+
+ 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.
+
+ 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
+ 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.
+
+ 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 (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.
+
+ 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 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 (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 (section 6.2). The keyword `ABS' overrides `REL'.
+
+ 3.4 Constants
+
+ NASM understands four different types of constant: numeric,
+ character, string and floating-point.
+
+ 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 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
+
+ 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
+
+ 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.
+
+ 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.
+
+ 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.
+
+ 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
+
+ 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
+
+ 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.
+
+ 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.
+
+ 3.5.2 `^': Bitwise XOR Operator
+
+ `^' provides the bitwise XOR operation.
+
+ 3.5.3 `&': Bitwise AND Operator
+
+ `&' provides the bitwise AND operation.
+
+ 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.
+
+ 3.5.5 `+' and `-': Addition and Subtraction Operators
+
+ The `+' and `-' operators do perfectly ordinary addition and
+ subtraction.
+
+ 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.
+
+ 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 section 3.6).
+
+ 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.
+
+ 3.7 `STRICT': Inhibiting Optimization
+
+ When assembling with the optimizer set to level 2 or higher (see
+ 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.
+
+ 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.
+
+ 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 section 7.4.6).
+
+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.
+
+ 4.1 Single-Line Macros
+
+ 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 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 section 4.1.7).
+
+ You can pre-define single-line macros using the `-d' option on the
+ NASM command line: see section 2.1.18.
+
+ 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.
+
+ 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 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 section 4.3.8 for details.
+
+ 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).
+
+ 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
+
+ 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
+ section 2.1.19.
+
+ 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 section 4.5 for an example of this. Another
+ use for `%assign' is given in section 8.4 and section 9.1.
+
+ The expression passed to `%assign' is a critical expression (see
+ 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).
+
+ 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 section
+ 4.10.2):
+
+ %defstr PATH %!PATH ; The operating system PATH variable
+
+ 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
+
+ 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.
+
+ 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.
+
+ 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.
+
+ 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 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.
+
+ 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
+
+ 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'.
+
+ 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 section 2.1.24).
+
+ 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 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.
+
+ 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 section 6.3.1 for a better way to write the above macro.
+
+ 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
+ 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 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 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 section 4.3.7.
+
+ 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 section 4.5) in order to iterate through all the
+ parameters of a macro. Examples are given in section 4.3.7.
+
+ 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.
+
+ 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 (section 4.3.3) and context-
+ local labels (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, `%[...]' (section
+ 4.1.3), behaves the same way as macro parameters for the purpose of
+ concatenation.
+
+ See also the `%+' operator, section 4.1.4.
+
+ 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 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.
+
+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
+
+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.
+
+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
+
+ 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'.
+
+ 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'.
+
+ 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'.
+
+ 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 section 4.7. For a sample
+ use of `%ifctx', see section 4.7.5.
+
+ 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 section 4.5 for a detailed example.
+
+ The expression given to `%if', and its counterpart `%elif', is a
+ critical expression (see 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'.
+
+ 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'.
+
+ 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 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'.
+
+ 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.
+
+ 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.
+
+ 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.
+
+ 4.6 Source Files and Dependencies
+
+ These commands allow you to split your sources into multiple files.
+
+ 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 section 2.1.17).
+
+ 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"'.
+
+ 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 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.
+
+ 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 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 section 4.11.8.
+
+ 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.
+
+ 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.
+
+ 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.
+
+ 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'.
+
+ 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'.
+
+ 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 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'.
+
+ 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 section 4.8.1)
+
+ (*) `%stacksize' (see section 4.8.2)
+
+ (*) `%local' (see section 4.8.3)
+
+ 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 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 section 8.4.5 and adds
+ the value in i to the value pointed to by j_ptr and returns the sum
+ in the ax register. See section 4.7.1 for an explanation of `push'
+ and `pop' and the use of context stacks.
+
+ 4.8.2 `%stacksize' Directive
+
+ The `%stacksize' directive is used in conjunction with the `%arg'
+ (see section 4.8.1) and the `%local' (see 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 section
+ 4.8.3).
+
+ 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 section 4.8.2 and is also compatible with the `%arg' directive
+ (see 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.
+
+ 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
+
+ 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 section 4.10.1).
+
+ (*) `%!' enables NASM to read in the value of an environment
+ variable, which can then be used in your program (see section
+ 4.10.2).
+
+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.
+
+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 section 4.1.8 for notes on the `%defstr' directive.
+
+ 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 chapter 6) are implemented
+ as macros which invoke primitive directives; these are described in
+ chapter 6. The rest of the standard macro set is described here.
+
+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_.
+
+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.
+
+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"
+
+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.
+
+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.
+
+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
+
+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
+
+4.11.8 `__USE_'_package_`__': Package Include Test
+
+ When a standard macro package (see chapter 5) is included with the
+ `%use' directive (see 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 section 5.1),
+ then the macro `__USE_ALTREG__' is defined.
+
+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 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._
+
+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
+
+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
+
+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, section 5.2.
+
+Chapter 5: Standard Macro Packages
+----------------------------------
+
+ The `%use' directive (see 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 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.
+
+ 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 section 11.1.
+
+ 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 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.
+
+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 chapter 7.
+
+ 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!
+
+ 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.
+
+ 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 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'.
+
+ 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
+ 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.
+
+ 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 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.
+
+ 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
+ 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.
+
+ 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.
+
+ 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.
+
+ 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.
+
+ 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.
+
+ 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.
+
+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 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.
+
+ 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 section 7.1.3.
+
+ Using the `bin' format puts NASM by default into 16-bit mode (see
+ 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'.
+
+ 7.1.1 `ORG': Binary File Program Origin
+
+ The `bin' format provides an additional directive to the list given
+ in 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 section 12.1.3 for further comments.
+
+ 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.
+
+ 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 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.
+
+ 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.
+
+ 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'.
+
+ 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'.
+
+ 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
+
+ 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'.
+
+ 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.
+
+ 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.
+
+ 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
+
+ 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
+
+ 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.
+
+ 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 section 7.4.8.
+
+ 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 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
+
+ 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 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.
+
+ 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'.
+
+ 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.
+
+ 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 (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 (section 7.5), in NASM, with
+ regard to this exception.
+
+ 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
+
+ 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.
+
+ 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.
+
+ 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'.
+
+ 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'.
+
+ 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.
+
+ 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.)
+
+ 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 section 9.2.
+
+ 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]
+
+ 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 section
+ 9.2.4.
+
+ 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.
+
+ 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.
+
+ 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.
+
+ 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 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'.
+
+ 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 section
+ 7.9.3 for full documentation of this feature.
+
+ `aoutb' also supports the same extensions to the `GLOBAL' directive
+ as `elf' does: see section 7.9.5 for documentation of this.
+
+ 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'.
+
+ 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'.
+
+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
+
+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
+
+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
+
+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.
+
+ 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.
+
+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.
+
+ 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.
+
+ 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 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.
+
+ 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'.
+
+ 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.
+
+ 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.
+
+ 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.
+
+ 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'.
+
+ 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.
+
+ 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 section 2.1.27.
+
+ 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'.
+
+ 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 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.
+
+ 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 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.
+
+ 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 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.
+
+ 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.
+
+ 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);
+
+ 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.
+
+ 8.5.3 Using `c16.mac' With Pascal Programs
+
+ The `c16.mac' macro package, described in 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
+ 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.
+
+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.
+
+ 9.1 Interfacing to 32-bit C Programs
+
+ A lot of the discussion in 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.
+
+ 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
+ section 8.4.1, will still work. For `ELF', though, the leading
+ underscore should not be used.
+
+ See also section 2.1.27.
+
+ 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);
+
+ 9.1.3 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 section 9.1.1.) Thus, a C variable declared as `int i' can be
+ accessed from assembler as
+
+ extern _i
+ mov eax,[_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 dd 0
+
+ To access a C array, you need to know the size of the components of
+ the array. For example, `int' variables are four bytes long, so if a
+ C program declares an array as `int a[10]', you can access `a[3]' by
+ coding `mov ax,[_a+12]'. (The byte offset 12 is obtained by
+ multiplying the desired array index, 3, by the size of the array
+ element, 4.) The sizes of the C base types in 32-bit compilers are:
+ 1 for `char', 2 for `short', 4 for `int', `long' and `float', and 8
+ for `double'. Pointers, being 32-bit addresses, are also 4 bytes
+ long.
+
+ 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 eight bytes long rather than five, since the `int' field
+ would be aligned to a four-byte boundary. However, this sort of
+ feature is sometimes 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.
+
+ 9.1.4 `c32.mac': Helper Macros for the 32-bit C Interface
+
+ Included in the NASM archives, in the `misc' directory, is a file
+ `c32.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 example of an assembly function using the macro set is given
+ here:
+
+ proc _proc32
+
+ %$i arg
+ %$j arg
+ mov eax,[ebp + %$i]
+ mov ebx,[ebp + %$j]
+ add eax,[ebx]
+
+ endproc
+
+ This defines `_proc32' 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.
+
+ `arg' can take an optional parameter, giving the size of the
+ argument. If no size is given, 4 is assumed, since it is likely that
+ many function parameters will be of type `int' or pointers.
+
+ 9.2 Writing NetBSD/FreeBSD/OpenBSD and Linux/ELF Shared Libraries
+
+ `ELF' replaced the older `a.out' object file format under Linux
+ because it contains support for position-independent code (PIC),
+ which makes writing shared libraries much easier. NASM supports the
+ `ELF' position-independent code features, so you can write Linux
+ `ELF' shared libraries in NASM.
+
+ NetBSD, and its close cousins FreeBSD and OpenBSD, take a different
+ approach by hacking PIC support into the `a.out' format. NASM
+ supports this as the `aoutb' output format, so you can write BSD
+ shared libraries in NASM too.
+
+ The operating system loads a PIC shared library by memory-mapping
+ the library file at an arbitrarily chosen point in the address space
+ of the running process. The contents of the library's code section
+ must therefore not depend on where it is loaded in memory.
+
+ Therefore, you cannot get at your variables by writing code like
+ this:
+
+ mov eax,[myvar] ; WRONG
+
+ Instead, the linker provides an area of memory called the _global
+ offset table_, or GOT; the GOT is situated at a constant distance
+ from your library's code, so if you can find out where your library
+ is loaded (which is typically done using a `CALL' and `POP'
+ combination), you can obtain the address of the GOT, and you can
+ then load the addresses of your variables out of linker-generated
+ entries in the GOT.
+
+ The _data_ section of a PIC shared library does not have these
+ restrictions: since the data section is writable, it has to be
+ copied into memory anyway rather than just paged in from the library
+ file, so as long as it's being copied it can be relocated too. So
+ you can put ordinary types of relocation in the data section without
+ too much worry (but see section 9.2.4 for a caveat).
+
+ 9.2.1 Obtaining the Address of the GOT
+
+ Each code module in your shared library should define the GOT as an
+ external symbol:
+
+ extern _GLOBAL_OFFSET_TABLE_ ; in ELF
+ extern __GLOBAL_OFFSET_TABLE_ ; in BSD a.out
+
+ At the beginning of any function in your shared library which plans
+ to access your data or BSS sections, you must first calculate the
+ address of the GOT. This is typically done by writing the function
+ in this form:
+
+ func: push ebp
+ mov ebp,esp
+ push ebx
+ call .get_GOT
+ .get_GOT:
+ pop ebx
+ add ebx,_GLOBAL_OFFSET_TABLE_+$$-.get_GOT wrt ..gotpc
+
+ ; the function body comes here
+
+ mov ebx,[ebp-4]
+ mov esp,ebp
+ pop ebp
+ ret
+
+ (For BSD, again, the symbol `_GLOBAL_OFFSET_TABLE' requires a second
+ leading underscore.)
+
+ The first two lines of this function are simply the standard C
+ prologue to set up a stack frame, and the last three lines are
+ standard C function epilogue. The third line, and the fourth to last
+ line, save and restore the `EBX' register, because PIC shared
+ libraries use this register to store the address of the GOT.
+
+ The interesting bit is the `CALL' instruction and the following two
+ lines. The `CALL' and `POP' combination obtains the address of the
+ label `.get_GOT', without having to know in advance where the
+ program was loaded (since the `CALL' instruction is encoded relative
+ to the current position). The `ADD' instruction makes use of one of
+ the special PIC relocation types: GOTPC relocation. With the
+ `WRT ..gotpc' qualifier specified, the symbol referenced (here
+ `_GLOBAL_OFFSET_TABLE_', the special symbol assigned to the GOT) is
+ given as an offset from the beginning of the section. (Actually,
+ `ELF' encodes it as the offset from the operand field of the `ADD'
+ instruction, but NASM simplifies this deliberately, so you do things
+ the same way for both `ELF' and `BSD'.) So the instruction then
+ _adds_ the beginning of the section, to get the real address of the
+ GOT, and subtracts the value of `.get_GOT' which it knows is in
+ `EBX'. Therefore, by the time that instruction has finished, `EBX'
+ contains the address of the GOT.
+
+ If you didn't follow that, don't worry: it's never necessary to
+ obtain the address of the GOT by any other means, so you can put
+ those three instructions into a macro and safely ignore them:
+
+ %macro get_GOT 0
+
+ call %%getgot
+ %%getgot:
+ pop ebx
+ add ebx,_GLOBAL_OFFSET_TABLE_+$$-%%getgot wrt ..gotpc
+
+ %endmacro
+
+ 9.2.2 Finding Your Local Data Items
+
+ Having got the GOT, you can then use it to obtain the addresses of
+ your data items. Most variables will reside in the sections you have
+ declared; they can be accessed using the `..gotoff' special `WRT'
+ type. The way this works is like this:
+
+ lea eax,[ebx+myvar wrt ..gotoff]
+
+ The expression `myvar wrt ..gotoff' is calculated, when the shared
+ library is linked, to be the offset to the local variable `myvar'
+ from the beginning of the GOT. Therefore, adding it to `EBX' as
+ above will place the real address of `myvar' in `EAX'.
+
+ If you declare variables as `GLOBAL' without specifying a size for
+ them, they are shared between code modules in the library, but do
+ not get exported from the library to the program that loaded it.
+ They will still be in your ordinary data and BSS sections, so you
+ can access them in the same way as local variables, using the above
+ `..gotoff' mechanism.
+
+ Note that due to a peculiarity of the way BSD `a.out' format handles
+ this relocation type, there must be at least one non-local symbol in
+ the same section as the address you're trying to access.
+
+ 9.2.3 Finding External and Common Data Items
+
+ If your library needs to get at an external variable (external to
+ the _library_, not just to one of the modules within it), you must
+ use the `..got' type to get at it. The `..got' type, instead of
+ giving you the offset from the GOT base to the variable, gives you
+ the offset from the GOT base to a GOT _entry_ containing the address
+ of the variable. The linker will set up this GOT entry when it
+ builds the library, and the dynamic linker will place the correct
+ address in it at load time. So to obtain the address of an external
+ variable `extvar' in `EAX', you would code
+
+ mov eax,[ebx+extvar wrt ..got]
+
+ This loads the address of `extvar' out of an entry in the GOT. The
+ linker, when it builds the shared library, collects together every
+ relocation of type `..got', and builds the GOT so as to ensure it
+ has every necessary entry present.
+
+ Common variables must also be accessed in this way.
+
+ 9.2.4 Exporting Symbols to the Library User
+
+ If you want to export symbols to the user of the library, you have
+ to declare whether they are functions or data, and if they are data,
+ you have to give the size of the data item. This is because the
+ dynamic linker has to build procedure linkage table entries for any
+ exported functions, and also moves exported data items away from the
+ library's data section in which they were declared.
+
+ So to export a function to users of the library, you must use
+
+ global func:function ; declare it as a function
+
+ func: push ebp
+
+ ; etc.
+
+ And to export a data item such as an array, you would have to code
+
+ global array:data array.end-array ; give the size too
+
+ array: resd 128
+ .end:
+
+ Be careful: If you export a variable to the library user, by
+ declaring it as `GLOBAL' and supplying a size, the variable will end
+ up living in the data section of the main program, rather than in
+ your library's data section, where you declared it. So you will have
+ to access your own global variable with the `..got' mechanism rather
+ than `..gotoff', as if it were external (which, effectively, it has
+ become).
+
+ Equally, if you need to store the address of an exported global in
+ one of your data sections, you can't do it by means of the standard
+ sort of code:
+
+ dataptr: dd global_data_item ; WRONG
+
+ NASM will interpret this code as an ordinary relocation, in which
+ `global_data_item' is merely an offset from the beginning of the
+ `.data' section (or whatever); so this reference will end up
+ pointing at your data section instead of at the exported global
+ which resides elsewhere.
+
+ Instead of the above code, then, you must write
+
+ dataptr: dd global_data_item wrt ..sym
+
+ which makes use of the special `WRT' type `..sym' to instruct NASM
+ to search the symbol table for a particular symbol at that address,
+ rather than just relocating by section base.
+
+ Either method will work for functions: referring to one of your
+ functions by means of
+
+ funcptr: dd my_function
+
+ will give the user the address of the code you wrote, whereas
+
+ funcptr: dd my_function wrt .sym
+
+ will give the address of the procedure linkage table for the
+ function, which is where the calling program will _believe_ the
+ function lives. Either address is a valid way to call the function.
+
+ 9.2.5 Calling Procedures Outside the Library
+
+ Calling procedures outside your shared library has to be done by
+ means of a _procedure linkage table_, or PLT. The PLT is placed at a
+ known offset from where the library is loaded, so the library code
+ can make calls to the PLT in a position-independent way. Within the
+ PLT there is code to jump to offsets contained in the GOT, so
+ function calls to other shared libraries or to routines in the main
+ program can be transparently passed off to their real destinations.
+
+ To call an external routine, you must use another special PIC
+ relocation type, `WRT ..plt'. This is much easier than the GOT-based
+ ones: you simply replace calls such as `CALL printf' with the PLT-
+ relative version `CALL printf WRT ..plt'.
+
+ 9.2.6 Generating the Library File
+
+ Having written some code modules and assembled them to `.o' files,
+ you then generate your shared library with a command such as
+
+ ld -shared -o library.so module1.o module2.o # for ELF
+ ld -Bshareable -o library.so module1.o module2.o # for BSD
+
+ For ELF, if your shared library is going to reside in system
+ directories such as `/usr/lib' or `/lib', it is usually worth using
+ the `-soname' flag to the linker, to store the final library file
+ name, with a version number, into the library:
+
+ ld -shared -soname library.so.1 -o library.so.1.2 *.o
+
+ You would then copy `library.so.1.2' into the library directory, and
+ create `library.so.1' as a symbolic link to it.
+
+Chapter 10: Mixing 16 and 32 Bit Code
+-------------------------------------
+
+ This chapter tries to cover some of the issues, largely related to
+ unusual forms of addressing and jump instructions, encountered when
+ writing operating system code such as protected-mode initialisation
+ routines, which require code that operates in mixed segment sizes,
+ such as code in a 16-bit segment trying to modify data in a 32-bit
+ one, or jumps between different-size segments.
+
+ 10.1 Mixed-Size Jumps
+
+ The most common form of mixed-size instruction is the one used when
+ writing a 32-bit OS: having done your setup in 16-bit mode, such as
+ loading the kernel, you then have to boot it by switching into
+ protected mode and jumping to the 32-bit kernel start address. In a
+ fully 32-bit OS, this tends to be the _only_ mixed-size instruction
+ you need, since everything before it can be done in pure 16-bit
+ code, and everything after it can be pure 32-bit.
+
+ This jump must specify a 48-bit far address, since the target
+ segment is a 32-bit one. However, it must be assembled in a 16-bit
+ segment, so just coding, for example,
+
+ jmp 0x1234:0x56789ABC ; wrong!
+
+ will not work, since the offset part of the address will be
+ truncated to `0x9ABC' and the jump will be an ordinary 16-bit far
+ one.
+
+ The Linux kernel setup code gets round the inability of `as86' to
+ generate the required instruction by coding it manually, using `DB'
+ instructions. NASM can go one better than that, by actually
+ generating the right instruction itself. Here's how to do it right:
+
+ jmp dword 0x1234:0x56789ABC ; right
+
+ The `DWORD' prefix (strictly speaking, it should come _after_ the
+ colon, since it is declaring the _offset_ field to be a doubleword;
+ but NASM will accept either form, since both are unambiguous) forces
+ the offset part to be treated as far, in the assumption that you are
+ deliberately writing a jump from a 16-bit segment to a 32-bit one.
+
+ You can do the reverse operation, jumping from a 32-bit segment to a
+ 16-bit one, by means of the `WORD' prefix:
+
+ jmp word 0x8765:0x4321 ; 32 to 16 bit
+
+ If the `WORD' prefix is specified in 16-bit mode, or the `DWORD'
+ prefix in 32-bit mode, they will be ignored, since each is
+ explicitly forcing NASM into a mode it was in anyway.
+
+ 10.2 Addressing Between Different-Size Segments
+
+ If your OS is mixed 16 and 32-bit, or if you are writing a DOS
+ extender, you are likely to have to deal with some 16-bit segments
+ and some 32-bit ones. At some point, you will probably end up
+ writing code in a 16-bit segment which has to access data in a 32-
+ bit segment, or vice versa.
+
+ If the data you are trying to access in a 32-bit segment lies within
+ the first 64K of the segment, you may be able to get away with using
+ an ordinary 16-bit addressing operation for the purpose; but sooner
+ or later, you will want to do 32-bit addressing from 16-bit mode.
+
+ The easiest way to do this is to make sure you use a register for
+ the address, since any effective address containing a 32-bit
+ register is forced to be a 32-bit address. So you can do
+
+ mov eax,offset_into_32_bit_segment_specified_by_fs
+ mov dword [fs:eax],0x11223344
+
+ This is fine, but slightly cumbersome (since it wastes an
+ instruction and a register) if you already know the precise offset
+ you are aiming at. The x86 architecture does allow 32-bit effective
+ addresses to specify nothing but a 4-byte offset, so why shouldn't
+ NASM be able to generate the best instruction for the purpose?
+
+ It can. As in section 10.1, you need only prefix the address with
+ the `DWORD' keyword, and it will be forced to be a 32-bit address:
+
+ mov dword [fs:dword my_offset],0x11223344
+
+ Also as in section 10.1, NASM is not fussy about whether the `DWORD'
+ prefix comes before or after the segment override, so arguably a
+ nicer-looking way to code the above instruction is
+
+ mov dword [dword fs:my_offset],0x11223344
+
+ Don't confuse the `DWORD' prefix _outside_ the square brackets,
+ which controls the size of the data stored at the address, with the
+ one `inside' the square brackets which controls the length of the
+ address itself. The two can quite easily be different:
+
+ mov word [dword 0x12345678],0x9ABC
+
+ This moves 16 bits of data to an address specified by a 32-bit
+ offset.
+
+ You can also specify `WORD' or `DWORD' prefixes along with the `FAR'
+ prefix to indirect far jumps or calls. For example:
+
+ call dword far [fs:word 0x4321]
+
+ This instruction contains an address specified by a 16-bit offset;
+ it loads a 48-bit far pointer from that (16-bit segment and 32-bit
+ offset), and calls that address.
+
+ 10.3 Other Mixed-Size Instructions
+
+ The other way you might want to access data might be using the
+ string instructions (`LODSx', `STOSx' and so on) or the `XLATB'
+ instruction. These instructions, since they take no parameters,
+ might seem to have no easy way to make them perform 32-bit
+ addressing when assembled in a 16-bit segment.
+
+ This is the purpose of NASM's `a16', `a32' and `a64' prefixes. If
+ you are coding `LODSB' in a 16-bit segment but it is supposed to be
+ accessing a string in a 32-bit segment, you should load the desired
+ address into `ESI' and then code
+
+ a32 lodsb
+
+ The prefix forces the addressing size to 32 bits, meaning that
+ `LODSB' loads from `[DS:ESI]' instead of `[DS:SI]'. To access a
+ string in a 16-bit segment when coding in a 32-bit one, the
+ corresponding `a16' prefix can be used.
+
+ The `a16', `a32' and `a64' prefixes can be applied to any
+ instruction in NASM's instruction table, but most of them can
+ generate all the useful forms without them. The prefixes are
+ necessary only for instructions with implicit addressing: `CMPSx',
+ `SCASx', `LODSx', `STOSx', `MOVSx', `INSx', `OUTSx', and `XLATB'.
+ Also, the various push and pop instructions (`PUSHA' and `POPF' as
+ well as the more usual `PUSH' and `POP') can accept `a16', `a32' or
+ `a64' prefixes to force a particular one of `SP', `ESP' or `RSP' to
+ be used as a stack pointer, in case the stack segment in use is a
+ different size from the code segment.
+
+ `PUSH' and `POP', when applied to segment registers in 32-bit mode,
+ also have the slightly odd behaviour that they push and pop 4 bytes
+ at a time, of which the top two are ignored and the bottom two give
+ the value of the segment register being manipulated. To force the
+ 16-bit behaviour of segment-register push and pop instructions, you
+ can use the operand-size prefix `o16':
+
+ o16 push ss
+ o16 push ds
+
+ This code saves a doubleword of stack space by fitting two segment
+ registers into the space which would normally be consumed by pushing
+ one.
+
+ (You can also use the `o32' prefix to force the 32-bit behaviour
+ when in 16-bit mode, but this seems less useful.)
+
+Chapter 11: Writing 64-bit Code (Unix, Win64)
+---------------------------------------------
+
+ This chapter attempts to cover some of the common issues involved
+ when writing 64-bit code, to run under Win64 or Unix. It covers how
+ to write assembly code to interface with 64-bit C routines, and how
+ to write position-independent code for shared libraries.
+
+ All 64-bit code uses a flat memory model, since segmentation is not
+ available in 64-bit mode. The one exception is the `FS' and `GS'
+ registers, which still add their bases.
+
+ Position independence in 64-bit mode is significantly simpler, since
+ the processor supports `RIP'-relative addressing directly; see the
+ `REL' keyword (section 3.3). On most 64-bit platforms, it is
+ probably desirable to make that the default, using the directive
+ `DEFAULT REL' (section 6.2).
+
+ 64-bit programming is relatively similar to 32-bit programming, but
+ of course pointers are 64 bits long; additionally, all existing
+ platforms pass arguments in registers rather than on the stack.
+ Furthermore, 64-bit platforms use SSE2 by default for floating
+ point. Please see the ABI documentation for your platform.
+
+ 64-bit platforms differ in the sizes of the fundamental datatypes,
+ not just from 32-bit platforms but from each other. If a specific
+ size data type is desired, it is probably best to use the types
+ defined in the Standard C header `<inttypes.h>'.
+
+ In 64-bit mode, the default instruction size is still 32 bits. When
+ loading a value into a 32-bit register (but not an 8- or 16-bit
+ register), the upper 32 bits of the corresponding 64-bit register
+ are set to zero.
+
+ 11.1 Register Names in 64-bit Mode
+
+ NASM uses the following names for general-purpose registers in 64-
+ bit mode, for 8-, 16-, 32- and 64-bit references, respecitively:
+
+ AL/AH, CL/CH, DL/DH, BL/BH, SPL, BPL, SIL, DIL, R8B-R15B
+ AX, CX, DX, BX, SP, BP, SI, DI, R8W-R15W
+ EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI, R8D-R15D
+ RAX, RCX, RDX, RBX, RSP, RBP, RSI, RDI, R8-R15
+
+ This is consistent with the AMD documentation and most other
+ assemblers. The Intel documentation, however, uses the names
+ `R8L-R15L' for 8-bit references to the higher registers. It is
+ possible to use those names by definiting them as macros; similarly,
+ if one wants to use numeric names for the low 8 registers, define
+ them as macros. The standard macro package `altreg' (see section
+ 5.1) can be used for this purpose.
+
+ 11.2 Immediates and Displacements in 64-bit Mode
+
+ In 64-bit mode, immediates and displacements are generally only 32
+ bits wide. NASM will therefore truncate most displacements and
+ immediates to 32 bits.
+
+ The only instruction which takes a full 64-bit immediate is:
+
+ MOV reg64,imm64
+
+ NASM will produce this instruction whenever the programmer uses
+ `MOV' with an immediate into a 64-bit register. If this is not
+ desirable, simply specify the equivalent 32-bit register, which will
+ be automatically zero-extended by the processor, or specify the
+ immediate as `DWORD':
+
+ mov rax,foo ; 64-bit immediate
+ mov rax,qword foo ; (identical)
+ mov eax,foo ; 32-bit immediate, zero-extended
+ mov rax,dword foo ; 32-bit immediate, sign-extended
+
+ The length of these instructions are 10, 5 and 7 bytes,
+ respectively.
+
+ The only instructions which take a full 64-bit _displacement_ is
+ loading or storing, using `MOV', `AL', `AX', `EAX' or `RAX' (but no
+ other registers) to an absolute 64-bit address. Since this is a
+ relatively rarely used instruction (64-bit code generally uses
+ relative addressing), the programmer has to explicitly declare the
+ displacement size as `QWORD':
+
+ default abs
+
+ mov eax,[foo] ; 32-bit absolute disp, sign-extended
+ mov eax,[a32 foo] ; 32-bit absolute disp, zero-extended
+ mov eax,[qword foo] ; 64-bit absolute disp
+
+ default rel
+
+ mov eax,[foo] ; 32-bit relative disp
+ mov eax,[a32 foo] ; d:o, address truncated to 32 bits(!)
+ mov eax,[qword foo] ; error
+ mov eax,[abs qword foo] ; 64-bit absolute disp
+
+ A sign-extended absolute displacement can access from -2 GB to +2
+ GB; a zero-extended absolute displacement can access from 0 to 4 GB.
+
+ 11.3 Interfacing to 64-bit C Programs (Unix)
+
+ On Unix, the 64-bit ABI is defined by the document:
+
+ `http://www.x86-64.org/documentation/abi.pdf'
+
+ Although written for AT&T-syntax assembly, the concepts apply
+ equally well for NASM-style assembly. What follows is a simplified
+ summary.
+
+ The first six integer arguments (from the left) are passed in `RDI',
+ `RSI', `RDX', `RCX', `R8', and `R9', in that order. Additional
+ integer arguments are passed on the stack. These registers, plus
+ `RAX', `R10' and `R11' are destroyed by function calls, and thus are
+ available for use by the function without saving.
+
+ Integer return values are passed in `RAX' and `RDX', in that order.
+
+ Floating point is done using SSE registers, except for
+ `long double'. Floating-point arguments are passed in `XMM0' to
+ `XMM7'; return is `XMM0' and `XMM1'. `long double' are passed on the
+ stack, and returned in `ST0' and `ST1'.
+
+ All SSE and x87 registers are destroyed by function calls.
+
+ On 64-bit Unix, `long' is 64 bits.
+
+ Integer and SSE register arguments are counted separately, so for
+ the case of
+
+ void foo(long a, double b, int c)
+
+ `a' is passed in `RDI', `b' in `XMM0', and `c' in `ESI'.
+
+ 11.4 Interfacing to 64-bit C Programs (Win64)
+
+ The Win64 ABI is described at:
+
+ `http://msdn2.microsoft.com/en-gb/library/ms794533.aspx'
+
+ What follows is a simplified summary.
+
+ The first four integer arguments are passed in `RCX', `RDX', `R8'
+ and `R9', in that order. Additional integer arguments are passed on
+ the stack. These registers, plus `RAX', `R10' and `R11' are
+ destroyed by function calls, and thus are available for use by the
+ function without saving.
+
+ Integer return values are passed in `RAX' only.
+
+ Floating point is done using SSE registers, except for
+ `long double'. Floating-point arguments are passed in `XMM0' to
+ `XMM3'; return is `XMM0' only.
+
+ On Win64, `long' is 32 bits; `long long' or `_int64' is 64 bits.
+
+ Integer and SSE register arguments are counted together, so for the
+ case of
+
+ void foo(long long a, double b, int c)
+
+ `a' is passed in `RCX', `b' in `XMM1', and `c' in `R8D'.
+
+Chapter 12: Troubleshooting
+---------------------------
+
+ This chapter describes some of the common problems that users have
+ been known to encounter with NASM, and answers them. It also gives
+ instructions for reporting bugs in NASM if you find a difficulty
+ that isn't listed here.
+
+ 12.1 Common Problems
+
+12.1.1 NASM Generates Inefficient Code
+
+ We sometimes get `bug' reports about NASM generating inefficient, or
+ even `wrong', code on instructions such as `ADD ESP,8'. This is a
+ deliberate design feature, connected to predictability of output:
+ NASM, on seeing `ADD ESP,8', will generate the form of the
+ instruction which leaves room for a 32-bit offset. You need to code
+ `ADD ESP,BYTE 8' if you want the space-efficient form of the
+ instruction. This isn't a bug, it's user error: if you prefer to
+ have NASM produce the more efficient code automatically enable
+ optimization with the `-O' option (see section 2.1.22).
+
+12.1.2 My Jumps are Out of Range
+
+ Similarly, people complain that when they issue conditional jumps
+ (which are `SHORT' by default) that try to jump too far, NASM
+ reports `short jump out of range' instead of making the jumps
+ longer.
+
+ This, again, is partly a predictability issue, but in fact has a
+ more practical reason as well. NASM has no means of being told what
+ type of processor the code it is generating will be run on; so it
+ cannot decide for itself that it should generate `Jcc NEAR' type
+ instructions, because it doesn't know that it's working for a 386 or
+ above. Alternatively, it could replace the out-of-range short `JNE'
+ instruction with a very short `JE' instruction that jumps over a
+ `JMP NEAR'; this is a sensible solution for processors below a 386,
+ but hardly efficient on processors which have good branch prediction
+ _and_ could have used `JNE NEAR' instead. So, once again, it's up to
+ the user, not the assembler, to decide what instructions should be
+ generated. See section 2.1.22.
+
+12.1.3 `ORG' Doesn't Work
+
+ People writing boot sector programs in the `bin' format often
+ complain that `ORG' doesn't work the way they'd like: in order to
+ place the `0xAA55' signature word at the end of a 512-byte boot
+ sector, people who are used to MASM tend to code
+
+ ORG 0
+
+ ; some boot sector code
+
+ ORG 510
+ DW 0xAA55
+
+ This is not the intended use of the `ORG' directive in NASM, and
+ will not work. The correct way to solve this problem in NASM is to
+ use the `TIMES' directive, like this:
+
+ ORG 0
+
+ ; some boot sector code
+
+ TIMES 510-($-$$) DB 0
+ DW 0xAA55
+
+ The `TIMES' directive will insert exactly enough zero bytes into the
+ output to move the assembly point up to 510. This method also has
+ the advantage that if you accidentally fill your boot sector too
+ full, NASM will catch the problem at assembly time and report it, so
+ you won't end up with a boot sector that you have to disassemble to
+ find out what's wrong with it.
+
+12.1.4 `TIMES' Doesn't Work
+
+ The other common problem with the above code is people who write the
+ `TIMES' line as
+
+ TIMES 510-$ DB 0
+
+ by reasoning that `$' should be a pure number, just like 510, so the
+ difference between them is also a pure number and can happily be fed
+ to `TIMES'.
+
+ NASM is a _modular_ assembler: the various component parts are
+ designed to be easily separable for re-use, so they don't exchange
+ information unnecessarily. In consequence, the `bin' output format,
+ even though it has been told by the `ORG' directive that the `.text'
+ section should start at 0, does not pass that information back to
+ the expression evaluator. So from the evaluator's point of view, `$'
+ isn't a pure number: it's an offset from a section base. Therefore
+ the difference between `$' and 510 is also not a pure number, but
+ involves a section base. Values involving section bases cannot be
+ passed as arguments to `TIMES'.
+
+ The solution, as in the previous section, is to code the `TIMES'
+ line in the form
+
+ TIMES 510-($-$$) DB 0
+
+ in which `$' and `$$' are offsets from the same section base, and so
+ their difference is a pure number. This will solve the problem and
+ generate sensible code.
+
+ 12.2 Bugs
+
+ We have never yet released a version of NASM with any _known_ bugs.
+ That doesn't usually stop there being plenty we didn't know about,
+ though. Any that you find should be reported firstly via the
+ `bugtracker' at `https://sourceforge.net/projects/nasm/' (click on
+ "Bugs"), or if that fails then through one of the contacts in
+ section 1.2.
+
+ Please read section 2.2 first, and don't report the bug if it's
+ listed in there as a deliberate feature. (If you think the feature
+ is badly thought out, feel free to send us reasons why you think it
+ should be changed, but don't just send us mail saying `This is a
+ bug' if the documentation says we did it on purpose.) Then read
+ section 12.1, and don't bother reporting the bug if it's listed
+ there.
+
+ If you do report a bug, _please_ give us all of the following
+ information:
+
+ (*) What operating system you're running NASM under. DOS, Linux,
+ NetBSD, Win16, Win32, VMS (I'd be impressed), whatever.
+
+ (*) If you're running NASM under DOS or Win32, tell us whether
+ you've compiled your own executable from the DOS source archive,
+ or whether you were using the standard distribution binaries out
+ of the archive. If you were using a locally built executable,
+ try to reproduce the problem using one of the standard binaries,
+ as this will make it easier for us to reproduce your problem
+ prior to fixing it.
+
+ (*) Which version of NASM you're using, and exactly how you invoked
+ it. Give us the precise command line, and the contents of the
+ `NASMENV' environment variable if any.
+
+ (*) Which versions of any supplementary programs you're using, and
+ how you invoked them. If the problem only becomes visible at
+ link time, tell us what linker you're using, what version of it
+ you've got, and the exact linker command line. If the problem
+ involves linking against object files generated by a compiler,
+ tell us what compiler, what version, and what command line or
+ options you used. (If you're compiling in an IDE, please try to
+ reproduce the problem with the command-line version of the
+ compiler.)
+
+ (*) If at all possible, send us a NASM source file which exhibits
+ the problem. If this causes copyright problems (e.g. you can
+ only reproduce the bug in restricted-distribution code) then
+ bear in mind the following two points: firstly, we guarantee
+ that any source code sent to us for the purposes of debugging
+ NASM will be used _only_ for the purposes of debugging NASM, and
+ that we will delete all our copies of it as soon as we have
+ found and fixed the bug or bugs in question; and secondly, we
+ would prefer _not_ to be mailed large chunks of code anyway. The
+ smaller the file, the better. A three-line sample file that does
+ nothing useful _except_ demonstrate the problem is much easier
+ to work with than a fully fledged ten-thousand-line program. (Of
+ course, some errors _do_ only crop up in large files, so this
+ may not be possible.)
+
+ (*) A description of what the problem actually _is_. `It doesn't
+ work' is _not_ a helpful description! Please describe exactly
+ what is happening that shouldn't be, or what isn't happening
+ that should. Examples might be: `NASM generates an error message
+ saying Line 3 for an error that's actually on Line 5'; `NASM
+ generates an error message that I believe it shouldn't be
+ generating at all'; `NASM fails to generate an error message
+ that I believe it _should_ be generating'; `the object file
+ produced from this source code crashes my linker'; `the ninth
+ byte of the output file is 66 and I think it should be 77
+ instead'.
+
+ (*) If you believe the output file from NASM to be faulty, send it
+ to us. That allows us to determine whether our own copy of NASM
+ generates the same file, or whether the problem is related to
+ portability issues between our development platforms and yours.
+ We can handle binary files mailed to us as MIME attachments,
+ uuencoded, and even BinHex. Alternatively, we may be able to
+ provide an FTP site you can upload the suspect files to; but
+ mailing them is easier for us.
+
+ (*) Any other information or data files that might be helpful. If,
+ for example, the problem involves NASM failing to generate an
+ object file while TASM can generate an equivalent file without
+ trouble, then send us _both_ object files, so we can see what
+ TASM is doing differently from us.
+
+Appendix A: Ndisasm
+-------------------
+
+ The Netwide Disassembler, NDISASM
+
+ A.1 Introduction
+
+ The Netwide Disassembler is a small companion program to the Netwide
+ Assembler, NASM. It seemed a shame to have an x86 assembler,
+ complete with a full instruction table, and not make as much use of
+ it as possible, so here's a disassembler which shares the
+ instruction table (and some other bits of code) with NASM.
+
+ The Netwide Disassembler does nothing except to produce
+ disassemblies of _binary_ source files. NDISASM does not have any
+ understanding of object file formats, like `objdump', and it will
+ not understand `DOS .EXE' files like `debug' will. It just
+ disassembles.
+
+ A.2 Getting Started: Installation
+
+ See section 1.3 for installation instructions. NDISASM, like NASM,
+ has a `man page' which you may want to put somewhere useful, if you
+ are on a Unix system.
+
+ A.3 Running NDISASM
+
+ To disassemble a file, you will typically use a command of the form
+
+ ndisasm -b {16|32|64} filename
+
+ NDISASM can disassemble 16-, 32- or 64-bit code equally easily,
+ provided of course that you remember to specify which it is to work
+ with. If no `-b' switch is present, NDISASM works in 16-bit mode by
+ default. The `-u' switch (for USE32) also invokes 32-bit mode.
+
+ Two more command line options are `-r' which reports the version
+ number of NDISASM you are running, and `-h' which gives a short
+ summary of command line options.
+
+ A.3.1 COM Files: Specifying an Origin
+
+ To disassemble a `DOS .COM' file correctly, a disassembler must
+ assume that the first instruction in the file is loaded at address
+ `0x100', rather than at zero. NDISASM, which assumes by default that
+ any file you give it is loaded at zero, will therefore need to be
+ informed of this.
+
+ The `-o' option allows you to declare a different origin for the
+ file you are disassembling. Its argument may be expressed in any of
+ the NASM numeric formats: decimal by default, if it begins with
+ ``$'' or ``0x'' or ends in ``H'' it's `hex', if it ends in ``Q''
+ it's `octal', and if it ends in ``B'' it's `binary'.
+
+ Hence, to disassemble a `.COM' file:
+
+ ndisasm -o100h filename.com
+
+ will do the trick.
+
+ A.3.2 Code Following Data: Synchronisation
+
+ Suppose you are disassembling a file which contains some data which
+ isn't machine code, and _then_ contains some machine code. NDISASM
+ will faithfully plough through the data section, producing machine
+ instructions wherever it can (although most of them will look
+ bizarre, and some may have unusual prefixes, e.g.
+ ``FS OR AX,0x240A''), and generating `DB' instructions ever so often
+ if it's totally stumped. Then it will reach the code section.
+
+ Supposing NDISASM has just finished generating a strange machine
+ instruction from part of the data section, and its file position is
+ now one byte _before_ the beginning of the code section. It's
+ entirely possible that another spurious instruction will get
+ generated, starting with the final byte of the data section, and
+ then the correct first instruction in the code section will not be
+ seen because the starting point skipped over it. This isn't really
+ ideal.
+
+ To avoid this, you can specify a ``synchronisation'' point, or
+ indeed as many synchronisation points as you like (although NDISASM
+ can only handle 2147483647 sync points internally). The definition
+ of a sync point is this: NDISASM guarantees to hit sync points
+ exactly during disassembly. If it is thinking about generating an
+ instruction which would cause it to jump over a sync point, it will
+ discard that instruction and output a ``db'' instead. So it _will_
+ start disassembly exactly from the sync point, and so you _will_ see
+ all the instructions in your code section.
+
+ Sync points are specified using the `-s' option: they are measured
+ in terms of the program origin, not the file position. So if you
+ want to synchronize after 32 bytes of a `.COM' file, you would have
+ to do
+
+ ndisasm -o100h -s120h file.com
+
+ rather than
+
+ ndisasm -o100h -s20h file.com
+
+ As stated above, you can specify multiple sync markers if you need
+ to, just by repeating the `-s' option.
+
+ A.3.3 Mixed Code and Data: Automatic (Intelligent) Synchronisation
+
+ Suppose you are disassembling the boot sector of a `DOS' floppy
+ (maybe it has a virus, and you need to understand the virus so that
+ you know what kinds of damage it might have done you). Typically,
+ this will contain a `JMP' instruction, then some data, then the rest
+ of the code. So there is a very good chance of NDISASM being
+ _misaligned_ when the data ends and the code begins. Hence a sync
+ point is needed.
+
+ On the other hand, why should you have to specify the sync point
+ manually? What you'd do in order to find where the sync point would
+ be, surely, would be to read the `JMP' instruction, and then to use
+ its target address as a sync point. So can NDISASM do that for you?
+
+ The answer, of course, is yes: using either of the synonymous
+ switches `-a' (for automatic sync) or `-i' (for intelligent sync)
+ will enable `auto-sync' mode. Auto-sync mode automatically generates
+ a sync point for any forward-referring PC-relative jump or call
+ instruction that NDISASM encounters. (Since NDISASM is one-pass, if
+ it encounters a PC-relative jump whose target has already been
+ processed, there isn't much it can do about it...)
+
+ Only PC-relative jumps are processed, since an absolute jump is
+ either through a register (in which case NDISASM doesn't know what
+ the register contains) or involves a segment address (in which case
+ the target code isn't in the same segment that NDISASM is working
+ in, and so the sync point can't be placed anywhere useful).
+
+ For some kinds of file, this mechanism will automatically put sync
+ points in all the right places, and save you from having to place
+ any sync points manually. However, it should be stressed that auto-
+ sync mode is _not_ guaranteed to catch all the sync points, and you
+ may still have to place some manually.
+
+ Auto-sync mode doesn't prevent you from declaring manual sync
+ points: it just adds automatically generated ones to the ones you
+ provide. It's perfectly feasible to specify `-i' _and_ some `-s'
+ options.
+
+ Another caveat with auto-sync mode is that if, by some unpleasant
+ fluke, something in your data section should disassemble to a PC-
+ relative call or jump instruction, NDISASM may obediently place a
+ sync point in a totally random place, for example in the middle of
+ one of the instructions in your code section. So you may end up with
+ a wrong disassembly even if you use auto-sync. Again, there isn't
+ much I can do about this. If you have problems, you'll have to use
+ manual sync points, or use the `-k' option (documented below) to
+ suppress disassembly of the data area.
+
+ A.3.4 Other Options
+
+ The `-e' option skips a header on the file, by ignoring the first N
+ bytes. This means that the header is _not_ counted towards the
+ disassembly offset: if you give `-e10 -o10', disassembly will start
+ at byte 10 in the file, and this will be given offset 10, not 20.
+
+ The `-k' option is provided with two comma-separated numeric
+ arguments, the first of which is an assembly offset and the second
+ is a number of bytes to skip. This _will_ count the skipped bytes
+ towards the assembly offset: its use is to suppress disassembly of a
+ data section which wouldn't contain anything you wanted to see
+ anyway.
+
+ A.4 Bugs and Improvements
+
+ There are no known bugs. However, any you find, with patches if
+ possible, should be sent to `nasm-bugs@lists.sourceforge.net', or to
+ the developer's site at `https://sourceforge.net/projects/nasm/' and
+ we'll try to fix them. Feel free to send contributions and new
+ features as well.
+
+Appendix B: Instruction List
+----------------------------
+
+ B.1 Introduction
+
+ The following sections show the instructions which NASM currently
+ supports. For each instruction, there is a separate entry for each
+ supported addressing mode. The third column shows the processor type
+ in which the instruction was introduced and, when appropriate, one
+ or more usage flags.
+
+ B.1.1 Special instructions...
+
+ DB
+ DW
+ DD
+ DQ
+ DT
+ DO
+ DY
+ RESB imm 8086
+ RESW
+ RESD
+ RESQ
+ REST
+ RESO
+ RESY
+
+ B.1.2 Conventional instructions
+
+ AAA 8086,NOLONG
+ AAD 8086,NOLONG
+ AAD imm 8086,NOLONG
+ AAM 8086,NOLONG
+ AAM imm 8086,NOLONG
+ AAS 8086,NOLONG
+ ADC mem,reg8 8086
+ ADC reg8,reg8 8086
+ ADC mem,reg16 8086
+ ADC reg16,reg16 8086
+ ADC mem,reg32 386
+ ADC reg32,reg32 386
+ ADC mem,reg64 X64
+ ADC reg64,reg64 X64
+ ADC reg8,mem 8086
+ ADC reg8,reg8 8086
+ ADC reg16,mem 8086
+ ADC reg16,reg16 8086
+ ADC reg32,mem 386
+ ADC reg32,reg32 386
+ ADC reg64,mem X64
+ ADC reg64,reg64 X64
+ ADC rm16,imm8 8086
+ ADC rm32,imm8 386
+ ADC rm64,imm8 X64
+ ADC reg_al,imm 8086
+ ADC reg_ax,sbyte16 8086
+ ADC reg_ax,imm 8086
+ ADC reg_eax,sbyte32 386
+ ADC reg_eax,imm 386
+ ADC reg_rax,sbyte64 X64
+ ADC reg_rax,imm X64
+ ADC rm8,imm 8086
+ ADC rm16,imm 8086
+ ADC rm32,imm 386
+ ADC rm64,imm X64
+ ADC mem,imm8 8086
+ ADC mem,imm16 8086
+ ADC mem,imm32 386
+ ADD mem,reg8 8086
+ ADD reg8,reg8 8086
+ ADD mem,reg16 8086
+ ADD reg16,reg16 8086
+ ADD mem,reg32 386
+ ADD reg32,reg32 386
+ ADD mem,reg64 X64
+ ADD reg64,reg64 X64
+ ADD reg8,mem 8086
+ ADD reg8,reg8 8086
+ ADD reg16,mem 8086
+ ADD reg16,reg16 8086
+ ADD reg32,mem 386
+ ADD reg32,reg32 386
+ ADD reg64,mem X64
+ ADD reg64,reg64 X64
+ ADD rm16,imm8 8086
+ ADD rm32,imm8 386
+ ADD rm64,imm8 X64
+ ADD reg_al,imm 8086
+ ADD reg_ax,sbyte16 8086
+ ADD reg_ax,imm 8086
+ ADD reg_eax,sbyte32 386
+ ADD reg_eax,imm 386
+ ADD reg_rax,sbyte64 X64
+ ADD reg_rax,imm X64
+ ADD rm8,imm 8086
+ ADD rm16,imm 8086
+ ADD rm32,imm 386
+ ADD rm64,imm X64
+ ADD mem,imm8 8086
+ ADD mem,imm16 8086
+ ADD mem,imm32 386
+ AND mem,reg8 8086
+ AND reg8,reg8 8086
+ AND mem,reg16 8086
+ AND reg16,reg16 8086
+ AND mem,reg32 386
+ AND reg32,reg32 386
+ AND mem,reg64 X64
+ AND reg64,reg64 X64
+ AND reg8,mem 8086
+ AND reg8,reg8 8086
+ AND reg16,mem 8086
+ AND reg16,reg16 8086
+ AND reg32,mem 386
+ AND reg32,reg32 386
+ AND reg64,mem X64
+ AND reg64,reg64 X64
+ AND rm16,imm8 8086
+ AND rm32,imm8 386
+ AND rm64,imm8 X64
+ AND reg_al,imm 8086
+ AND reg_ax,sbyte16 8086
+ AND reg_ax,imm 8086
+ AND reg_eax,sbyte32 386
+ AND reg_eax,imm 386
+ AND reg_rax,sbyte64 X64
+ AND reg_rax,imm X64
+ AND rm8,imm 8086
+ AND rm16,imm 8086
+ AND rm32,imm 386
+ AND rm64,imm X64
+ AND mem,imm8 8086
+ AND mem,imm16 8086
+ AND mem,imm32 386
+ ARPL mem,reg16 286,PROT,NOLONG
+ ARPL reg16,reg16 286,PROT,NOLONG
+ BB0_RESET PENT,CYRIX,ND
+ BB1_RESET PENT,CYRIX,ND
+ BOUND reg16,mem 186,NOLONG
+ BOUND reg32,mem 386,NOLONG
+ BSF reg16,mem 386
+ BSF reg16,reg16 386
+ BSF reg32,mem 386
+ BSF reg32,reg32 386
+ BSF reg64,mem X64
+ BSF reg64,reg64 X64
+ BSR reg16,mem 386
+ BSR reg16,reg16 386
+ BSR reg32,mem 386
+ BSR reg32,reg32 386
+ BSR reg64,mem X64
+ BSR reg64,reg64 X64
+ BSWAP reg32 486
+ BSWAP reg64 X64
+ BT mem,reg16 386
+ BT reg16,reg16 386
+ BT mem,reg32 386
+ BT reg32,reg32 386
+ BT mem,reg64 X64
+ BT reg64,reg64 X64
+ BT rm16,imm 386
+ BT rm32,imm 386
+ BT rm64,imm X64
+ BTC mem,reg16 386
+ BTC reg16,reg16 386
+ BTC mem,reg32 386
+ BTC reg32,reg32 386
+ BTC mem,reg64 X64
+ BTC reg64,reg64 X64
+ BTC rm16,imm 386
+ BTC rm32,imm 386
+ BTC rm64,imm X64
+ BTR mem,reg16 386
+ BTR reg16,reg16 386
+ BTR mem,reg32 386
+ BTR reg32,reg32 386
+ BTR mem,reg64 X64
+ BTR reg64,reg64 X64
+ BTR rm16,imm 386
+ BTR rm32,imm 386
+ BTR rm64,imm X64
+ BTS mem,reg16 386
+ BTS reg16,reg16 386
+ BTS mem,reg32 386
+ BTS reg32,reg32 386
+ BTS mem,reg64 X64
+ BTS reg64,reg64 X64
+ BTS rm16,imm 386
+ BTS rm32,imm 386
+ BTS rm64,imm X64
+ CALL imm 8086
+ CALL imm|near 8086
+ CALL imm|far 8086,ND,NOLONG
+ CALL imm16 8086
+ CALL imm16|near 8086
+ CALL imm16|far 8086,ND,NOLONG
+ CALL imm32 386
+ CALL imm32|near 386
+ CALL imm32|far 386,ND,NOLONG
+ CALL imm:imm 8086,NOLONG
+ CALL imm16:imm 8086,NOLONG
+ CALL imm:imm16 8086,NOLONG
+ CALL imm32:imm 386,NOLONG
+ CALL imm:imm32 386,NOLONG
+ CALL mem|far 8086,NOLONG
+ CALL mem|far X64
+ CALL mem16|far 8086
+ CALL mem32|far 386
+ CALL mem64|far X64
+ CALL mem|near 8086
+ CALL mem16|near 8086
+ CALL mem32|near 386,NOLONG
+ CALL mem64|near X64
+ CALL reg16 8086
+ CALL reg32 386,NOLONG
+ CALL reg64 X64
+ CALL mem 8086
+ CALL mem16 8086
+ CALL mem32 386,NOLONG
+ CALL mem64 X64
+ CBW 8086
+ CDQ 386
+ CDQE X64
+ CLC 8086
+ CLD 8086
+ CLGI X64,AMD
+ CLI 8086
+ CLTS 286,PRIV
+ CMC 8086
+ CMP mem,reg8 8086
+ CMP reg8,reg8 8086
+ CMP mem,reg16 8086
+ CMP reg16,reg16 8086
+ CMP mem,reg32 386
+ CMP reg32,reg32 386
+ CMP mem,reg64 X64
+ CMP reg64,reg64 X64
+ CMP reg8,mem 8086
+ CMP reg8,reg8 8086
+ CMP reg16,mem 8086
+ CMP reg16,reg16 8086
+ CMP reg32,mem 386
+ CMP reg32,reg32 386
+ CMP reg64,mem X64
+ CMP reg64,reg64 X64
+ CMP rm16,imm8 8086
+ CMP rm32,imm8 386
+ CMP rm64,imm8 X64
+ CMP reg_al,imm 8086
+ CMP reg_ax,sbyte16 8086
+ CMP reg_ax,imm 8086
+ CMP reg_eax,sbyte32 386
+ CMP reg_eax,imm 386
+ CMP reg_rax,sbyte64 X64
+ CMP reg_rax,imm X64
+ CMP rm8,imm 8086
+ CMP rm16,imm 8086
+ CMP rm32,imm 386
+ CMP rm64,imm X64
+ CMP mem,imm8 8086
+ CMP mem,imm16 8086
+ CMP mem,imm32 386
+ CMPSB 8086
+ CMPSD 386
+ CMPSQ X64
+ CMPSW 8086
+ CMPXCHG mem,reg8 PENT
+ CMPXCHG reg8,reg8 PENT
+ CMPXCHG mem,reg16 PENT
+ CMPXCHG reg16,reg16 PENT
+ CMPXCHG mem,reg32 PENT
+ CMPXCHG reg32,reg32 PENT
+ CMPXCHG mem,reg64 X64
+ CMPXCHG reg64,reg64 X64
+ CMPXCHG486 mem,reg8 486,UNDOC,ND
+ CMPXCHG486 reg8,reg8 486,UNDOC,ND
+ CMPXCHG486 mem,reg16 486,UNDOC,ND
+ CMPXCHG486 reg16,reg16 486,UNDOC,ND
+ CMPXCHG486 mem,reg32 486,UNDOC,ND
+ CMPXCHG486 reg32,reg32 486,UNDOC,ND
+ CMPXCHG8B mem PENT
+ CMPXCHG16B mem X64
+ CPUID PENT
+ CPU_READ PENT,CYRIX
+ CPU_WRITE PENT,CYRIX
+ CQO X64
+ CWD 8086
+ CWDE 386
+ DAA 8086,NOLONG
+ DAS 8086,NOLONG
+ DEC reg16 8086,NOLONG
+ DEC reg32 386,NOLONG
+ DEC rm8 8086
+ DEC rm16 8086
+ DEC rm32 386
+ DEC rm64 X64
+ DIV rm8 8086
+ DIV rm16 8086
+ DIV rm32 386
+ DIV rm64 X64
+ DMINT P6,CYRIX
+ EMMS PENT,MMX
+ ENTER imm,imm 186
+ EQU imm 8086
+ EQU imm:imm 8086
+ F2XM1 8086,FPU
+ FABS 8086,FPU
+ FADD mem32 8086,FPU
+ FADD mem64 8086,FPU
+ FADD fpureg|to 8086,FPU
+ FADD fpureg 8086,FPU
+ FADD fpureg,fpu0 8086,FPU
+ FADD fpu0,fpureg 8086,FPU
+ FADD 8086,FPU,ND
+ FADDP fpureg 8086,FPU
+ FADDP fpureg,fpu0 8086,FPU
+ FADDP 8086,FPU,ND
+ FBLD mem80 8086,FPU
+ FBLD mem 8086,FPU
+ FBSTP mem80 8086,FPU
+ FBSTP mem 8086,FPU
+ FCHS 8086,FPU
+ FCLEX 8086,FPU
+ FCMOVB fpureg P6,FPU
+ FCMOVB fpu0,fpureg P6,FPU
+ FCMOVB P6,FPU,ND
+ FCMOVBE fpureg P6,FPU
+ FCMOVBE fpu0,fpureg P6,FPU
+ FCMOVBE P6,FPU,ND
+ FCMOVE fpureg P6,FPU
+ FCMOVE fpu0,fpureg P6,FPU
+ FCMOVE P6,FPU,ND
+ FCMOVNB fpureg P6,FPU
+ FCMOVNB fpu0,fpureg P6,FPU
+ FCMOVNB P6,FPU,ND
+ FCMOVNBE fpureg P6,FPU
+ FCMOVNBE fpu0,fpureg P6,FPU
+ FCMOVNBE P6,FPU,ND
+ FCMOVNE fpureg P6,FPU
+ FCMOVNE fpu0,fpureg P6,FPU
+ FCMOVNE P6,FPU,ND
+ FCMOVNU fpureg P6,FPU
+ FCMOVNU fpu0,fpureg P6,FPU
+ FCMOVNU P6,FPU,ND
+ FCMOVU fpureg P6,FPU
+ FCMOVU fpu0,fpureg P6,FPU
+ FCMOVU P6,FPU,ND
+ FCOM mem32 8086,FPU
+ FCOM mem64 8086,FPU
+ FCOM fpureg 8086,FPU
+ FCOM fpu0,fpureg 8086,FPU
+ FCOM 8086,FPU,ND
+ FCOMI fpureg P6,FPU
+ FCOMI fpu0,fpureg P6,FPU
+ FCOMI P6,FPU,ND
+ FCOMIP fpureg P6,FPU
+ FCOMIP fpu0,fpureg P6,FPU
+ FCOMIP P6,FPU,ND
+ FCOMP mem32 8086,FPU
+ FCOMP mem64 8086,FPU
+ FCOMP fpureg 8086,FPU
+ FCOMP fpu0,fpureg 8086,FPU
+ FCOMP 8086,FPU,ND
+ FCOMPP 8086,FPU
+ FCOS 386,FPU
+ FDECSTP 8086,FPU
+ FDISI 8086,FPU
+ FDIV mem32 8086,FPU
+ FDIV mem64 8086,FPU
+ FDIV fpureg|to 8086,FPU
+ FDIV fpureg 8086,FPU
+ FDIV fpureg,fpu0 8086,FPU
+ FDIV fpu0,fpureg 8086,FPU
+ FDIV 8086,FPU,ND
+ FDIVP fpureg 8086,FPU
+ FDIVP fpureg,fpu0 8086,FPU
+ FDIVP 8086,FPU,ND
+ FDIVR mem32 8086,FPU
+ FDIVR mem64 8086,FPU
+ FDIVR fpureg|to 8086,FPU
+ FDIVR fpureg,fpu0 8086,FPU
+ FDIVR fpureg 8086,FPU
+ FDIVR fpu0,fpureg 8086,FPU
+ FDIVR 8086,FPU,ND
+ FDIVRP fpureg 8086,FPU
+ FDIVRP fpureg,fpu0 8086,FPU
+ FDIVRP 8086,FPU,ND
+ FEMMS PENT,3DNOW
+ FENI 8086,FPU
+ FFREE fpureg 8086,FPU
+ FFREE 8086,FPU
+ FFREEP fpureg 286,FPU,UNDOC
+ FFREEP 286,FPU,UNDOC
+ FIADD mem32 8086,FPU
+ FIADD mem16 8086,FPU
+ FICOM mem32 8086,FPU
+ FICOM mem16 8086,FPU
+ FICOMP mem32 8086,FPU
+ FICOMP mem16 8086,FPU
+ FIDIV mem32 8086,FPU
+ FIDIV mem16 8086,FPU
+ FIDIVR mem32 8086,FPU
+ FIDIVR mem16 8086,FPU
+ FILD mem32 8086,FPU
+ FILD mem16 8086,FPU
+ FILD mem64 8086,FPU
+ FIMUL mem32 8086,FPU
+ FIMUL mem16 8086,FPU
+ FINCSTP 8086,FPU
+ FINIT 8086,FPU
+ FIST mem32 8086,FPU
+ FIST mem16 8086,FPU
+ FISTP mem32 8086,FPU
+ FISTP mem16 8086,FPU
+ FISTP mem64 8086,FPU
+ FISTTP mem16 PRESCOTT,FPU
+ FISTTP mem32 PRESCOTT,FPU
+ FISTTP mem64 PRESCOTT,FPU
+ FISUB mem32 8086,FPU
+ FISUB mem16 8086,FPU
+ FISUBR mem32 8086,FPU
+ FISUBR mem16 8086,FPU
+ FLD mem32 8086,FPU
+ FLD mem64 8086,FPU
+ FLD mem80 8086,FPU
+ FLD fpureg 8086,FPU
+ FLD 8086,FPU,ND
+ FLD1 8086,FPU
+ FLDCW mem 8086,FPU,SW
+ FLDENV mem 8086,FPU
+ FLDL2E 8086,FPU
+ FLDL2T 8086,FPU
+ FLDLG2 8086,FPU
+ FLDLN2 8086,FPU
+ FLDPI 8086,FPU
+ FLDZ 8086,FPU
+ FMUL mem32 8086,FPU
+ FMUL mem64 8086,FPU
+ FMUL fpureg|to 8086,FPU
+ FMUL fpureg,fpu0 8086,FPU
+ FMUL fpureg 8086,FPU
+ FMUL fpu0,fpureg 8086,FPU
+ FMUL 8086,FPU,ND
+ FMULP fpureg 8086,FPU
+ FMULP fpureg,fpu0 8086,FPU
+ FMULP 8086,FPU,ND
+ FNCLEX 8086,FPU
+ FNDISI 8086,FPU
+ FNENI 8086,FPU
+ FNINIT 8086,FPU
+ FNOP 8086,FPU
+ FNSAVE mem 8086,FPU
+ FNSTCW mem 8086,FPU,SW
+ FNSTENV mem 8086,FPU
+ FNSTSW mem 8086,FPU,SW
+ FNSTSW reg_ax 286,FPU
+ FPATAN 8086,FPU
+ FPREM 8086,FPU
+ FPREM1 386,FPU
+ FPTAN 8086,FPU
+ FRNDINT 8086,FPU
+ FRSTOR mem 8086,FPU
+ FSAVE mem 8086,FPU
+ FSCALE 8086,FPU
+ FSETPM 286,FPU
+ FSIN 386,FPU
+ FSINCOS 386,FPU
+ FSQRT 8086,FPU
+ FST mem32 8086,FPU
+ FST mem64 8086,FPU
+ FST fpureg 8086,FPU
+ FST 8086,FPU,ND
+ FSTCW mem 8086,FPU,SW
+ FSTENV mem 8086,FPU
+ FSTP mem32 8086,FPU
+ FSTP mem64 8086,FPU
+ FSTP mem80 8086,FPU
+ FSTP fpureg 8086,FPU
+ FSTP 8086,FPU,ND
+ FSTSW mem 8086,FPU,SW
+ FSTSW reg_ax 286,FPU
+ FSUB mem32 8086,FPU
+ FSUB mem64 8086,FPU
+ FSUB fpureg|to 8086,FPU
+ FSUB fpureg,fpu0 8086,FPU
+ FSUB fpureg 8086,FPU
+ FSUB fpu0,fpureg 8086,FPU
+ FSUB 8086,FPU,ND
+ FSUBP fpureg 8086,FPU
+ FSUBP fpureg,fpu0 8086,FPU
+ FSUBP 8086,FPU,ND
+ FSUBR mem32 8086,FPU
+ FSUBR mem64 8086,FPU
+ FSUBR fpureg|to 8086,FPU
+ FSUBR fpureg,fpu0 8086,FPU
+ FSUBR fpureg 8086,FPU
+ FSUBR fpu0,fpureg 8086,FPU
+ FSUBR 8086,FPU,ND
+ FSUBRP fpureg 8086,FPU
+ FSUBRP fpureg,fpu0 8086,FPU
+ FSUBRP 8086,FPU,ND
+ FTST 8086,FPU
+ FUCOM fpureg 386,FPU
+ FUCOM fpu0,fpureg 386,FPU
+ FUCOM 386,FPU,ND
+ FUCOMI fpureg P6,FPU
+ FUCOMI fpu0,fpureg P6,FPU
+ FUCOMI P6,FPU,ND
+ FUCOMIP fpureg P6,FPU
+ FUCOMIP fpu0,fpureg P6,FPU
+ FUCOMIP P6,FPU,ND
+ FUCOMP fpureg 386,FPU
+ FUCOMP fpu0,fpureg 386,FPU
+ FUCOMP 386,FPU,ND
+ FUCOMPP 386,FPU
+ FXAM 8086,FPU
+ FXCH fpureg 8086,FPU
+ FXCH fpureg,fpu0 8086,FPU
+ FXCH fpu0,fpureg 8086,FPU
+ FXCH 8086,FPU,ND
+ FXTRACT 8086,FPU
+ FYL2X 8086,FPU
+ FYL2XP1 8086,FPU
+ HLT 8086,PRIV
+ IBTS mem,reg16 386,SW,UNDOC,ND
+ IBTS reg16,reg16 386,UNDOC,ND
+ IBTS mem,reg32 386,SD,UNDOC,ND
+ IBTS reg32,reg32 386,UNDOC,ND
+ ICEBP 386,ND
+ IDIV rm8 8086
+ IDIV rm16 8086
+ IDIV rm32 386
+ IDIV rm64 X64
+ IMUL rm8 8086
+ IMUL rm16 8086
+ IMUL rm32 386
+ IMUL rm64 X64
+ IMUL reg16,mem 386
+ IMUL reg16,reg16 386
+ IMUL reg32,mem 386
+ IMUL reg32,reg32 386
+ IMUL reg64,mem X64
+ IMUL reg64,reg64 X64
+ IMUL reg16,mem,imm8 186
+ IMUL reg16,mem,sbyte16 186,ND
+ IMUL reg16,mem,imm16 186
+ IMUL reg16,mem,imm 186,ND
+ IMUL reg16,reg16,imm8 186
+ IMUL reg16,reg16,sbyte16 186,ND
+ IMUL reg16,reg16,imm16 186
+ IMUL reg16,reg16,imm 186,ND
+ IMUL reg32,mem,imm8 386
+ IMUL reg32,mem,sbyte32 386,ND
+ IMUL reg32,mem,imm32 386
+ IMUL reg32,mem,imm 386,ND
+ IMUL reg32,reg32,imm8 386
+ IMUL reg32,reg32,sbyte32 386,ND
+ IMUL reg32,reg32,imm32 386
+ IMUL reg32,reg32,imm 386,ND
+ IMUL reg64,mem,imm8 X64
+ IMUL reg64,mem,sbyte64 X64,ND
+ IMUL reg64,mem,imm32 X64
+ IMUL reg64,mem,imm X64,ND
+ IMUL reg64,reg64,imm8 X64
+ IMUL reg64,reg64,sbyte64 X64,ND
+ IMUL reg64,reg64,imm32 X64
+ IMUL reg64,reg64,imm X64,ND
+ IMUL reg16,imm8 186
+ IMUL reg16,sbyte16 186,ND
+ IMUL reg16,imm16 186
+ IMUL reg16,imm 186,ND
+ IMUL reg32,imm8 386
+ IMUL reg32,sbyte32 386,ND
+ IMUL reg32,imm32 386
+ IMUL reg32,imm 386,ND
+ IMUL reg64,imm8 X64
+ IMUL reg64,sbyte64 X64,ND
+ IMUL reg64,imm32 X64
+ IMUL reg64,imm X64,ND
+ IN reg_al,imm 8086
+ IN reg_ax,imm 8086
+ IN reg_eax,imm 386
+ IN reg_al,reg_dx 8086
+ IN reg_ax,reg_dx 8086
+ IN reg_eax,reg_dx 386
+ INC reg16 8086,NOLONG
+ INC reg32 386,NOLONG
+ INC rm8 8086
+ INC rm16 8086
+ INC rm32 386
+ INC rm64 X64
+ INCBIN
+ INSB 186
+ INSD 386
+ INSW 186
+ INT imm 8086
+ INT01 386,ND
+ INT1 386
+ INT03 8086,ND
+ INT3 8086
+ INTO 8086,NOLONG
+ INVD 486,PRIV
+ INVLPG mem 486,PRIV
+ INVLPGA reg_ax,reg_ecx X86_64,AMD,NOLONG
+ INVLPGA reg_eax,reg_ecx X86_64,AMD
+ INVLPGA reg_rax,reg_ecx X64,AMD
+ INVLPGA X86_64,AMD
+ IRET 8086
+ IRETD 386
+ IRETQ X64
+ IRETW 8086
+ JCXZ imm 8086,NOLONG
+ JECXZ imm 386
+ JRCXZ imm X64
+ JMP imm|short 8086
+ JMP imm 8086,ND
+ JMP imm 8086
+ JMP imm|near 8086,ND
+ JMP imm|far 8086,ND,NOLONG
+ JMP imm16 8086
+ JMP imm16|near 8086,ND
+ JMP imm16|far 8086,ND,NOLONG
+ JMP imm32 386
+ JMP imm32|near 386,ND
+ JMP imm32|far 386,ND,NOLONG
+ JMP imm:imm 8086,NOLONG
+ JMP imm16:imm 8086,NOLONG
+ JMP imm:imm16 8086,NOLONG
+ JMP imm32:imm 386,NOLONG
+ JMP imm:imm32 386,NOLONG
+ JMP mem|far 8086,NOLONG
+ JMP mem|far X64
+ JMP mem16|far 8086
+ JMP mem32|far 386
+ JMP mem64|far X64
+ JMP mem|near 8086
+ JMP mem16|near 8086
+ JMP mem32|near 386,NOLONG
+ JMP mem64|near X64
+ JMP reg16 8086
+ JMP reg32 386,NOLONG
+ JMP reg64 X64
+ JMP mem 8086
+ JMP mem16 8086
+ JMP mem32 386,NOLONG
+ JMP mem64 X64
+ JMPE imm IA64
+ JMPE imm16 IA64
+ JMPE imm32 IA64
+ JMPE rm16 IA64
+ JMPE rm32 IA64
+ LAHF 8086
+ LAR reg16,mem 286,PROT,SW
+ LAR reg16,reg16 286,PROT
+ LAR reg16,reg32 386,PROT
+ LAR reg16,reg64 X64,PROT,ND
+ LAR reg32,mem 386,PROT,SW
+ LAR reg32,reg16 386,PROT
+ LAR reg32,reg32 386,PROT
+ LAR reg32,reg64 X64,PROT,ND
+ LAR reg64,mem X64,PROT,SW
+ LAR reg64,reg16 X64,PROT
+ LAR reg64,reg32 X64,PROT
+ LAR reg64,reg64 X64,PROT
+ LDS reg16,mem 8086,NOLONG
+ LDS reg32,mem 386,NOLONG
+ LEA reg16,mem 8086
+ LEA reg32,mem 386
+ LEA reg64,mem X64
+ LEAVE 186
+ LES reg16,mem 8086,NOLONG
+ LES reg32,mem 386,NOLONG
+ LFENCE X64,AMD
+ LFS reg16,mem 386
+ LFS reg32,mem 386
+ LGDT mem 286,PRIV
+ LGS reg16,mem 386
+ LGS reg32,mem 386
+ LIDT mem 286,PRIV
+ LLDT mem 286,PROT,PRIV
+ LLDT mem16 286,PROT,PRIV
+ LLDT reg16 286,PROT,PRIV
+ LMSW mem 286,PRIV
+ LMSW mem16 286,PRIV
+ LMSW reg16 286,PRIV
+ LOADALL 386,UNDOC
+ LOADALL286 286,UNDOC
+ LODSB 8086
+ LODSD 386
+ LODSQ X64
+ LODSW 8086
+ LOOP imm 8086
+ LOOP imm,reg_cx 8086,NOLONG
+ LOOP imm,reg_ecx 386
+ LOOP imm,reg_rcx X64
+ LOOPE imm 8086
+ LOOPE imm,reg_cx 8086,NOLONG
+ LOOPE imm,reg_ecx 386
+ LOOPE imm,reg_rcx X64
+ LOOPNE imm 8086
+ LOOPNE imm,reg_cx 8086,NOLONG
+ LOOPNE imm,reg_ecx 386
+ LOOPNE imm,reg_rcx X64
+ LOOPNZ imm 8086
+ LOOPNZ imm,reg_cx 8086,NOLONG
+ LOOPNZ imm,reg_ecx 386
+ LOOPNZ imm,reg_rcx X64
+ LOOPZ imm 8086
+ LOOPZ imm,reg_cx 8086,NOLONG
+ LOOPZ imm,reg_ecx 386
+ LOOPZ imm,reg_rcx X64
+ LSL reg16,mem 286,PROT,SW
+ LSL reg16,reg16 286,PROT
+ LSL reg16,reg32 386,PROT
+ LSL reg16,reg64 X64,PROT,ND
+ LSL reg32,mem 386,PROT,SW
+ LSL reg32,reg16 386,PROT
+ LSL reg32,reg32 386,PROT
+ LSL reg32,reg64 X64,PROT,ND
+ LSL reg64,mem X64,PROT,SW
+ LSL reg64,reg16 X64,PROT
+ LSL reg64,reg32 X64,PROT
+ LSL reg64,reg64 X64,PROT
+ LSS reg16,mem 386
+ LSS reg32,mem 386
+ LTR mem 286,PROT,PRIV
+ LTR mem16 286,PROT,PRIV
+ LTR reg16 286,PROT,PRIV
+ MFENCE X64,AMD
+ MONITOR PRESCOTT
+ MONITOR reg_eax,reg_ecx,reg_edx PRESCOTT,ND
+ MONITOR reg_rax,reg_ecx,reg_edx X64,ND
+ MOV mem,reg_sreg 8086
+ MOV reg16,reg_sreg 8086
+ MOV reg32,reg_sreg 386
+ MOV reg_sreg,mem 8086
+ MOV reg_sreg,reg16 8086
+ MOV reg_sreg,reg32 386
+ MOV reg_al,mem_offs 8086
+ MOV reg_ax,mem_offs 8086
+ MOV reg_eax,mem_offs 386
+ MOV reg_rax,mem_offs X64
+ MOV mem_offs,reg_al 8086
+ MOV mem_offs,reg_ax 8086
+ MOV mem_offs,reg_eax 386
+ MOV mem_offs,reg_rax X64
+ MOV reg32,reg_creg 386,PRIV,NOLONG
+ MOV reg64,reg_creg X64,PRIV
+ MOV reg_creg,reg32 386,PRIV,NOLONG
+ MOV reg_creg,reg64 X64,PRIV
+ MOV reg32,reg_dreg 386,PRIV,NOLONG
+ MOV reg64,reg_dreg X64,PRIV
+ MOV reg_dreg,reg32 386,PRIV,NOLONG
+ MOV reg_dreg,reg64 X64,PRIV
+ MOV reg32,reg_treg 386,NOLONG,ND
+ MOV reg_treg,reg32 386,NOLONG,ND
+ MOV mem,reg8 8086
+ MOV reg8,reg8 8086
+ MOV mem,reg16 8086
+ MOV reg16,reg16 8086
+ MOV mem,reg32 386
+ MOV reg32,reg32 386
+ MOV mem,reg64 X64
+ MOV reg64,reg64 X64
+ MOV reg8,mem 8086
+ MOV reg8,reg8 8086
+ MOV reg16,mem 8086
+ MOV reg16,reg16 8086
+ MOV reg32,mem 386
+ MOV reg32,reg32 386
+ MOV reg64,mem X64
+ MOV reg64,reg64 X64
+ MOV reg8,imm 8086
+ MOV reg16,imm 8086
+ MOV reg32,imm 386
+ MOV reg64,imm X64
+ MOV reg64,imm32 X64
+ MOV rm8,imm 8086
+ MOV rm16,imm 8086
+ MOV rm32,imm 386
+ MOV rm64,imm X64
+ MOV mem,imm8 8086
+ MOV mem,imm16 8086
+ MOV mem,imm32 386
+ MOVD mmxreg,mem PENT,MMX,SD
+ MOVD mmxreg,reg32 PENT,MMX
+ MOVD mem,mmxreg PENT,MMX,SD
+ MOVD reg32,mmxreg PENT,MMX
+ MOVD xmmreg,mem X64,SD
+ MOVD xmmreg,reg32 X64
+ MOVD mem,xmmreg X64,SD
+ MOVD reg32,xmmreg X64,SSE
+ MOVQ mmxreg,mmxrm PENT,MMX
+ MOVQ mmxrm,mmxreg PENT,MMX
+ MOVQ mmxreg,rm64 X64,MMX
+ MOVQ rm64,mmxreg X64,MMX
+ MOVSB 8086
+ MOVSD 386
+ MOVSQ X64
+ MOVSW 8086
+ MOVSX reg16,mem 386
+ MOVSX reg16,reg8 386
+ MOVSX reg32,rm8 386
+ MOVSX reg32,rm16 386
+ MOVSX reg64,rm8 X64
+ MOVSX reg64,rm16 X64
+ MOVSXD reg64,rm32 X64
+ MOVSX reg64,rm32 X64,ND
+ MOVZX reg16,mem 386
+ MOVZX reg16,reg8 386
+ MOVZX reg32,rm8 386
+ MOVZX reg32,rm16 386
+ MOVZX reg64,rm8 X64
+ MOVZX reg64,rm16 X64
+ MUL rm8 8086
+ MUL rm16 8086
+ MUL rm32 386
+ MUL rm64 X64
+ MWAIT PRESCOTT
+ MWAIT reg_eax,reg_ecx PRESCOTT,ND
+ NEG rm8 8086
+ NEG rm16 8086
+ NEG rm32 386
+ NEG rm64 X64
+ NOP 8086
+ NOP rm16 P6
+ NOP rm32 P6
+ NOP rm64 X64
+ NOT rm8 8086
+ NOT rm16 8086
+ NOT rm32 386
+ NOT rm64 X64
+ OR mem,reg8 8086
+ OR reg8,reg8 8086
+ OR mem,reg16 8086
+ OR reg16,reg16 8086
+ OR mem,reg32 386
+ OR reg32,reg32 386
+ OR mem,reg64 X64
+ OR reg64,reg64 X64
+ OR reg8,mem 8086
+ OR reg8,reg8 8086
+ OR reg16,mem 8086
+ OR reg16,reg16 8086
+ OR reg32,mem 386
+ OR reg32,reg32 386
+ OR reg64,mem X64
+ OR reg64,reg64 X64
+ OR rm16,imm8 8086
+ OR rm32,imm8 386
+ OR rm64,imm8 X64
+ OR reg_al,imm 8086
+ OR reg_ax,sbyte16 8086
+ OR reg_ax,imm 8086
+ OR reg_eax,sbyte32 386
+ OR reg_eax,imm 386
+ OR reg_rax,sbyte64 X64
+ OR reg_rax,imm X64
+ OR rm8,imm 8086
+ OR rm16,imm 8086
+ OR rm32,imm 386
+ OR rm64,imm X64
+ OR mem,imm8 8086
+ OR mem,imm16 8086
+ OR mem,imm32 386
+ OUT imm,reg_al 8086
+ OUT imm,reg_ax 8086
+ OUT imm,reg_eax 386
+ OUT reg_dx,reg_al 8086
+ OUT reg_dx,reg_ax 8086
+ OUT reg_dx,reg_eax 386
+ OUTSB 186
+ OUTSD 386
+ OUTSW 186
+ PACKSSDW mmxreg,mmxrm PENT,MMX
+ PACKSSWB mmxreg,mmxrm PENT,MMX
+ PACKUSWB mmxreg,mmxrm PENT,MMX
+ PADDB mmxreg,mmxrm PENT,MMX
+ PADDD mmxreg,mmxrm PENT,MMX
+ PADDSB mmxreg,mmxrm PENT,MMX
+ PADDSIW mmxreg,mmxrm PENT,MMX,CYRIX
+ PADDSW mmxreg,mmxrm PENT,MMX
+ PADDUSB mmxreg,mmxrm PENT,MMX
+ PADDUSW mmxreg,mmxrm PENT,MMX
+ PADDW mmxreg,mmxrm PENT,MMX
+ PAND mmxreg,mmxrm PENT,MMX
+ PANDN mmxreg,mmxrm PENT,MMX
+ PAUSE 8086
+ PAVEB mmxreg,mmxrm PENT,MMX,CYRIX
+ PAVGUSB mmxreg,mmxrm PENT,3DNOW
+ PCMPEQB mmxreg,mmxrm PENT,MMX
+ PCMPEQD mmxreg,mmxrm PENT,MMX
+ PCMPEQW mmxreg,mmxrm PENT,MMX
+ PCMPGTB mmxreg,mmxrm PENT,MMX
+ PCMPGTD mmxreg,mmxrm PENT,MMX
+ PCMPGTW mmxreg,mmxrm PENT,MMX
+ PDISTIB mmxreg,mem PENT,MMX,CYRIX
+ PF2ID mmxreg,mmxrm PENT,3DNOW
+ PFACC mmxreg,mmxrm PENT,3DNOW
+ PFADD mmxreg,mmxrm PENT,3DNOW
+ PFCMPEQ mmxreg,mmxrm PENT,3DNOW
+ PFCMPGE mmxreg,mmxrm PENT,3DNOW
+ PFCMPGT mmxreg,mmxrm PENT,3DNOW
+ PFMAX mmxreg,mmxrm PENT,3DNOW
+ PFMIN mmxreg,mmxrm PENT,3DNOW
+ PFMUL mmxreg,mmxrm PENT,3DNOW
+ PFRCP mmxreg,mmxrm PENT,3DNOW
+ PFRCPIT1 mmxreg,mmxrm PENT,3DNOW
+ PFRCPIT2 mmxreg,mmxrm PENT,3DNOW
+ PFRSQIT1 mmxreg,mmxrm PENT,3DNOW
+ PFRSQRT mmxreg,mmxrm PENT,3DNOW
+ PFSUB mmxreg,mmxrm PENT,3DNOW
+ PFSUBR mmxreg,mmxrm PENT,3DNOW
+ PI2FD mmxreg,mmxrm PENT,3DNOW
+ PMACHRIW mmxreg,mem PENT,MMX,CYRIX
+ PMADDWD mmxreg,mmxrm PENT,MMX
+ PMAGW mmxreg,mmxrm PENT,MMX,CYRIX
+ PMULHRIW mmxreg,mmxrm PENT,MMX,CYRIX
+ PMULHRWA mmxreg,mmxrm PENT,3DNOW
+ PMULHRWC mmxreg,mmxrm PENT,MMX,CYRIX
+ PMULHW mmxreg,mmxrm PENT,MMX
+ PMULLW mmxreg,mmxrm PENT,MMX
+ PMVGEZB mmxreg,mem PENT,MMX,CYRIX
+ PMVLZB mmxreg,mem PENT,MMX,CYRIX
+ PMVNZB mmxreg,mem PENT,MMX,CYRIX
+ PMVZB mmxreg,mem PENT,MMX,CYRIX
+ POP reg16 8086
+ POP reg32 386,NOLONG
+ POP reg64 X64
+ POP rm16 8086
+ POP rm32 386,NOLONG
+ POP rm64 X64
+ POP reg_cs 8086,UNDOC,ND
+ POP reg_dess 8086,NOLONG
+ POP reg_fsgs 386
+ POPA 186,NOLONG
+ POPAD 386,NOLONG
+ POPAW 186,NOLONG
+ POPF 8086
+ POPFD 386,NOLONG
+ POPFQ X64
+ POPFW 8086
+ POR mmxreg,mmxrm PENT,MMX
+ PREFETCH mem PENT,3DNOW
+ PREFETCHW mem PENT,3DNOW
+ PSLLD mmxreg,mmxrm PENT,MMX
+ PSLLD mmxreg,imm PENT,MMX
+ PSLLQ mmxreg,mmxrm PENT,MMX
+ PSLLQ mmxreg,imm PENT,MMX
+ PSLLW mmxreg,mmxrm PENT,MMX
+ PSLLW mmxreg,imm PENT,MMX
+ PSRAD mmxreg,mmxrm PENT,MMX
+ PSRAD mmxreg,imm PENT,MMX
+ PSRAW mmxreg,mmxrm PENT,MMX
+ PSRAW mmxreg,imm PENT,MMX
+ PSRLD mmxreg,mmxrm PENT,MMX
+ PSRLD mmxreg,imm PENT,MMX
+ PSRLQ mmxreg,mmxrm PENT,MMX
+ PSRLQ mmxreg,imm PENT,MMX
+ PSRLW mmxreg,mmxrm PENT,MMX
+ PSRLW mmxreg,imm PENT,MMX
+ PSUBB mmxreg,mmxrm PENT,MMX
+ PSUBD mmxreg,mmxrm PENT,MMX
+ PSUBSB mmxreg,mmxrm PENT,MMX
+ PSUBSIW mmxreg,mmxrm PENT,MMX,CYRIX
+ PSUBSW mmxreg,mmxrm PENT,MMX
+ PSUBUSB mmxreg,mmxrm PENT,MMX
+ PSUBUSW mmxreg,mmxrm PENT,MMX
+ PSUBW mmxreg,mmxrm PENT,MMX
+ PUNPCKHBW mmxreg,mmxrm PENT,MMX
+ PUNPCKHDQ mmxreg,mmxrm PENT,MMX
+ PUNPCKHWD mmxreg,mmxrm PENT,MMX
+ PUNPCKLBW mmxreg,mmxrm PENT,MMX
+ PUNPCKLDQ mmxreg,mmxrm PENT,MMX
+ PUNPCKLWD mmxreg,mmxrm PENT,MMX
+ PUSH reg16 8086
+ PUSH reg32 386,NOLONG
+ PUSH reg64 X64
+ PUSH rm16 8086
+ PUSH rm32 386,NOLONG
+ PUSH rm64 X64
+ PUSH reg_cs 8086,NOLONG
+ PUSH reg_dess 8086,NOLONG
+ PUSH reg_fsgs 386
+ PUSH imm8 186
+ PUSH imm16 186,AR0,SZ
+ PUSH imm32 386,NOLONG,AR0,SZ
+ PUSH imm32 386,NOLONG,SD
+ PUSH imm64 X64,AR0,SZ
+ PUSHA 186,NOLONG
+ PUSHAD 386,NOLONG
+ PUSHAW 186,NOLONG
+ PUSHF 8086
+ PUSHFD 386,NOLONG
+ PUSHFQ X64
+ PUSHFW 8086
+ PXOR mmxreg,mmxrm PENT,MMX
+ RCL rm8,unity 8086
+ RCL rm8,reg_cl 8086
+ RCL rm8,imm 186
+ RCL rm16,unity 8086
+ RCL rm16,reg_cl 8086
+ RCL rm16,imm 186
+ RCL rm32,unity 386
+ RCL rm32,reg_cl 386
+ RCL rm32,imm 386
+ RCL rm64,unity X64
+ RCL rm64,reg_cl X64
+ RCL rm64,imm X64
+ RCR rm8,unity 8086
+ RCR rm8,reg_cl 8086
+ RCR rm8,imm 186
+ RCR rm16,unity 8086
+ RCR rm16,reg_cl 8086
+ RCR rm16,imm 186
+ RCR rm32,unity 386
+ RCR rm32,reg_cl 386
+ RCR rm32,imm 386
+ RCR rm64,unity X64
+ RCR rm64,reg_cl X64
+ RCR rm64,imm X64
+ RDSHR rm32 P6,CYRIXM
+ RDMSR PENT,PRIV
+ RDPMC P6
+ RDTSC PENT
+ RDTSCP X86_64
+ RET 8086
+ RET imm 8086,SW
+ RETF 8086
+ RETF imm 8086,SW
+ RETN 8086
+ RETN imm 8086,SW
+ ROL rm8,unity 8086
+ ROL rm8,reg_cl 8086
+ ROL rm8,imm 186
+ ROL rm16,unity 8086
+ ROL rm16,reg_cl 8086
+ ROL rm16,imm 186
+ ROL rm32,unity 386
+ ROL rm32,reg_cl 386
+ ROL rm32,imm 386
+ ROL rm64,unity X64
+ ROL rm64,reg_cl X64
+ ROL rm64,imm X64
+ ROR rm8,unity 8086
+ ROR rm8,reg_cl 8086
+ ROR rm8,imm 186
+ ROR rm16,unity 8086
+ ROR rm16,reg_cl 8086
+ ROR rm16,imm 186
+ ROR rm32,unity 386
+ ROR rm32,reg_cl 386
+ ROR rm32,imm 386
+ ROR rm64,unity X64
+ ROR rm64,reg_cl X64
+ ROR rm64,imm X64
+ RDM P6,CYRIX,ND
+ RSDC reg_sreg,mem80 486,CYRIXM
+ RSLDT mem80 486,CYRIXM
+ RSM PENTM
+ RSTS mem80 486,CYRIXM
+ SAHF 8086
+ SAL rm8,unity 8086,ND
+ SAL rm8,reg_cl 8086,ND
+ SAL rm8,imm 186,ND
+ SAL rm16,unity 8086,ND
+ SAL rm16,reg_cl 8086,ND
+ SAL rm16,imm 186,ND
+ SAL rm32,unity 386,ND
+ SAL rm32,reg_cl 386,ND
+ SAL rm32,imm 386,ND
+ SAL rm64,unity X64,ND
+ SAL rm64,reg_cl X64,ND
+ SAL rm64,imm X64,ND
+ SALC 8086,UNDOC
+ SAR rm8,unity 8086
+ SAR rm8,reg_cl 8086
+ SAR rm8,imm 186
+ SAR rm16,unity 8086
+ SAR rm16,reg_cl 8086
+ SAR rm16,imm 186
+ SAR rm32,unity 386
+ SAR rm32,reg_cl 386
+ SAR rm32,imm 386
+ SAR rm64,unity X64
+ SAR rm64,reg_cl X64
+ SAR rm64,imm X64
+ SBB mem,reg8 8086
+ SBB reg8,reg8 8086
+ SBB mem,reg16 8086
+ SBB reg16,reg16 8086
+ SBB mem,reg32 386
+ SBB reg32,reg32 386
+ SBB mem,reg64 X64
+ SBB reg64,reg64 X64
+ SBB reg8,mem 8086
+ SBB reg8,reg8 8086
+ SBB reg16,mem 8086
+ SBB reg16,reg16 8086
+ SBB reg32,mem 386
+ SBB reg32,reg32 386
+ SBB reg64,mem X64
+ SBB reg64,reg64 X64
+ SBB rm16,imm8 8086
+ SBB rm32,imm8 386
+ SBB rm64,imm8 X64
+ SBB reg_al,imm 8086
+ SBB reg_ax,sbyte16 8086
+ SBB reg_ax,imm 8086
+ SBB reg_eax,sbyte32 386
+ SBB reg_eax,imm 386
+ SBB reg_rax,sbyte64 X64
+ SBB reg_rax,imm X64
+ SBB rm8,imm 8086
+ SBB rm16,imm 8086
+ SBB rm32,imm 386
+ SBB rm64,imm X64
+ SBB mem,imm8 8086
+ SBB mem,imm16 8086
+ SBB mem,imm32 386
+ SCASB 8086
+ SCASD 386
+ SCASQ X64
+ SCASW 8086
+ SFENCE X64,AMD
+ SGDT mem 286
+ SHL rm8,unity 8086
+ SHL rm8,reg_cl 8086
+ SHL rm8,imm 186
+ SHL rm16,unity 8086
+ SHL rm16,reg_cl 8086
+ SHL rm16,imm 186
+ SHL rm32,unity 386
+ SHL rm32,reg_cl 386
+ SHL rm32,imm 386
+ SHL rm64,unity X64
+ SHL rm64,reg_cl X64
+ SHL rm64,imm X64
+ SHLD mem,reg16,imm 3862
+ SHLD reg16,reg16,imm 3862
+ SHLD mem,reg32,imm 3862
+ SHLD reg32,reg32,imm 3862
+ SHLD mem,reg64,imm X642
+ SHLD reg64,reg64,imm X642
+ SHLD mem,reg16,reg_cl 386
+ SHLD reg16,reg16,reg_cl 386
+ SHLD mem,reg32,reg_cl 386
+ SHLD reg32,reg32,reg_cl 386
+ SHLD mem,reg64,reg_cl X64
+ SHLD reg64,reg64,reg_cl X64
+ SHR rm8,unity 8086
+ SHR rm8,reg_cl 8086
+ SHR rm8,imm 186
+ SHR rm16,unity 8086
+ SHR rm16,reg_cl 8086
+ SHR rm16,imm 186
+ SHR rm32,unity 386
+ SHR rm32,reg_cl 386
+ SHR rm32,imm 386
+ SHR rm64,unity X64
+ SHR rm64,reg_cl X64
+ SHR rm64,imm X64
+ SHRD mem,reg16,imm 3862
+ SHRD reg16,reg16,imm 3862
+ SHRD mem,reg32,imm 3862
+ SHRD reg32,reg32,imm 3862
+ SHRD mem,reg64,imm X642
+ SHRD reg64,reg64,imm X642
+ SHRD mem,reg16,reg_cl 386
+ SHRD reg16,reg16,reg_cl 386
+ SHRD mem,reg32,reg_cl 386
+ SHRD reg32,reg32,reg_cl 386
+ SHRD mem,reg64,reg_cl X64
+ SHRD reg64,reg64,reg_cl X64
+ SIDT mem 286
+ SLDT mem 286
+ SLDT mem16 286
+ SLDT reg16 286
+ SLDT reg32 386
+ SLDT reg64 X64,ND
+ SLDT reg64 X64
+ SKINIT X64
+ SMI 386,UNDOC
+ SMINT P6,CYRIX,ND
+ SMINTOLD 486,CYRIX,ND
+ SMSW mem 286
+ SMSW mem16 286
+ SMSW reg16 286
+ SMSW reg32 386
+ STC 8086
+ STD 8086
+ STGI X64
+ STI 8086
+ STOSB 8086
+ STOSD 386
+ STOSQ X64
+ STOSW 8086
+ STR mem 286,PROT
+ STR mem16 286,PROT
+ STR reg16 286,PROT
+ STR reg32 386,PROT
+ STR reg64 X64
+ SUB mem,reg8 8086
+ SUB reg8,reg8 8086
+ SUB mem,reg16 8086
+ SUB reg16,reg16 8086
+ SUB mem,reg32 386
+ SUB reg32,reg32 386
+ SUB mem,reg64 X64
+ SUB reg64,reg64 X64
+ SUB reg8,mem 8086
+ SUB reg8,reg8 8086
+ SUB reg16,mem 8086
+ SUB reg16,reg16 8086
+ SUB reg32,mem 386
+ SUB reg32,reg32 386
+ SUB reg64,mem X64
+ SUB reg64,reg64 X64
+ SUB rm16,imm8 8086
+ SUB rm32,imm8 386
+ SUB rm64,imm8 X64
+ SUB reg_al,imm 8086
+ SUB reg_ax,sbyte16 8086
+ SUB reg_ax,imm 8086
+ SUB reg_eax,sbyte32 386
+ SUB reg_eax,imm 386
+ SUB reg_rax,sbyte64 X64
+ SUB reg_rax,imm X64
+ SUB rm8,imm 8086
+ SUB rm16,imm 8086
+ SUB rm32,imm 386
+ SUB rm64,imm X64
+ SUB mem,imm8 8086
+ SUB mem,imm16 8086
+ SUB mem,imm32 386
+ SVDC mem80,reg_sreg 486,CYRIXM
+ SVLDT mem80 486,CYRIXM,ND
+ SVTS mem80 486,CYRIXM
+ SWAPGS X64
+ SYSCALL P6,AMD
+ SYSENTER P6
+ SYSEXIT P6,PRIV
+ SYSRET P6,PRIV,AMD
+ TEST mem,reg8 8086
+ TEST reg8,reg8 8086
+ TEST mem,reg16 8086
+ TEST reg16,reg16 8086
+ TEST mem,reg32 386
+ TEST reg32,reg32 386
+ TEST mem,reg64 X64
+ TEST reg64,reg64 X64
+ TEST reg8,mem 8086
+ TEST reg16,mem 8086
+ TEST reg32,mem 386
+ TEST reg64,mem X64
+ TEST reg_al,imm 8086
+ TEST reg_ax,imm 8086
+ TEST reg_eax,imm 386
+ TEST reg_rax,imm X64
+ TEST rm8,imm 8086
+ TEST rm16,imm 8086
+ TEST rm32,imm 386
+ TEST rm64,imm X64
+ TEST mem,imm8 8086
+ TEST mem,imm16 8086
+ TEST mem,imm32 386
+ UD0 186,UNDOC
+ UD1 186,UNDOC
+ UD2B 186,UNDOC,ND
+ UD2 186
+ UD2A 186,ND
+ UMOV mem,reg8 386,UNDOC,ND
+ UMOV reg8,reg8 386,UNDOC,ND
+ UMOV mem,reg16 386,UNDOC,ND
+ UMOV reg16,reg16 386,UNDOC,ND
+ UMOV mem,reg32 386,UNDOC,ND
+ UMOV reg32,reg32 386,UNDOC,ND
+ UMOV reg8,mem 386,UNDOC,ND
+ UMOV reg8,reg8 386,UNDOC,ND
+ UMOV reg16,mem 386,UNDOC,ND
+ UMOV reg16,reg16 386,UNDOC,ND
+ UMOV reg32,mem 386,UNDOC,ND
+ UMOV reg32,reg32 386,UNDOC,ND
+ VERR mem 286,PROT
+ VERR mem16 286,PROT
+ VERR reg16 286,PROT
+ VERW mem 286,PROT
+ VERW mem16 286,PROT
+ VERW reg16 286,PROT
+ FWAIT 8086
+ WBINVD 486,PRIV
+ WRSHR rm32 P6,CYRIXM
+ WRMSR PENT,PRIV
+ XADD mem,reg8 486
+ XADD reg8,reg8 486
+ XADD mem,reg16 486
+ XADD reg16,reg16 486
+ XADD mem,reg32 486
+ XADD reg32,reg32 486
+ XADD mem,reg64 X64
+ XADD reg64,reg64 X64
+ XBTS reg16,mem 386,SW,UNDOC,ND
+ XBTS reg16,reg16 386,UNDOC,ND
+ XBTS reg32,mem 386,SD,UNDOC,ND
+ XBTS reg32,reg32 386,UNDOC,ND
+ XCHG reg_ax,reg16 8086
+ XCHG reg_eax,reg32na 386
+ XCHG reg_rax,reg64 X64
+ XCHG reg16,reg_ax 8086
+ XCHG reg32na,reg_eax 386
+ XCHG reg64,reg_rax X64
+ XCHG reg_eax,reg_eax 386,NOLONG
+ XCHG reg8,mem 8086
+ XCHG reg8,reg8 8086
+ XCHG reg16,mem 8086
+ XCHG reg16,reg16 8086
+ XCHG reg32,mem 386
+ XCHG reg32,reg32 386
+ XCHG reg64,mem X64
+ XCHG reg64,reg64 X64
+ XCHG mem,reg8 8086
+ XCHG reg8,reg8 8086
+ XCHG mem,reg16 8086
+ XCHG reg16,reg16 8086
+ XCHG mem,reg32 386
+ XCHG reg32,reg32 386
+ XCHG mem,reg64 X64
+ XCHG reg64,reg64 X64
+ XLATB 8086
+ XLAT 8086
+ XOR mem,reg8 8086
+ XOR reg8,reg8 8086
+ XOR mem,reg16 8086
+ XOR reg16,reg16 8086
+ XOR mem,reg32 386
+ XOR reg32,reg32 386
+ XOR mem,reg64 X64
+ XOR reg64,reg64 X64
+ XOR reg8,mem 8086
+ XOR reg8,reg8 8086
+ XOR reg16,mem 8086
+ XOR reg16,reg16 8086
+ XOR reg32,mem 386
+ XOR reg32,reg32 386
+ XOR reg64,mem X64
+ XOR reg64,reg64 X64
+ XOR rm16,imm8 8086
+ XOR rm32,imm8 386
+ XOR rm64,imm8 X64
+ XOR reg_al,imm 8086
+ XOR reg_ax,sbyte16 8086
+ XOR reg_ax,imm 8086
+ XOR reg_eax,sbyte32 386
+ XOR reg_eax,imm 386
+ XOR reg_rax,sbyte64 X64
+ XOR reg_rax,imm X64
+ XOR rm8,imm 8086
+ XOR rm16,imm 8086
+ XOR rm32,imm 386
+ XOR rm64,imm X64
+ XOR mem,imm8 8086
+ XOR mem,imm16 8086
+ XOR mem,imm32 386
+ CMOVcc reg16,mem P6
+ CMOVcc reg16,reg16 P6
+ CMOVcc reg32,mem P6
+ CMOVcc reg32,reg32 P6
+ CMOVcc reg64,mem X64
+ CMOVcc reg64,reg64 X64
+ Jcc imm|near 386
+ Jcc imm16|near 386
+ Jcc imm32|near 386
+ Jcc imm|short 8086,ND
+ Jcc imm 8086,ND
+ Jcc imm 386,ND
+ Jcc imm 8086,ND
+ Jcc imm 8086
+ SETcc mem 386
+ SETcc reg8 386
+
+ B.1.3 Katmai Streaming SIMD instructions (SSE -- a.k.a. KNI, XMM, MMX2)
+
+ ADDPS xmmreg,xmmrm KATMAI,SSE
+ ADDSS xmmreg,xmmrm KATMAI,SSE,SD
+ ANDNPS xmmreg,xmmrm KATMAI,SSE
+ ANDPS xmmreg,xmmrm KATMAI,SSE
+ CMPEQPS xmmreg,xmmrm KATMAI,SSE
+ CMPEQSS xmmreg,xmmrm KATMAI,SSE
+ CMPLEPS xmmreg,xmmrm KATMAI,SSE
+ CMPLESS xmmreg,xmmrm KATMAI,SSE
+ CMPLTPS xmmreg,xmmrm KATMAI,SSE
+ CMPLTSS xmmreg,xmmrm KATMAI,SSE
+ CMPNEQPS xmmreg,xmmrm KATMAI,SSE
+ CMPNEQSS xmmreg,xmmrm KATMAI,SSE
+ CMPNLEPS xmmreg,xmmrm KATMAI,SSE
+ CMPNLESS xmmreg,xmmrm KATMAI,SSE
+ CMPNLTPS xmmreg,xmmrm KATMAI,SSE
+ CMPNLTSS xmmreg,xmmrm KATMAI,SSE
+ CMPORDPS xmmreg,xmmrm KATMAI,SSE
+ CMPORDSS xmmreg,xmmrm KATMAI,SSE
+ CMPUNORDPS xmmreg,xmmrm KATMAI,SSE
+ CMPUNORDSS xmmreg,xmmrm KATMAI,SSE
+ CMPPS xmmreg,mem,imm KATMAI,SSE
+ CMPPS xmmreg,xmmreg,imm KATMAI,SSE
+ CMPSS xmmreg,mem,imm KATMAI,SSE
+ CMPSS xmmreg,xmmreg,imm KATMAI,SSE
+ COMISS xmmreg,xmmrm KATMAI,SSE
+ CVTPI2PS xmmreg,mmxrm KATMAI,SSE,MMX
+ CVTPS2PI mmxreg,xmmrm KATMAI,SSE,MMX
+ CVTSI2SS xmmreg,mem KATMAI,SSE,SD,AR1,ND
+ CVTSI2SS xmmreg,rm32 KATMAI,SSE,SD,AR1
+ CVTSI2SS xmmreg,rm64 X64,SSE,AR1
+ CVTSS2SI reg32,xmmreg KATMAI,SSE,SD,AR1
+ CVTSS2SI reg32,mem KATMAI,SSE,SD,AR1
+ CVTSS2SI reg64,xmmreg X64,SSE,SD,AR1
+ CVTSS2SI reg64,mem X64,SSE,SD,AR1
+ CVTTPS2PI mmxreg,xmmrm KATMAI,SSE,MMX
+ CVTTSS2SI reg32,xmmrm KATMAI,SSE,SD,AR1
+ CVTTSS2SI reg64,xmmrm X64,SSE,SD,AR1
+ DIVPS xmmreg,xmmrm KATMAI,SSE
+ DIVSS xmmreg,xmmrm KATMAI,SSE
+ LDMXCSR mem KATMAI,SSE,SD
+ MAXPS xmmreg,xmmrm KATMAI,SSE
+ MAXSS xmmreg,xmmrm KATMAI,SSE
+ MINPS xmmreg,xmmrm KATMAI,SSE
+ MINSS xmmreg,xmmrm KATMAI,SSE
+ MOVAPS xmmreg,mem KATMAI,SSE
+ MOVAPS mem,xmmreg KATMAI,SSE
+ MOVAPS xmmreg,xmmreg KATMAI,SSE
+ MOVAPS xmmreg,xmmreg KATMAI,SSE
+ MOVHPS xmmreg,mem KATMAI,SSE
+ MOVHPS mem,xmmreg KATMAI,SSE
+ MOVLHPS xmmreg,xmmreg KATMAI,SSE
+ MOVLPS xmmreg,mem KATMAI,SSE
+ MOVLPS mem,xmmreg KATMAI,SSE
+ MOVHLPS xmmreg,xmmreg KATMAI,SSE
+ MOVMSKPS reg32,xmmreg KATMAI,SSE
+ MOVMSKPS reg64,xmmreg X64,SSE
+ MOVNTPS mem,xmmreg KATMAI,SSE
+ MOVSS xmmreg,mem KATMAI,SSE
+ MOVSS mem,xmmreg KATMAI,SSE
+ MOVSS xmmreg,xmmreg KATMAI,SSE
+ MOVSS xmmreg,xmmreg KATMAI,SSE
+ MOVUPS xmmreg,mem KATMAI,SSE
+ MOVUPS mem,xmmreg KATMAI,SSE
+ MOVUPS xmmreg,xmmreg KATMAI,SSE
+ MOVUPS xmmreg,xmmreg KATMAI,SSE
+ MULPS xmmreg,xmmrm KATMAI,SSE
+ MULSS xmmreg,xmmrm KATMAI,SSE
+ ORPS xmmreg,xmmrm KATMAI,SSE
+ RCPPS xmmreg,xmmrm KATMAI,SSE
+ RCPSS xmmreg,xmmrm KATMAI,SSE
+ RSQRTPS xmmreg,xmmrm KATMAI,SSE
+ RSQRTSS xmmreg,xmmrm KATMAI,SSE
+ SHUFPS xmmreg,mem,imm KATMAI,SSE
+ SHUFPS xmmreg,xmmreg,imm KATMAI,SSE
+ SQRTPS xmmreg,xmmrm KATMAI,SSE
+ SQRTSS xmmreg,xmmrm KATMAI,SSE
+ STMXCSR mem KATMAI,SSE,SD
+ SUBPS xmmreg,xmmrm KATMAI,SSE
+ SUBSS xmmreg,xmmrm KATMAI,SSE
+ UCOMISS xmmreg,xmmrm KATMAI,SSE
+ UNPCKHPS xmmreg,xmmrm KATMAI,SSE
+ UNPCKLPS xmmreg,xmmrm KATMAI,SSE
+ XORPS xmmreg,xmmrm KATMAI,SSE
+
+ B.1.4 Introduced in Deschutes but necessary for SSE support
+
+ FXRSTOR mem P6,SSE,FPU
+ FXSAVE mem P6,SSE,FPU
+
+ B.1.5 XSAVE group (AVX and extended state)
+
+ XGETBV NEHALEM
+ XSETBV NEHALEM,PRIV
+ XSAVE mem NEHALEM
+ XRSTOR mem NEHALEM
+
+ B.1.6 Generic memory operations
+
+ PREFETCHNTA mem KATMAI
+ PREFETCHT0 mem KATMAI
+ PREFETCHT1 mem KATMAI
+ PREFETCHT2 mem KATMAI
+ SFENCE KATMAI
+
+ B.1.7 New MMX instructions introduced in Katmai
+
+ MASKMOVQ mmxreg,mmxreg KATMAI,MMX
+ MOVNTQ mem,mmxreg KATMAI,MMX
+ PAVGB mmxreg,mmxrm KATMAI,MMX
+ PAVGW mmxreg,mmxrm KATMAI,MMX
+ PEXTRW reg32,mmxreg,imm KATMAI,MMX
+ PINSRW mmxreg,mem,imm KATMAI,MMX
+ PINSRW mmxreg,rm16,imm KATMAI,MMX
+ PINSRW mmxreg,reg32,imm KATMAI,MMX
+ PMAXSW mmxreg,mmxrm KATMAI,MMX
+ PMAXUB mmxreg,mmxrm KATMAI,MMX
+ PMINSW mmxreg,mmxrm KATMAI,MMX
+ PMINUB mmxreg,mmxrm KATMAI,MMX
+ PMOVMSKB reg32,mmxreg KATMAI,MMX
+ PMULHUW mmxreg,mmxrm KATMAI,MMX
+ PSADBW mmxreg,mmxrm KATMAI,MMX
+ PSHUFW mmxreg,mmxrm,imm KATMAI,MMX2
+
+ B.1.8 AMD Enhanced 3DNow! (Athlon) instructions
+
+ PF2IW mmxreg,mmxrm PENT,3DNOW
+ PFNACC mmxreg,mmxrm PENT,3DNOW
+ PFPNACC mmxreg,mmxrm PENT,3DNOW
+ PI2FW mmxreg,mmxrm PENT,3DNOW
+ PSWAPD mmxreg,mmxrm PENT,3DNOW
+
+ B.1.9 Willamette SSE2 Cacheability Instructions
+
+ MASKMOVDQU xmmreg,xmmreg WILLAMETTE,SSE2
+ CLFLUSH mem WILLAMETTE,SSE2
+ MOVNTDQ mem,xmmreg WILLAMETTE,SSE2,SO
+ MOVNTI mem,reg32 WILLAMETTE,SD
+ MOVNTI mem,reg64 X64
+ MOVNTPD mem,xmmreg WILLAMETTE,SSE2,SO
+ LFENCE WILLAMETTE,SSE2
+ MFENCE WILLAMETTE,SSE2
+
+B.1.10 Willamette MMX instructions (SSE2 SIMD Integer Instructions)
+
+ MOVD mem,xmmreg WILLAMETTE,SSE2,SD
+ MOVD xmmreg,mem WILLAMETTE,SSE2,SD
+ MOVD xmmreg,rm32 WILLAMETTE,SSE2
+ MOVD rm32,xmmreg WILLAMETTE,SSE2
+ MOVDQA xmmreg,xmmreg WILLAMETTE,SSE2
+ MOVDQA mem,xmmreg WILLAMETTE,SSE2,SO
+ MOVDQA xmmreg,mem WILLAMETTE,SSE2,SO
+ MOVDQA xmmreg,xmmreg WILLAMETTE,SSE2
+ MOVDQU xmmreg,xmmreg WILLAMETTE,SSE2
+ MOVDQU mem,xmmreg WILLAMETTE,SSE2,SO
+ MOVDQU xmmreg,mem WILLAMETTE,SSE2,SO
+ MOVDQU xmmreg,xmmreg WILLAMETTE,SSE2
+ MOVDQ2Q mmxreg,xmmreg WILLAMETTE,SSE2
+ MOVQ xmmreg,xmmreg WILLAMETTE,SSE2
+ MOVQ xmmreg,xmmreg WILLAMETTE,SSE2
+ MOVQ mem,xmmreg WILLAMETTE,SSE2
+ MOVQ xmmreg,mem WILLAMETTE,SSE2
+ MOVQ xmmreg,rm64 X64,SSE2
+ MOVQ rm64,xmmreg X64,SSE2
+ MOVQ2DQ xmmreg,mmxreg WILLAMETTE,SSE2
+ PACKSSWB xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ PACKSSDW xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ PACKUSWB xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ PADDB xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ PADDW xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ PADDD xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ PADDQ mmxreg,mmxrm WILLAMETTE,MMX
+ PADDQ xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ PADDSB xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ PADDSW xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ PADDUSB xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ PADDUSW xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ PAND xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ PANDN xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ PAVGB xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ PAVGW xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ PCMPEQB xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ PCMPEQW xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ PCMPEQD xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ PCMPGTB xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ PCMPGTW xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ PCMPGTD xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ PEXTRW reg32,xmmreg,imm WILLAMETTE,SSE2
+ PINSRW xmmreg,reg16,imm WILLAMETTE,SSE2
+ PINSRW xmmreg,reg32,imm WILLAMETTE,SSE2,ND
+ PINSRW xmmreg,mem,imm WILLAMETTE,SSE2
+ PINSRW xmmreg,mem16,imm WILLAMETTE,SSE2
+ PMADDWD xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ PMAXSW xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ PMAXUB xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ PMINSW xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ PMINUB xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ PMOVMSKB reg32,xmmreg WILLAMETTE,SSE2
+ PMULHUW xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ PMULHW xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ PMULLW xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ PMULUDQ mmxreg,mmxrm WILLAMETTE,SSE2,SO
+ PMULUDQ xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ POR xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ PSADBW xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ PSHUFD xmmreg,xmmreg,imm WILLAMETTE,SSE2
+ PSHUFD xmmreg,mem,imm WILLAMETTE,SSE22
+ PSHUFHW xmmreg,xmmreg,imm WILLAMETTE,SSE2
+ PSHUFHW xmmreg,mem,imm WILLAMETTE,SSE22
+ PSHUFLW xmmreg,xmmreg,imm WILLAMETTE,SSE2
+ PSHUFLW xmmreg,mem,imm WILLAMETTE,SSE22
+ PSLLDQ xmmreg,imm WILLAMETTE,SSE2,AR1
+ PSLLW xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ PSLLW xmmreg,imm WILLAMETTE,SSE2,AR1
+ PSLLD xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ PSLLD xmmreg,imm WILLAMETTE,SSE2,AR1
+ PSLLQ xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ PSLLQ xmmreg,imm WILLAMETTE,SSE2,AR1
+ PSRAW xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ PSRAW xmmreg,imm WILLAMETTE,SSE2,AR1
+ PSRAD xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ PSRAD xmmreg,imm WILLAMETTE,SSE2,AR1
+ PSRLDQ xmmreg,imm WILLAMETTE,SSE2,AR1
+ PSRLW xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ PSRLW xmmreg,imm WILLAMETTE,SSE2,AR1
+ PSRLD xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ PSRLD xmmreg,imm WILLAMETTE,SSE2,AR1
+ PSRLQ xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ PSRLQ xmmreg,imm WILLAMETTE,SSE2,AR1
+ PSUBB xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ PSUBW xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ PSUBD xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ PSUBQ mmxreg,mmxrm WILLAMETTE,SSE2,SO
+ PSUBQ xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ PSUBSB xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ PSUBSW xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ PSUBUSB xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ PSUBUSW xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ PUNPCKHBW xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ PUNPCKHWD xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ PUNPCKHDQ xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ PUNPCKHQDQ xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ PUNPCKLBW xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ PUNPCKLWD xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ PUNPCKLDQ xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ PUNPCKLQDQ xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ PXOR xmmreg,xmmrm WILLAMETTE,SSE2,SO
+
+B.1.11 Willamette Streaming SIMD instructions (SSE2)
+
+ ADDPD xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ ADDSD xmmreg,xmmrm WILLAMETTE,SSE2
+ ANDNPD xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ ANDPD xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ CMPEQPD xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ CMPEQSD xmmreg,xmmrm WILLAMETTE,SSE2
+ CMPLEPD xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ CMPLESD xmmreg,xmmrm WILLAMETTE,SSE2
+ CMPLTPD xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ CMPLTSD xmmreg,xmmrm WILLAMETTE,SSE2
+ CMPNEQPD xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ CMPNEQSD xmmreg,xmmrm WILLAMETTE,SSE2
+ CMPNLEPD xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ CMPNLESD xmmreg,xmmrm WILLAMETTE,SSE2
+ CMPNLTPD xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ CMPNLTSD xmmreg,xmmrm WILLAMETTE,SSE2
+ CMPORDPD xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ CMPORDSD xmmreg,xmmrm WILLAMETTE,SSE2
+ CMPUNORDPD xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ CMPUNORDSD xmmreg,xmmrm WILLAMETTE,SSE2
+ CMPPD xmmreg,xmmrm,imm WILLAMETTE,SSE22
+ CMPSD xmmreg,xmmrm,imm WILLAMETTE,SSE2
+ COMISD xmmreg,xmmrm WILLAMETTE,SSE2
+ CVTDQ2PD xmmreg,xmmrm WILLAMETTE,SSE2
+ CVTDQ2PS xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ CVTPD2DQ xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ CVTPD2PI mmxreg,xmmrm WILLAMETTE,SSE2,SO
+ CVTPD2PS xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ CVTPI2PD xmmreg,mmxrm WILLAMETTE,SSE2
+ CVTPS2DQ xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ CVTPS2PD xmmreg,xmmrm WILLAMETTE,SSE2
+ CVTSD2SI reg32,xmmreg WILLAMETTE,SSE2,AR1
+ CVTSD2SI reg32,mem WILLAMETTE,SSE2,AR1
+ CVTSD2SI reg64,xmmreg X64,SSE2,AR1
+ CVTSD2SI reg64,mem X64,SSE2,AR1
+ CVTSD2SS xmmreg,xmmrm WILLAMETTE,SSE2
+ CVTSI2SD xmmreg,mem WILLAMETTE,SSE2,SD,AR1,ND
+ CVTSI2SD xmmreg,rm32 WILLAMETTE,SSE2,SD,AR1
+ CVTSI2SD xmmreg,rm64 X64,SSE2,AR1
+ CVTSS2SD xmmreg,xmmrm WILLAMETTE,SSE2,SD
+ CVTTPD2PI mmxreg,xmmrm WILLAMETTE,SSE2,SO
+ CVTTPD2DQ xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ CVTTPS2DQ xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ CVTTSD2SI reg32,xmmreg WILLAMETTE,SSE2,AR1
+ CVTTSD2SI reg32,mem WILLAMETTE,SSE2,AR1
+ CVTTSD2SI reg64,xmmreg X64,SSE2,AR1
+ CVTTSD2SI reg64,mem X64,SSE2,AR1
+ DIVPD xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ DIVSD xmmreg,xmmrm WILLAMETTE,SSE2
+ MAXPD xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ MAXSD xmmreg,xmmrm WILLAMETTE,SSE2
+ MINPD xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ MINSD xmmreg,xmmrm WILLAMETTE,SSE2
+ MOVAPD xmmreg,xmmreg WILLAMETTE,SSE2
+ MOVAPD xmmreg,xmmreg WILLAMETTE,SSE2
+ MOVAPD mem,xmmreg WILLAMETTE,SSE2,SO
+ MOVAPD xmmreg,mem WILLAMETTE,SSE2,SO
+ MOVHPD mem,xmmreg WILLAMETTE,SSE2
+ MOVHPD xmmreg,mem WILLAMETTE,SSE2
+ MOVLPD mem,xmmreg WILLAMETTE,SSE2
+ MOVLPD xmmreg,mem WILLAMETTE,SSE2
+ MOVMSKPD reg32,xmmreg WILLAMETTE,SSE2
+ MOVMSKPD reg64,xmmreg X64,SSE2
+ MOVSD xmmreg,xmmreg WILLAMETTE,SSE2
+ MOVSD xmmreg,xmmreg WILLAMETTE,SSE2
+ MOVSD mem,xmmreg WILLAMETTE,SSE2
+ MOVSD xmmreg,mem WILLAMETTE,SSE2
+ MOVUPD xmmreg,xmmreg WILLAMETTE,SSE2
+ MOVUPD xmmreg,xmmreg WILLAMETTE,SSE2
+ MOVUPD mem,xmmreg WILLAMETTE,SSE2,SO
+ MOVUPD xmmreg,mem WILLAMETTE,SSE2,SO
+ MULPD xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ MULSD xmmreg,xmmrm WILLAMETTE,SSE2
+ ORPD xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ SHUFPD xmmreg,xmmreg,imm WILLAMETTE,SSE2
+ SHUFPD xmmreg,mem,imm WILLAMETTE,SSE2
+ SQRTPD xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ SQRTSD xmmreg,xmmrm WILLAMETTE,SSE2
+ SUBPD xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ SUBSD xmmreg,xmmrm WILLAMETTE,SSE2
+ UCOMISD xmmreg,xmmrm WILLAMETTE,SSE2
+ UNPCKHPD xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ UNPCKLPD xmmreg,xmmrm WILLAMETTE,SSE2,SO
+ XORPD xmmreg,xmmrm WILLAMETTE,SSE2,SO
+
+B.1.12 Prescott New Instructions (SSE3)
+
+ ADDSUBPD xmmreg,xmmrm PRESCOTT,SSE3,SO
+ ADDSUBPS xmmreg,xmmrm PRESCOTT,SSE3,SO
+ HADDPD xmmreg,xmmrm PRESCOTT,SSE3,SO
+ HADDPS xmmreg,xmmrm PRESCOTT,SSE3,SO
+ HSUBPD xmmreg,xmmrm PRESCOTT,SSE3,SO
+ HSUBPS xmmreg,xmmrm PRESCOTT,SSE3,SO
+ LDDQU xmmreg,mem PRESCOTT,SSE3,SO
+ MOVDDUP xmmreg,xmmrm PRESCOTT,SSE3
+ MOVSHDUP xmmreg,xmmrm PRESCOTT,SSE3
+ MOVSLDUP xmmreg,xmmrm PRESCOTT,SSE3
+
+B.1.13 VMX Instructions
+
+ VMCALL VMX
+ VMCLEAR mem VMX
+ VMLAUNCH VMX
+ VMLOAD X64,VMX
+ VMMCALL X64,VMX
+ VMPTRLD mem VMX
+ VMPTRST mem VMX
+ VMREAD rm32,reg32 VMX,NOLONG,SD
+ VMREAD rm64,reg64 X64,VMX
+ VMRESUME VMX
+ VMRUN X64,VMX
+ VMSAVE X64,VMX
+ VMWRITE reg32,rm32 VMX,NOLONG,SD
+ VMWRITE reg64,rm64 X64,VMX
+ VMXOFF VMX
+ VMXON mem VMX
+
+B.1.14 Extended Page Tables VMX instructions
+
+ INVEPT reg32,mem VMX,SO,NOLONG
+ INVEPT reg64,mem VMX,SO,LONG
+ INVVPID reg32,mem VMX,SO,NOLONG
+ INVVPID reg64,mem VMX,SO,LONG
+
+B.1.15 Tejas New Instructions (SSSE3)
+
+ PABSB mmxreg,mmxrm SSSE3,MMX
+ PABSB xmmreg,xmmrm SSSE3
+ PABSW mmxreg,mmxrm SSSE3,MMX
+ PABSW xmmreg,xmmrm SSSE3
+ PABSD mmxreg,mmxrm SSSE3,MMX
+ PABSD xmmreg,xmmrm SSSE3
+ PALIGNR mmxreg,mmxrm,imm SSSE3,MMX
+ PALIGNR xmmreg,xmmrm,imm SSSE3
+ PHADDW mmxreg,mmxrm SSSE3,MMX
+ PHADDW xmmreg,xmmrm SSSE3
+ PHADDD mmxreg,mmxrm SSSE3,MMX
+ PHADDD xmmreg,xmmrm SSSE3
+ PHADDSW mmxreg,mmxrm SSSE3,MMX
+ PHADDSW xmmreg,xmmrm SSSE3
+ PHSUBW mmxreg,mmxrm SSSE3,MMX
+ PHSUBW xmmreg,xmmrm SSSE3
+ PHSUBD mmxreg,mmxrm SSSE3,MMX
+ PHSUBD xmmreg,xmmrm SSSE3
+ PHSUBSW mmxreg,mmxrm SSSE3,MMX
+ PHSUBSW xmmreg,xmmrm SSSE3
+ PMADDUBSW mmxreg,mmxrm SSSE3,MMX
+ PMADDUBSW xmmreg,xmmrm SSSE3
+ PMULHRSW mmxreg,mmxrm SSSE3,MMX
+ PMULHRSW xmmreg,xmmrm SSSE3
+ PSHUFB mmxreg,mmxrm SSSE3,MMX
+ PSHUFB xmmreg,xmmrm SSSE3
+ PSIGNB mmxreg,mmxrm SSSE3,MMX
+ PSIGNB xmmreg,xmmrm SSSE3
+ PSIGNW mmxreg,mmxrm SSSE3,MMX
+ PSIGNW xmmreg,xmmrm SSSE3
+ PSIGND mmxreg,mmxrm SSSE3,MMX
+ PSIGND xmmreg,xmmrm SSSE3
+
+B.1.16 AMD SSE4A
+
+ EXTRQ xmmreg,imm,imm SSE4A,AMD
+ EXTRQ xmmreg,xmmreg SSE4A,AMD
+ INSERTQ xmmreg,xmmreg,imm,imm SSE4A,AMD
+ INSERTQ xmmreg,xmmreg SSE4A,AMD
+ MOVNTSD mem,xmmreg SSE4A,AMD
+ MOVNTSS mem,xmmreg SSE4A,AMD,SD
+
+B.1.17 New instructions in Barcelona
+
+ LZCNT reg16,rm16 P6,AMD
+ LZCNT reg32,rm32 P6,AMD
+ LZCNT reg64,rm64 X64,AMD
+
+B.1.18 Penryn New Instructions (SSE4.1)
+
+ BLENDPD xmmreg,xmmrm,imm SSE41
+ BLENDPS xmmreg,xmmrm,imm SSE41
+ BLENDVPD xmmreg,xmmrm,xmm0 SSE41
+ BLENDVPS xmmreg,xmmrm,xmm0 SSE41
+ DPPD xmmreg,xmmrm,imm SSE41
+ DPPS xmmreg,xmmrm,imm SSE41
+ EXTRACTPS rm32,xmmreg,imm SSE41
+ EXTRACTPS reg64,xmmreg,imm SSE41,X64
+ INSERTPS xmmreg,xmmrm,imm SSE41,SD
+ MOVNTDQA xmmreg,mem SSE41
+ MPSADBW xmmreg,xmmrm,imm SSE41
+ PACKUSDW xmmreg,xmmrm SSE41
+ PBLENDVB xmmreg,xmmrm,xmm0 SSE41
+ PBLENDW xmmreg,xmmrm,imm SSE41
+ PCMPEQQ xmmreg,xmmrm SSE41
+ PEXTRB reg32,xmmreg,imm SSE41
+ PEXTRB mem8,xmmreg,imm SSE41
+ PEXTRB reg64,xmmreg,imm SSE41,X64
+ PEXTRD rm32,xmmreg,imm SSE41
+ PEXTRQ rm64,xmmreg,imm SSE41,X64
+ PEXTRW reg32,xmmreg,imm SSE41
+ PEXTRW mem16,xmmreg,imm SSE41
+ PEXTRW reg64,xmmreg,imm SSE41,X64
+ PHMINPOSUW xmmreg,xmmrm SSE41
+ PINSRB xmmreg,mem,imm SSE41
+ PINSRB xmmreg,rm8,imm SSE41
+ PINSRB xmmreg,reg32,imm SSE41
+ PINSRD xmmreg,mem,imm SSE41
+ PINSRD xmmreg,rm32,imm SSE41
+ PINSRQ xmmreg,mem,imm SSE41,X64
+ PINSRQ xmmreg,rm64,imm SSE41,X64
+ PMAXSB xmmreg,xmmrm SSE41
+ PMAXSD xmmreg,xmmrm SSE41
+ PMAXUD xmmreg,xmmrm SSE41
+ PMAXUW xmmreg,xmmrm SSE41
+ PMINSB xmmreg,xmmrm SSE41
+ PMINSD xmmreg,xmmrm SSE41
+ PMINUD xmmreg,xmmrm SSE41
+ PMINUW xmmreg,xmmrm SSE41
+ PMOVSXBW xmmreg,xmmrm SSE41
+ PMOVSXBD xmmreg,xmmrm SSE41,SD
+ PMOVSXBQ xmmreg,xmmrm SSE41,SW
+ PMOVSXWD xmmreg,xmmrm SSE41
+ PMOVSXWQ xmmreg,xmmrm SSE41,SD
+ PMOVSXDQ xmmreg,xmmrm SSE41
+ PMOVZXBW xmmreg,xmmrm SSE41
+ PMOVZXBD xmmreg,xmmrm SSE41,SD
+ PMOVZXBQ xmmreg,xmmrm SSE41,SW
+ PMOVZXWD xmmreg,xmmrm SSE41
+ PMOVZXWQ xmmreg,xmmrm SSE41,SD
+ PMOVZXDQ xmmreg,xmmrm SSE41
+ PMULDQ xmmreg,xmmrm SSE41
+ PMULLD xmmreg,xmmrm SSE41
+ PTEST xmmreg,xmmrm SSE41
+ ROUNDPD xmmreg,xmmrm,imm SSE41
+ ROUNDPS xmmreg,xmmrm,imm SSE41
+ ROUNDSD xmmreg,xmmrm,imm SSE41
+ ROUNDSS xmmreg,xmmrm,imm SSE41
+
+B.1.19 Nehalem New Instructions (SSE4.2)
+
+ CRC32 reg32,rm8 SSE42
+ CRC32 reg32,rm16 SSE42
+ CRC32 reg32,rm32 SSE42
+ CRC32 reg64,rm8 SSE42,X64
+ CRC32 reg64,rm64 SSE42,X64
+ PCMPESTRI xmmreg,xmmrm,imm SSE42
+ PCMPESTRM xmmreg,xmmrm,imm SSE42
+ PCMPISTRI xmmreg,xmmrm,imm SSE42
+ PCMPISTRM xmmreg,xmmrm,imm SSE42
+ PCMPGTQ xmmreg,xmmrm SSE42
+ POPCNT reg16,rm16 NEHALEM,SW
+ POPCNT reg32,rm32 NEHALEM,SD
+ POPCNT reg64,rm64 NEHALEM,X64
+
+B.1.20 Intel SMX
+
+ GETSEC KATMAI
+
+B.1.21 Geode (Cyrix) 3DNow! additions
+
+ PFRCPV mmxreg,mmxrm PENT,3DNOW,CYRIX
+ PFRSQRTV mmxreg,mmxrm PENT,3DNOW,CYRIX
+
+B.1.22 Intel new instructions in ???
+
+ MOVBE reg16,mem16 NEHALEM
+ MOVBE reg32,mem32 NEHALEM
+ MOVBE reg64,mem64 NEHALEM
+ MOVBE mem16,reg16 NEHALEM
+ MOVBE mem32,reg32 NEHALEM
+ MOVBE mem64,reg64 NEHALEM
+
+B.1.23 Intel AES instructions
+
+ AESENC xmmreg,xmmrm128 SSE,WESTMERE
+ AESENCLAST xmmreg,xmmrm128 SSE,WESTMERE
+ AESDEC xmmreg,xmmrm128 SSE,WESTMERE
+ AESDECLAST xmmreg,xmmrm128 SSE,WESTMERE
+ AESIMC xmmreg,xmmrm128 SSE,WESTMERE
+ AESKEYGENASSIST xmmreg,xmmrm128,imm8 SSE,WESTMERE
+
+B.1.24 Intel AVX AES instructions
+
+ VAESENC xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VAESENCLAST xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VAESDEC xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VAESDECLAST xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VAESIMC xmmreg,xmmrm128 AVX,SANDYBRIDGE
+ VAESKEYGENASSIST xmmreg,xmmrm128,imm8 AVX,SANDYBRIDGE
+
+B.1.25 Intel AVX instructions
+
+ VADDPD xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VADDPD ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VADDPS xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VADDPS ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VADDSD xmmreg,xmmreg*,xmmrm64 AVX,SANDYBRIDGE
+ VADDSS xmmreg,xmmreg*,xmmrm32 AVX,SANDYBRIDGE
+ VADDSUBPD xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VADDSUBPD ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VADDSUBPS xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VADDSUBPS ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VANDPD xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VANDPD ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VANDPS xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VANDPS ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VANDNPD xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VANDNPD ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VANDNPS xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VANDNPS ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VBLENDPD xmmreg,xmmreg*,xmmrm128,imm8 AVX,SANDYBRIDGE
+ VBLENDPD ymmreg,ymmreg*,ymmrm256,imm8 AVX,SANDYBRIDGE
+ VBLENDPS xmmreg,xmmreg*,xmmrm128,imm8 AVX,SANDYBRIDGE
+ VBLENDPS ymmreg,ymmreg*,ymmrm256,imm8 AVX,SANDYBRIDGE
+ VBLENDVPD xmmreg,xmmreg,xmmrm128,xmmreg AVX,SANDYBRIDGE
+ VBLENDVPD xmmreg,xmmrm128,xmm0 AVX,SANDYBRIDGE
+ VBLENDVPD ymmreg,ymmreg,ymmrm256,ymmreg AVX,SANDYBRIDGE
+ VBLENDVPD ymmreg,ymmrm256,ymm0 AVX,SANDYBRIDGE
+ VBLENDVPS xmmreg,xmmreg,xmmrm128,xmmreg AVX,SANDYBRIDGE
+ VBLENDVPS xmmreg,xmmrm128,xmm0 AVX,SANDYBRIDGE
+ VBLENDVPS ymmreg,ymmreg,ymmrm256,ymmreg AVX,SANDYBRIDGE
+ VBLENDVPD ymmreg,ymmrm256,ymm0 AVX,SANDYBRIDGE
+ VBROADCASTSS xmmreg,mem32 AVX,SANDYBRIDGE
+ VBROADCASTSS ymmreg,mem32 AVX,SANDYBRIDGE
+ VBROADCASTSD ymmreg,mem64 AVX,SANDYBRIDGE
+ VBROADCASTF128 ymmreg,mem128 AVX,SANDYBRIDGE
+ VCMPEQPD xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VCMPEQPD ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VCMPLTPD xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VCMPLTPD ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VCMPLEPD xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VCMPLEPD ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VCMPUNORDPD xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VCMPUNORDPD ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VCMPNEQPD xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VCMPNEQPD ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VCMPNLTPD xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VCMPNLTPD ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VCMPNLEPD xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VCMPNLEPD ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VCMPORDPD xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VCMPORDPD ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VCMPEQ_UQPD xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VCMPEQ_UQPD ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VCMPNGEPD xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VCMPNGEPD ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VCMPNGTPD xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VCMPNGTPD ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VCMPFALSEPD xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VCMPFALSEPD ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VCMPNEQ_OQPD xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VCMPNEQ_OQPD ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VCMPGEPD xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VCMPGEPD ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VCMPGTPD xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VCMPGTPD ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VCMPTRUEPD xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VCMPTRUEPD ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VCMPEQ_OSPD xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VCMPEQ_OSPD ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VCMPLT_OQPD xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VCMPLT_OQPD ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VCMPLE_OQPD xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VCMPLE_OQPD ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VCMPUNORD_SPD xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VCMPUNORD_SPD ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VCMPNEQ_USPD xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VCMPNEQ_USPD ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VCMPNLT_UQPD xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VCMPNLT_UQPD ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VCMPNLE_UQPD xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VCMPNLE_UQPD ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VCMPORD_SPD xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VCMPORD_SPD ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VCMPEQ_USPD xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VCMPEQ_USPD ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VCMPNGE_UQPD xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VCMPNGE_UQPD ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VCMPNGT_UQPD xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VCMPNGT_UQPD ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VCMPFALSE_OSPD xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VCMPFALSE_OSPD ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VCMPNEQ_OSPD xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VCMPNEQ_OSPD ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VCMPGE_OQPD xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VCMPGE_OQPD ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VCMPGT_OQPD xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VCMPGT_OQPD ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VCMPTRUE_USPD xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VCMPTRUE_USPD ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VCMPPD xmmreg,xmmreg*,xmmrm128,imm8 AVX,SANDYBRIDGE
+ VCMPPD ymmreg,ymmreg*,ymmrm256,imm8 AVX,SANDYBRIDGE
+ VCMPEQPS xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VCMPEQPS ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VCMPLTPS xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VCMPLTPS ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VCMPLEPS xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VCMPLEPS ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VCMPUNORDPS xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VCMPUNORDPS ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VCMPNEQPS xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VCMPNEQPS ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VCMPNLTPS xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VCMPNLTPS ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VCMPNLEPS xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VCMPNLEPS ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VCMPORDPS xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VCMPORDPS ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VCMPEQ_UQPS xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VCMPEQ_UQPS ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VCMPNGEPS xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VCMPNGEPS ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VCMPNGTPS xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VCMPNGTPS ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VCMPFALSEPS xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VCMPFALSEPS ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VCMPNEQ_OQPS xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VCMPNEQ_OQPS ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VCMPGEPS xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VCMPGEPS ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VCMPGTPS xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VCMPGTPS ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VCMPTRUEPS xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VCMPTRUEPS ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VCMPEQ_OSPS xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VCMPEQ_OSPS ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VCMPLT_OQPS xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VCMPLT_OQPS ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VCMPLE_OQPS xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VCMPLE_OQPS ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VCMPUNORD_SPS xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VCMPUNORD_SPS ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VCMPNEQ_USPS xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VCMPNEQ_USPS ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VCMPNLT_UQPS xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VCMPNLT_UQPS ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VCMPNLE_UQPS xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VCMPNLE_UQPS ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VCMPORD_SPS xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VCMPORD_SPS ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VCMPEQ_USPS xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VCMPEQ_USPS ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VCMPNGE_UQPS xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VCMPNGE_UQPS ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VCMPNGT_UQPS xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VCMPNGT_UQPS ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VCMPFALSE_OSPS xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VCMPFALSE_OSPS ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VCMPNEQ_OSPS xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VCMPNEQ_OSPS ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VCMPGE_OQPS xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VCMPGE_OQPS ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VCMPGT_OQPS xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VCMPGT_OQPS ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VCMPTRUE_USPS xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VCMPTRUE_USPS ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VCMPPS xmmreg,xmmreg*,xmmrm128,imm8 AVX,SANDYBRIDGE
+ VCMPPS ymmreg,ymmreg*,ymmrm256,imm8 AVX,SANDYBRIDGE
+ VCMPEQSD xmmreg,xmmreg*,xmmrm64 AVX,SANDYBRIDGE
+ VCMPLTSD xmmreg,xmmreg*,xmmrm64 AVX,SANDYBRIDGE
+ VCMPLESD xmmreg,xmmreg*,xmmrm64 AVX,SANDYBRIDGE
+ VCMPUNORDSD xmmreg,xmmreg*,xmmrm64 AVX,SANDYBRIDGE
+ VCMPNEQSD xmmreg,xmmreg*,xmmrm64 AVX,SANDYBRIDGE
+ VCMPNLTSD xmmreg,xmmreg*,xmmrm64 AVX,SANDYBRIDGE
+ VCMPNLESD xmmreg,xmmreg*,xmmrm64 AVX,SANDYBRIDGE
+ VCMPORDSD xmmreg,xmmreg*,xmmrm64 AVX,SANDYBRIDGE
+ VCMPEQ_UQSD xmmreg,xmmreg*,xmmrm64 AVX,SANDYBRIDGE
+ VCMPNGESD xmmreg,xmmreg*,xmmrm64 AVX,SANDYBRIDGE
+ VCMPNGTSD xmmreg,xmmreg*,xmmrm64 AVX,SANDYBRIDGE
+ VCMPFALSESD xmmreg,xmmreg*,xmmrm64 AVX,SANDYBRIDGE
+ VCMPNEQ_OQSD xmmreg,xmmreg*,xmmrm64 AVX,SANDYBRIDGE
+ VCMPGESD xmmreg,xmmreg*,xmmrm64 AVX,SANDYBRIDGE
+ VCMPGTSD xmmreg,xmmreg*,xmmrm64 AVX,SANDYBRIDGE
+ VCMPTRUESD xmmreg,xmmreg*,xmmrm64 AVX,SANDYBRIDGE
+ VCMPEQ_OSSD xmmreg,xmmreg*,xmmrm64 AVX,SANDYBRIDGE
+ VCMPLT_OQSD xmmreg,xmmreg*,xmmrm64 AVX,SANDYBRIDGE
+ VCMPLE_OQSD xmmreg,xmmreg*,xmmrm64 AVX,SANDYBRIDGE
+ VCMPUNORD_SSD xmmreg,xmmreg*,xmmrm64 AVX,SANDYBRIDGE
+ VCMPNEQ_USSD xmmreg,xmmreg*,xmmrm64 AVX,SANDYBRIDGE
+ VCMPNLT_UQSD xmmreg,xmmreg*,xmmrm64 AVX,SANDYBRIDGE
+ VCMPNLE_UQSD xmmreg,xmmreg*,xmmrm64 AVX,SANDYBRIDGE
+ VCMPORD_SSD xmmreg,xmmreg*,xmmrm64 AVX,SANDYBRIDGE
+ VCMPEQ_USSD xmmreg,xmmreg*,xmmrm64 AVX,SANDYBRIDGE
+ VCMPNGE_UQSD xmmreg,xmmreg*,xmmrm64 AVX,SANDYBRIDGE
+ VCMPNGT_UQSD xmmreg,xmmreg*,xmmrm64 AVX,SANDYBRIDGE
+ VCMPFALSE_OSSD xmmreg,xmmreg*,xmmrm64 AVX,SANDYBRIDGE
+ VCMPNEQ_OSSD xmmreg,xmmreg*,xmmrm64 AVX,SANDYBRIDGE
+ VCMPGE_OQSD xmmreg,xmmreg*,xmmrm64 AVX,SANDYBRIDGE
+ VCMPGT_OQSD xmmreg,xmmreg*,xmmrm64 AVX,SANDYBRIDGE
+ VCMPTRUE_USSD xmmreg,xmmreg*,xmmrm64 AVX,SANDYBRIDGE
+ VCMPSD xmmreg,xmmreg*,xmmrm64,imm8 AVX,SANDYBRIDGE
+ VCMPEQSS xmmreg,xmmreg*,xmmrm32 AVX,SANDYBRIDGE
+ VCMPLTSS xmmreg,xmmreg*,xmmrm32 AVX,SANDYBRIDGE
+ VCMPLESS xmmreg,xmmreg*,xmmrm32 AVX,SANDYBRIDGE
+ VCMPUNORDSS xmmreg,xmmreg*,xmmrm32 AVX,SANDYBRIDGE
+ VCMPNEQSS xmmreg,xmmreg*,xmmrm32 AVX,SANDYBRIDGE
+ VCMPNLTSS xmmreg,xmmreg*,xmmrm32 AVX,SANDYBRIDGE
+ VCMPNLESS xmmreg,xmmreg*,xmmrm32 AVX,SANDYBRIDGE
+ VCMPORDSS xmmreg,xmmreg*,xmmrm32 AVX,SANDYBRIDGE
+ VCMPEQ_UQSS xmmreg,xmmreg*,xmmrm32 AVX,SANDYBRIDGE
+ VCMPNGESS xmmreg,xmmreg*,xmmrm32 AVX,SANDYBRIDGE
+ VCMPNGTSS xmmreg,xmmreg*,xmmrm32 AVX,SANDYBRIDGE
+ VCMPFALSESS xmmreg,xmmreg*,xmmrm32 AVX,SANDYBRIDGE
+ VCMPNEQ_OQSS xmmreg,xmmreg*,xmmrm32 AVX,SANDYBRIDGE
+ VCMPGESS xmmreg,xmmreg*,xmmrm32 AVX,SANDYBRIDGE
+ VCMPGTSS xmmreg,xmmreg*,xmmrm32 AVX,SANDYBRIDGE
+ VCMPTRUESS xmmreg,xmmreg*,xmmrm32 AVX,SANDYBRIDGE
+ VCMPEQ_OSSS xmmreg,xmmreg*,xmmrm32 AVX,SANDYBRIDGE
+ VCMPLT_OQSS xmmreg,xmmreg*,xmmrm32 AVX,SANDYBRIDGE
+ VCMPLE_OQSS xmmreg,xmmreg*,xmmrm32 AVX,SANDYBRIDGE
+ VCMPUNORD_SSS xmmreg,xmmreg*,xmmrm32 AVX,SANDYBRIDGE
+ VCMPNEQ_USSS xmmreg,xmmreg*,xmmrm32 AVX,SANDYBRIDGE
+ VCMPNLT_UQSS xmmreg,xmmreg*,xmmrm32 AVX,SANDYBRIDGE
+ VCMPNLE_UQSS xmmreg,xmmreg*,xmmrm32 AVX,SANDYBRIDGE
+ VCMPORD_SSS xmmreg,xmmreg*,xmmrm32 AVX,SANDYBRIDGE
+ VCMPEQ_USSS xmmreg,xmmreg*,xmmrm32 AVX,SANDYBRIDGE
+ VCMPNGE_UQSS xmmreg,xmmreg*,xmmrm32 AVX,SANDYBRIDGE
+ VCMPNGT_UQSS xmmreg,xmmreg*,xmmrm32 AVX,SANDYBRIDGE
+ VCMPFALSE_OSSS xmmreg,xmmreg*,xmmrm32 AVX,SANDYBRIDGE
+ VCMPNEQ_OSSS xmmreg,xmmreg*,xmmrm32 AVX,SANDYBRIDGE
+ VCMPGE_OQSS xmmreg,xmmreg*,xmmrm32 AVX,SANDYBRIDGE
+ VCMPGT_OQSS xmmreg,xmmreg*,xmmrm32 AVX,SANDYBRIDGE
+ VCMPTRUE_USSS xmmreg,xmmreg*,xmmrm32 AVX,SANDYBRIDGE
+ VCMPSS xmmreg,xmmreg*,xmmrm32,imm8 AVX,SANDYBRIDGE
+ VCOMISD xmmreg,xmmrm64 AVX,SANDYBRIDGE
+ VCOMISS xmmreg,xmmrm32 AVX,SANDYBRIDGE
+ VCVTDQ2PD xmmreg,xmmrm64 AVX,SANDYBRIDGE
+ VCVTDQ2PD ymmreg,xmmrm128 AVX,SANDYBRIDGE
+ VCVTDQ2PS xmmreg,xmmrm128 AVX,SANDYBRIDGE
+ VCVTDQ2PS ymmreg,ymmrm256 AVX,SANDYBRIDGE
+ VCVTPD2DQ xmmreg,xmmreg AVX,SANDYBRIDGE
+ VCVTPD2DQ xmmreg,mem128 AVX,SANDYBRIDGE,SO
+ VCVTPD2DQ xmmreg,ymmreg AVX,SANDYBRIDGE
+ VCVTPD2DQ xmmreg,mem256 AVX,SANDYBRIDGE,SY
+ VCVTPD2PS xmmreg,xmmreg AVX,SANDYBRIDGE
+ VCVTPD2PS xmmreg,mem128 AVX,SANDYBRIDGE,SO
+ VCVTPD2PS xmmreg,ymmreg AVX,SANDYBRIDGE
+ VCVTPD2PS xmmreg,mem256 AVX,SANDYBRIDGE,SY
+ VCVTPS2DQ xmmreg,xmmrm128 AVX,SANDYBRIDGE
+ VCVTPS2DQ ymmreg,ymmrm256 AVX,SANDYBRIDGE
+ VCVTPS2PD xmmreg,xmmrm64 AVX,SANDYBRIDGE
+ VCVTPS2PD ymmreg,xmmrm128 AVX,SANDYBRIDGE
+ VCVTSD2SI reg32,xmmrm64 AVX,SANDYBRIDGE
+ VCVTSD2SI reg64,xmmrm64 AVX,SANDYBRIDGE,LONG
+ VCVTSD2SS xmmreg,xmmreg*,xmmrm64 AVX,SANDYBRIDGE
+ VCVTSI2SD xmmreg,xmmreg*,rm32 AVX,SANDYBRIDGE,SD
+ VCVTSI2SD xmmreg,xmmreg*,mem32 AVX,SANDYBRIDGE,ND,SD
+ VCVTSI2SD xmmreg,xmmreg*,rm64 AVX,SANDYBRIDGE,LONG
+ VCVTSI2SS xmmreg,xmmreg*,rm32 AVX,SANDYBRIDGE,SD
+ VCVTSI2SS xmmreg,xmmreg*,mem32 AVX,SANDYBRIDGE,ND,SD
+ VCVTSI2SS xmmreg,xmmreg*,rm64 AVX,SANDYBRIDGE,LONG
+ VCVTSS2SD xmmreg,xmmreg*,xmmrm32 AVX,SANDYBRIDGE
+ VCVTSS2SI reg32,xmmrm32 AVX,SANDYBRIDGE
+ VCVTSS2SI reg64,xmmrm32 AVX,SANDYBRIDGE,LONG
+ VCVTTPD2DQ xmmreg,xmmreg AVX,SANDYBRIDGE
+ VCVTTPD2DQ xmmreg,mem128 AVX,SANDYBRIDGE,SO
+ VCVTTPD2DQ xmmreg,ymmreg AVX,SANDYBRIDGE
+ VCVTTPD2DQ xmmreg,mem256 AVX,SANDYBRIDGE,SY
+ VCVTTPS2DQ xmmreg,xmmrm128 AVX,SANDYBRIDGE
+ VCVTTPS2DQ ymmreg,ymmrm256 AVX,SANDYBRIDGE
+ VCVTTSD2SI reg32,xmmrm64 AVX,SANDYBRIDGE
+ VCVTTSD2SI reg64,xmmrm64 AVX,SANDYBRIDGE,LONG
+ VCVTTSS2SI reg32,xmmrm32 AVX,SANDYBRIDGE
+ VCVTTSS2SI reg64,xmmrm32 AVX,SANDYBRIDGE,LONG
+ VDIVPD xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VDIVPD ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VDIVPS xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VDIVPS ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VDIVSD xmmreg,xmmreg*,xmmrm64 AVX,SANDYBRIDGE
+ VDIVSS xmmreg,xmmreg*,xmmrm32 AVX,SANDYBRIDGE
+ VDPPD xmmreg,xmmreg*,xmmrm128,imm8 AVX,SANDYBRIDGE
+ VDPPS xmmreg,xmmreg*,xmmrm128,imm8 AVX,SANDYBRIDGE
+ VDPPS ymmreg,ymmreg*,ymmrm256,imm8 AVX,SANDYBRIDGE
+ VEXTRACTF128 xmmrm128,xmmreg,imm8 AVX,SANDYBRIDGE
+ VEXTRACTPS rm32,xmmreg,imm8 AVX,SANDYBRIDGE
+ VHADDPD xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VHADDPD ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VHADDPS xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VHADDPS ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VHSUBPD xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VHSUBPD ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VHSUBPS xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VHSUBPS ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VINSERTF128 ymmreg,ymmreg,xmmrm128,imm8 AVX,SANDYBRIDGE
+ VINSERTPS xmmreg,xmmreg*,xmmrm32,imm8 AVX,SANDYBRIDGE
+ VLDDQU xmmreg,mem128 AVX,SANDYBRIDGE
+ VLDQQU ymmreg,mem256 AVX,SANDYBRIDGE
+ VLDDQU ymmreg,mem256 AVX,SANDYBRIDGE
+ VLDMXCSR mem32 AVX,SANDYBRIDGE
+ VMASKMOVDQU xmmreg,xmmreg AVX,SANDYBRIDGE
+ VMASKMOVPS xmmreg,xmmreg,mem128 AVX,SANDYBRIDGE
+ VMASKMOVPS ymmreg,ymmreg,mem256 AVX,SANDYBRIDGE
+ VMASKMOVPS mem128,xmmreg,xmmreg AVX,SANDYBRIDGE,SO
+ VMASKMOVPS mem256,xmmreg,xmmreg AVX,SANDYBRIDGE,SY
+ VMASKMOVPD xmmreg,xmmreg,mem128 AVX,SANDYBRIDGE
+ VMASKMOVPD ymmreg,ymmreg,mem256 AVX,SANDYBRIDGE
+ VMASKMOVPD mem128,xmmreg,xmmreg AVX,SANDYBRIDGE
+ VMASKMOVPD mem256,ymmreg,ymmreg AVX,SANDYBRIDGE
+ VMAXPD xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VMAXPD ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VMAXPS xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VMAXPS ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VMAXSD xmmreg,xmmreg*,xmmrm64 AVX,SANDYBRIDGE
+ VMAXSS xmmreg,xmmreg*,xmmrm32 AVX,SANDYBRIDGE
+ VMINPD xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VMINPD ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VMINPS xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VMINPS ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VMINSD xmmreg,xmmreg*,xmmrm64 AVX,SANDYBRIDGE
+ VMINSS xmmreg,xmmreg*,xmmrm32 AVX,SANDYBRIDGE
+ VMOVAPD xmmreg,xmmrm128 AVX,SANDYBRIDGE
+ VMOVAPD xmmrm128,xmmreg AVX,SANDYBRIDGE
+ VMOVAPD ymmreg,ymmrm256 AVX,SANDYBRIDGE
+ VMOVAPD ymmrm256,ymmreg AVX,SANDYBRIDGE
+ VMOVAPS xmmreg,xmmrm128 AVX,SANDYBRIDGE
+ VMOVAPS xmmrm128,xmmreg AVX,SANDYBRIDGE
+ VMOVAPS ymmreg,ymmrm256 AVX,SANDYBRIDGE
+ VMOVAPS ymmrm256,ymmreg AVX,SANDYBRIDGE
+ VMOVQ xmmreg,xmmrm64 AVX,SANDYBRIDGE
+ VMOVQ xmmrm64,xmmreg AVX,SANDYBRIDGE
+ VMOVQ xmmreg,rm64 AVX,SANDYBRIDGE,LONG
+ VMOVQ rm64,xmmreg AVX,SANDYBRIDGE,LONG
+ VMOVD xmmreg,rm32 AVX,SANDYBRIDGE
+ VMOVD rm32,xmmreg AVX,SANDYBRIDGE
+ VMOVDDUP xmmreg,xmmrm64 AVX,SANDYBRIDGE
+ VMOVDDUP ymmreg,ymmrm256 AVX,SANDYBRIDGE
+ VMOVDQA xmmreg,xmmrm128 AVX,SANDYBRIDGE
+ VMOVDQA xmmrm128,xmmreg AVX,SANDYBRIDGE
+ VMOVQQA ymmreg,ymmrm256 AVX,SANDYBRIDGE
+ VMOVQQA ymmrm256,ymmreg AVX,SANDYBRIDGE
+ VMOVDQA ymmreg,ymmrm AVX,SANDYBRIDGE
+ VMOVDQA ymmrm256,ymmreg AVX,SANDYBRIDGE
+ VMOVDQU xmmreg,xmmrm128 AVX,SANDYBRIDGE
+ VMOVDQU xmmrm128,xmmreg AVX,SANDYBRIDGE
+ VMOVQQU ymmreg,ymmrm256 AVX,SANDYBRIDGE
+ VMOVQQU ymmrm256,ymmreg AVX,SANDYBRIDGE
+ VMOVDQU ymmreg,ymmrm256 AVX,SANDYBRIDGE
+ VMOVDQU ymmrm256,ymmreg AVX,SANDYBRIDGE
+ VMOVHLPS xmmreg,xmmreg*,xmmreg AVX,SANDYBRIDGE
+ VMOVHPD xmmreg,xmmreg*,mem64 AVX,SANDYBRIDGE
+ VMOVHPD mem64,xmmreg AVX,SANDYBRIDGE
+ VMOVHPS xmmreg,xmmreg*,mem64 AVX,SANDYBRIDGE
+ VMOVHPS mem64,xmmreg AVX,SANDYBRIDGE
+ VMOVLHPS xmmreg,xmmreg*,xmmreg AVX,SANDYBRIDGE
+ VMOVLPD xmmreg,xmmreg*,mem64 AVX,SANDYBRIDGE
+ VMOVLPD mem64,xmmreg AVX,SANDYBRIDGE
+ VMOVLPS xmmreg,xmmreg*,mem64 AVX,SANDYBRIDGE
+ VMOVLPS mem64,xmmreg AVX,SANDYBRIDGE
+ VMOVMSKPD reg64,xmmreg AVX,SANDYBRIDGE,LONG
+ VMOVMSKPD reg32,xmmreg AVX,SANDYBRIDGE
+ VMOVMSKPD reg64,ymmreg AVX,SANDYBRIDGE,LONG
+ VMOVMSKPD reg32,ymmreg AVX,SANDYBRIDGE
+ VMOVMSKPS reg64,xmmreg AVX,SANDYBRIDGE,LONG
+ VMOVMSKPS reg32,xmmreg AVX,SANDYBRIDGE
+ VMOVMSKPS reg64,ymmreg AVX,SANDYBRIDGE,LONG
+ VMOVMSKPS reg32,ymmreg AVX,SANDYBRIDGE
+ VMOVNTDQ mem128,xmmreg AVX,SANDYBRIDGE
+ VMOVNTQQ mem256,ymmreg AVX,SANDYBRIDGE
+ VMOVNTDQ mem256,ymmreg AVX,SANDYBRIDGE
+ VMOVNTDQA xmmreg,mem128 AVX,SANDYBRIDGE
+ VMOVNTPD mem128,xmmreg AVX,SANDYBRIDGE
+ VMOVNTPD mem256,ymmreg AVX,SANDYBRIDGE
+ VMOVNTPS mem128,xmmreg AVX,SANDYBRIDGE
+ VMOVNTPS mem128,ymmreg AVX,SANDYBRIDGE
+ VMOVSD xmmreg,xmmreg*,xmmreg AVX,SANDYBRIDGE
+ VMOVSD xmmreg,mem64 AVX,SANDYBRIDGE
+ VMOVSD xmmreg,xmmreg*,xmmreg AVX,SANDYBRIDGE
+ VMOVSD mem64,xmmreg AVX,SANDYBRIDGE
+ VMOVSHDUP xmmreg,xmmrm128 AVX,SANDYBRIDGE
+ VMOVSHDUP ymmreg,ymmrm256 AVX,SANDYBRIDGE
+ VMOVSLDUP xmmreg,xmmrm128 AVX,SANDYBRIDGE
+ VMOVSLDUP ymmreg,ymmrm256 AVX,SANDYBRIDGE
+ VMOVSS xmmreg,xmmreg*,xmmreg AVX,SANDYBRIDGE
+ VMOVSS xmmreg,mem64 AVX,SANDYBRIDGE
+ VMOVSS xmmreg,xmmreg*,xmmreg AVX,SANDYBRIDGE
+ VMOVSS mem64,xmmreg AVX,SANDYBRIDGE
+ VMOVUPD xmmreg,xmmrm128 AVX,SANDYBRIDGE
+ VMOVUPD xmmrm128,xmmreg AVX,SANDYBRIDGE
+ VMOVUPD ymmreg,ymmrm256 AVX,SANDYBRIDGE
+ VMOVUPD ymmrm256,ymmreg AVX,SANDYBRIDGE
+ VMOVUPS xmmreg,xmmrm128 AVX,SANDYBRIDGE
+ VMOVUPS xmmrm128,xmmreg AVX,SANDYBRIDGE
+ VMOVUPS ymmreg,ymmrm256 AVX,SANDYBRIDGE
+ VMOVUPS ymmrm256,ymmreg AVX,SANDYBRIDGE
+ VMPSADBW xmmreg,xmmreg*,xmmrm128,imm8 AVX,SANDYBRIDGE
+ VMULPD xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VMULPD ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VMULPS xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VMULPS ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VMULSD xmmreg,xmmreg*,xmmrm64 AVX,SANDYBRIDGE
+ VMULSS xmmreg,xmmreg*,xmmrm32 AVX,SANDYBRIDGE
+ VORPD xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VORPD ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VORPS xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VORPS ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VPABSB xmmreg,xmmrm128 AVX,SANDYBRIDGE
+ VPABSW xmmreg,xmmrm128 AVX,SANDYBRIDGE
+ VPABSD xmmreg,xmmrm128 AVX,SANDYBRIDGE
+ VPACKSSWB xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPACKSSDW xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPACKUSWB xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPACKUSDW xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPADDB xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPADDW xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPADDD xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPADDQ xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPADDSB xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPADDSW xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPADDUSB xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPADDUSW xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPALIGNR xmmreg,xmmreg*,xmmrm128,imm8 AVX,SANDYBRIDGE
+ VPAND xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPANDN xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPAVGB xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPAVGW xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPBLENDVB xmmreg,xmmreg*,xmmrm128,xmmreg AVX,SANDYBRIDGE
+ VPBLENDW xmmreg,xmmreg*,xmmrm128,imm8 AVX,SANDYBRIDGE
+ VPCMPESTRI xmmreg,xmmrm128,imm8 AVX,SANDYBRIDGE
+ VPCMPESTRM xmmreg,xmmrm128,imm8 AVX,SANDYBRIDGE
+ VPCMPISTRI xmmreg,xmmrm128,imm8 AVX,SANDYBRIDGE
+ VPCMPISTRM xmmreg,xmmrm128,imm8 AVX,SANDYBRIDGE
+ VPCMPEQB xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPCMPEQW xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPCMPEQD xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPCMPEQQ xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPCMPGTB xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPCMPGTW xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPCMPGTD xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPCMPGTQ xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPERMILPD xmmreg,xmmreg,xmmrm128 AVX,SANDYBRIDGE
+ VPERMILPD ymmreg,ymmreg,ymmrm256 AVX,SANDYBRIDGE
+ VPERMILPD xmmreg,xmmrm128,imm8 AVX,SANDYBRIDGE
+ VPERMILPD ymmreg,ymmrm256,imm8 AVX,SANDYBRIDGE
+ VPERMILTD2PD xmmreg,xmmreg,xmmrm128,xmmreg AVX,SANDYBRIDGE
+ VPERMILTD2PD xmmreg,xmmreg,xmmreg,xmmrm128 AVX,SANDYBRIDGE
+ VPERMILTD2PD ymmreg,ymmreg,ymmrm256,ymmreg AVX,SANDYBRIDGE
+ VPERMILTD2PD ymmreg,ymmreg,ymmreg,ymmrm256 AVX,SANDYBRIDGE
+ VPERMILMO2PD xmmreg,xmmreg,xmmrm128,xmmreg AVX,SANDYBRIDGE
+ VPERMILMO2PD xmmreg,xmmreg,xmmreg,xmmrm128 AVX,SANDYBRIDGE
+ VPERMILMO2PD ymmreg,ymmreg,ymmrm256,ymmreg AVX,SANDYBRIDGE
+ VPERMILMO2PD ymmreg,ymmreg,ymmreg,ymmrm256 AVX,SANDYBRIDGE
+ VPERMILMZ2PD xmmreg,xmmreg,xmmrm128,xmmreg AVX,SANDYBRIDGE
+ VPERMILMZ2PD xmmreg,xmmreg,xmmreg,xmmrm128 AVX,SANDYBRIDGE
+ VPERMILMZ2PD ymmreg,ymmreg,ymmrm256,ymmreg AVX,SANDYBRIDGE
+ VPERMILMZ2PD ymmreg,ymmreg,ymmreg,ymmrm256 AVX,SANDYBRIDGE
+ VPERMIL2PD xmmreg,xmmreg,xmmrm128,xmmreg,imm8 AVX,SANDYBRIDGE
+ VPERMIL2PD xmmreg,xmmreg,xmmreg,xmmrm128,imm8 AVX,SANDYBRIDGE
+ VPERMIL2PD ymmreg,ymmreg,ymmrm256,ymmreg,imm8 AVX,SANDYBRIDGE
+ VPERMIL2PD ymmreg,ymmreg,ymmreg,ymmrm256,imm8 AVX,SANDYBRIDGE
+ VPERMILPS xmmreg,xmmreg,xmmrm128 AVX,SANDYBRIDGE
+ VPERMILPS ymmreg,ymmreg,ymmrm256 AVX,SANDYBRIDGE
+ VPERMILPS xmmreg,xmmrm128,imm8 AVX,SANDYBRIDGE
+ VPERMILPS ymmreg,ymmrm256,imm8 AVX,SANDYBRIDGE
+ VPERMILTD2PS xmmreg,xmmreg,xmmrm128,xmmreg AVX,SANDYBRIDGE
+ VPERMILTD2PS xmmreg,xmmreg,xmmreg,xmmrm128 AVX,SANDYBRIDGE
+ VPERMILTD2PS ymmreg,ymmreg,ymmrm256,ymmreg AVX,SANDYBRIDGE
+ VPERMILTD2PS ymmreg,ymmreg,ymmreg,ymmrm256 AVX,SANDYBRIDGE
+ VPERMILMO2PS xmmreg,xmmreg,xmmrm128,xmmreg AVX,SANDYBRIDGE
+ VPERMILMO2PS xmmreg,xmmreg,xmmreg,xmmrm128 AVX,SANDYBRIDGE
+ VPERMILMO2PS ymmreg,ymmreg,ymmrm256,ymmreg AVX,SANDYBRIDGE
+ VPERMILMO2PS ymmreg,ymmreg,ymmreg,ymmrm256 AVX,SANDYBRIDGE
+ VPERMILMZ2PS xmmreg,xmmreg,xmmrm128,xmmreg AVX,SANDYBRIDGE
+ VPERMILMZ2PS xmmreg,xmmreg,xmmreg,xmmrm128 AVX,SANDYBRIDGE
+ VPERMILMZ2PS ymmreg,ymmreg,ymmrm256,ymmreg AVX,SANDYBRIDGE
+ VPERMILMZ2PS ymmreg,ymmreg,ymmreg,ymmrm256 AVX,SANDYBRIDGE
+ VPERMIL2PS xmmreg,xmmreg,xmmrm128,xmmreg,imm8 AVX,SANDYBRIDGE
+ VPERMIL2PS xmmreg,xmmreg,xmmreg,xmmrm128,imm8 AVX,SANDYBRIDGE
+ VPERMIL2PS ymmreg,ymmreg,ymmrm256,ymmreg,imm8 AVX,SANDYBRIDGE
+ VPERMIL2PS ymmreg,ymmreg,ymmreg,ymmrm256,imm8 AVX,SANDYBRIDGE
+ VPERM2F128 ymmreg,ymmreg,ymmrm256,imm8 AVX,SANDYBRIDGE
+ VPEXTRB reg64,xmmreg,imm8 AVX,SANDYBRIDGE,LONG
+ VPEXTRB reg32,xmmreg,imm8 AVX,SANDYBRIDGE
+ VPEXTRB mem8,xmmreg,imm8 AVX,SANDYBRIDGE
+ VPEXTRW reg64,xmmreg,imm8 AVX,SANDYBRIDGE,LONG
+ VPEXTRW reg32,xmmreg,imm8 AVX,SANDYBRIDGE
+ VPEXTRW mem16,xmmreg,imm8 AVX,SANDYBRIDGE
+ VPEXTRW reg64,xmmreg,imm8 AVX,SANDYBRIDGE,LONG
+ VPEXTRW reg32,xmmreg,imm8 AVX,SANDYBRIDGE
+ VPEXTRW mem16,xmmreg,imm8 AVX,SANDYBRIDGE
+ VPEXTRD reg64,xmmreg,imm8 AVX,SANDYBRIDGE,LONG
+ VPEXTRD rm32,xmmreg,imm8 AVX,SANDYBRIDGE
+ VPEXTRQ rm64,xmmreg,imm8 AVX,SANDYBRIDGE,LONG
+ VPHADDW xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPHADDD xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPHADDSW xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPHMINPOSUW xmmreg,xmmrm128 AVX,SANDYBRIDGE
+ VPHSUBW xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPHSUBD xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPHSUBSW xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPINSRB xmmreg,xmmreg*,mem8,imm8 AVX,SANDYBRIDGE
+ VPINSRB xmmreg,xmmreg*,rm8,imm8 AVX,SANDYBRIDGE
+ VPINSRB xmmreg,xmmreg*,reg32,imm8 AVX,SANDYBRIDGE
+ VPINSRW xmmreg,xmmreg*,mem16,imm8 AVX,SANDYBRIDGE
+ VPINSRW xmmreg,xmmreg*,rm16,imm8 AVX,SANDYBRIDGE
+ VPINSRW xmmreg,xmmreg*,reg32,imm8 AVX,SANDYBRIDGE
+ VPINSRD xmmreg,xmmreg*,mem32,imm8 AVX,SANDYBRIDGE
+ VPINSRD xmmreg,xmmreg*,rm32,imm8 AVX,SANDYBRIDGE
+ VPINSRQ xmmreg,xmmreg*,mem64,imm8 AVX,SANDYBRIDGE,LONG
+ VPINSRQ xmmreg,xmmreg*,rm64,imm8 AVX,SANDYBRIDGE,LONG
+ VPMADDWD xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPMADDUBSW xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPMAXSB xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPMAXSW xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPMAXSD xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPMAXUB xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPMAXUW xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPMAXUD xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPMINSB xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPMINSW xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPMINSD xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPMINUB xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPMINUW xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPMINUD xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPMOVMSKB reg64,xmmreg AVX,SANDYBRIDGE,LONG
+ VPMOVMSKB reg32,xmmreg AVX,SANDYBRIDGE
+ VPMOVSXBW xmmreg,xmmrm64 AVX,SANDYBRIDGE
+ VPMOVSXBD xmmreg,xmmrm32 AVX,SANDYBRIDGE
+ VPMOVSXBQ xmmreg,xmmrm16 AVX,SANDYBRIDGE
+ VPMOVSXWD xmmreg,xmmrm64 AVX,SANDYBRIDGE
+ VPMOVSXWQ xmmreg,xmmrm32 AVX,SANDYBRIDGE
+ VPMOVSXDQ xmmreg,xmmrm64 AVX,SANDYBRIDGE
+ VPMOVZXBW xmmreg,xmmrm64 AVX,SANDYBRIDGE
+ VPMOVZXBD xmmreg,xmmrm32 AVX,SANDYBRIDGE
+ VPMOVZXBQ xmmreg,xmmrm16 AVX,SANDYBRIDGE
+ VPMOVZXWD xmmreg,xmmrm64 AVX,SANDYBRIDGE
+ VPMOVZXWQ xmmreg,xmmrm32 AVX,SANDYBRIDGE
+ VPMOVZXDQ xmmreg,xmmrm64 AVX,SANDYBRIDGE
+ VPMULHUW xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPMULHRSW xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPMULHW xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPMULLW xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPMULLD xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPMULUDQ xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPMULDQ xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPOR xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPSADBW xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPSHUFB xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPSHUFD xmmreg,xmmrm128,imm8 AVX,SANDYBRIDGE
+ VPSHUFHW xmmreg,xmmrm128,imm8 AVX,SANDYBRIDGE
+ VPSHUFLW xmmreg,xmmrm128,imm8 AVX,SANDYBRIDGE
+ VPSIGNB xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPSIGNW xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPSIGND xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPSLLDQ xmmreg,xmmreg*,imm8 AVX,SANDYBRIDGE
+ VPSRLDQ xmmreg,xmmreg*,imm8 AVX,SANDYBRIDGE
+ VPSLLW xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPSLLW xmmreg,xmmreg*,imm8 AVX,SANDYBRIDGE
+ VPSLLD xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPSLLD xmmreg,xmmreg*,imm8 AVX,SANDYBRIDGE
+ VPSLLQ xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPSLLQ xmmreg,xmmreg*,imm8 AVX,SANDYBRIDGE
+ VPSRAW xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPSRAW xmmreg,xmmreg*,imm8 AVX,SANDYBRIDGE
+ VPSRAD xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPSRAD xmmreg,xmmreg*,imm8 AVX,SANDYBRIDGE
+ VPSRLW xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPSRLW xmmreg,xmmreg*,imm8 AVX,SANDYBRIDGE
+ VPSRLD xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPSRLD xmmreg,xmmreg*,imm8 AVX,SANDYBRIDGE
+ VPSRLQ xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPSRLQ xmmreg,xmmreg*,imm8 AVX,SANDYBRIDGE
+ VPTEST xmmreg,xmmrm128 AVX,SANDYBRIDGE
+ VPTEST ymmreg,ymmrm256 AVX,SANDYBRIDGE
+ VPSUBB xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPSUBW xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPSUBD xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPSUBQ xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPSUBSB xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPSUBSW xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPSUBUSB xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPSUBUSW xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPUNPCKHBW xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPUNPCKHWD xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPUNPCKHDQ xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPUNPCKHQDQ xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPUNPCKLBW xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPUNPCKLWD xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPUNPCKLDQ xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPUNPCKLQDQ xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPXOR xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VRCPPS xmmreg,xmmrm128 AVX,SANDYBRIDGE
+ VRCPPS ymmreg,ymmrm256 AVX,SANDYBRIDGE
+ VRCPSS xmmreg,xmmreg*,xmmrm32 AVX,SANDYBRIDGE
+ VRSQRTPS xmmreg,xmmrm128 AVX,SANDYBRIDGE
+ VRSQRTPS ymmreg,ymmrm256 AVX,SANDYBRIDGE
+ VRSQRTSS xmmreg,xmmreg*,xmmrm32 AVX,SANDYBRIDGE
+ VROUNDPD xmmreg,xmmrm128,imm8 AVX,SANDYBRIDGE
+ VROUNDPD ymmreg,ymmrm256,imm8 AVX,SANDYBRIDGE
+ VROUNDPS xmmreg,xmmrm128,imm8 AVX,SANDYBRIDGE
+ VROUNDPS ymmreg,ymmrm256,imm8 AVX,SANDYBRIDGE
+ VROUNDSD xmmreg,xmmreg*,xmmrm64,imm8 AVX,SANDYBRIDGE
+ VROUNDSS xmmreg,xmmreg*,xmmrm32,imm8 AVX,SANDYBRIDGE
+ VSHUFPD xmmreg,xmmreg*,xmmrm128,imm8 AVX,SANDYBRIDGE
+ VSHUFPD ymmreg,ymmreg*,ymmrm256,imm8 AVX,SANDYBRIDGE
+ VSHUFPS xmmreg,xmmreg*,xmmrm128,imm8 AVX,SANDYBRIDGE
+ VSHUFPS ymmreg,ymmreg*,ymmrm256,imm8 AVX,SANDYBRIDGE
+ VSQRTPD xmmreg,xmmrm128 AVX,SANDYBRIDGE
+ VSQRTPD ymmreg,ymmrm256 AVX,SANDYBRIDGE
+ VSQRTPS xmmreg,xmmrm128 AVX,SANDYBRIDGE
+ VSQRTPS ymmreg,ymmrm256 AVX,SANDYBRIDGE
+ VSQRTSD xmmreg,xmmreg*,xmmrm64 AVX,SANDYBRIDGE
+ VSQRTSS xmmreg,xmmreg*,xmmrm32 AVX,SANDYBRIDGE
+ VSTMXCSR mem32 AVX,SANDYBRIDGE
+ VSUBPD xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VSUBPD ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VSUBPS xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VSUBPS ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VSUBSD xmmreg,xmmreg*,xmmrm64 AVX,SANDYBRIDGE
+ VSUBSS xmmreg,xmmreg*,xmmrm32 AVX,SANDYBRIDGE
+ VTESTPS xmmreg,xmmrm128 AVX,SANDYBRIDGE
+ VTESTPS ymmreg,ymmrm256 AVX,SANDYBRIDGE
+ VTESTPD xmmreg,xmmrm128 AVX,SANDYBRIDGE
+ VTESTPD ymmreg,ymmrm256 AVX,SANDYBRIDGE
+ VUCOMISD xmmreg,xmmrm64 AVX,SANDYBRIDGE
+ VUCOMISS xmmreg,xmmrm32 AVX,SANDYBRIDGE
+ VUNPCKHPD xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VUNPCKHPD ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VUNPCKHPS xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VUNPCKHPS ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VUNPCKLPD xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VUNPCKLPD ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VUNPCKLPS xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VUNPCKLPS ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VXORPD xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VXORPD ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VXORPS xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VXORPS ymmreg,ymmreg*,ymmrm256 AVX,SANDYBRIDGE
+ VZEROALL AVX,SANDYBRIDGE
+ VZEROUPPER AVX,SANDYBRIDGE
+
+B.1.26 Intel Carry-Less Multiplication instructions (CLMUL)
+
+ PCLMULLQLQDQ xmmreg,xmmrm128 SSE,WESTMERE
+ PCLMULHQLQDQ xmmreg,xmmrm128 SSE,WESTMERE
+ PCLMULLQHQDQ xmmreg,xmmrm128 SSE,WESTMERE
+ PCLMULHQHQDQ xmmreg,xmmrm128 SSE,WESTMERE
+ PCLMULQDQ xmmreg,xmmrm128,imm8 SSE,WESTMERE
+
+B.1.27 Intel AVX Carry-Less Multiplication instructions (CLMUL)
+
+ VPCLMULLQLQDQ xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPCLMULHQLQDQ xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPCLMULLQHQDQ xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPCLMULHQHQDQ xmmreg,xmmreg*,xmmrm128 AVX,SANDYBRIDGE
+ VPCLMULQDQ xmmreg,xmmreg*,xmmrm128,imm8 AVX,SANDYBRIDGE
+
+B.1.28 Intel Fused Multiply-Add instructions (FMA)
+
+ VFMADD132PS xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFMADD132PS ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFMADD132PD xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFMADD132PD ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFMADD312PS xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFMADD312PS ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFMADD312PD xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFMADD312PD ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFMADD213PS xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFMADD213PS ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFMADD213PD xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFMADD213PD ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFMADD123PS xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFMADD123PS ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFMADD123PD xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFMADD123PD ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFMADD231PS xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFMADD231PS ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFMADD231PD xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFMADD231PD ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFMADD321PS xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFMADD321PS ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFMADD321PD xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFMADD321PD ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFMADDSUB132PS xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFMADDSUB132PS ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFMADDSUB132PD xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFMADDSUB132PD ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFMADDSUB312PS xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFMADDSUB312PS ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFMADDSUB312PD xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFMADDSUB312PD ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFMADDSUB213PS xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFMADDSUB213PS ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFMADDSUB213PD xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFMADDSUB213PD ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFMADDSUB123PS xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFMADDSUB123PS ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFMADDSUB123PD xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFMADDSUB123PD ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFMADDSUB231PS xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFMADDSUB231PS ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFMADDSUB231PD xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFMADDSUB231PD ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFMADDSUB321PS xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFMADDSUB321PS ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFMADDSUB321PD xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFMADDSUB321PD ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFMSUB132PS xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFMSUB132PS ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFMSUB132PD xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFMSUB132PD ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFMSUB312PS xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFMSUB312PS ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFMSUB312PD xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFMSUB312PD ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFMSUB213PS xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFMSUB213PS ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFMSUB213PD xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFMSUB213PD ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFMSUB123PS xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFMSUB123PS ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFMSUB123PD xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFMSUB123PD ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFMSUB231PS xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFMSUB231PS ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFMSUB231PD xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFMSUB231PD ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFMSUB321PS xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFMSUB321PS ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFMSUB321PD xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFMSUB321PD ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFMSUBADD132PS xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFMSUBADD132PS ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFMSUBADD132PD xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFMSUBADD132PD ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFMSUBADD312PS xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFMSUBADD312PS ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFMSUBADD312PD xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFMSUBADD312PD ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFMSUBADD213PS xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFMSUBADD213PS ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFMSUBADD213PD xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFMSUBADD213PD ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFMSUBADD123PS xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFMSUBADD123PS ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFMSUBADD123PD xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFMSUBADD123PD ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFMSUBADD231PS xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFMSUBADD231PS ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFMSUBADD231PD xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFMSUBADD231PD ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFMSUBADD321PS xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFMSUBADD321PS ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFMSUBADD321PD xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFMSUBADD321PD ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFNMADD132PS xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFNMADD132PS ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFNMADD132PD xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFNMADD132PD ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFNMADD312PS xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFNMADD312PS ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFNMADD312PD xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFNMADD312PD ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFNMADD213PS xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFNMADD213PS ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFNMADD213PD xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFNMADD213PD ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFNMADD123PS xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFNMADD123PS ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFNMADD123PD xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFNMADD123PD ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFNMADD231PS xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFNMADD231PS ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFNMADD231PD xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFNMADD231PD ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFNMADD321PS xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFNMADD321PS ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFNMADD321PD xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFNMADD321PD ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFNMSUB132PS xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFNMSUB132PS ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFNMSUB132PD xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFNMSUB132PD ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFNMSUB312PS xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFNMSUB312PS ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFNMSUB312PD xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFNMSUB312PD ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFNMSUB213PS xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFNMSUB213PS ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFNMSUB213PD xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFNMSUB213PD ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFNMSUB123PS xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFNMSUB123PS ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFNMSUB123PD xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFNMSUB123PD ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFNMSUB231PS xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFNMSUB231PS ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFNMSUB231PD xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFNMSUB231PD ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFNMSUB321PS xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFNMSUB321PS ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFNMSUB321PD xmmreg,xmmreg,xmmrm128 FMA,FUTURE
+ VFNMSUB321PD ymmreg,ymmreg,ymmrm256 FMA,FUTURE
+ VFMADD132SS xmmreg,xmmreg,xmmrm32 FMA,FUTURE
+ VFMADD132SD xmmreg,xmmreg,xmmrm64 FMA,FUTURE
+ VFMADD312SS xmmreg,xmmreg,xmmrm32 FMA,FUTURE
+ VFMADD312SD xmmreg,xmmreg,xmmrm64 FMA,FUTURE
+ VFMADD213SS xmmreg,xmmreg,xmmrm32 FMA,FUTURE
+ VFMADD213SD xmmreg,xmmreg,xmmrm64 FMA,FUTURE
+ VFMADD123SS xmmreg,xmmreg,xmmrm32 FMA,FUTURE
+ VFMADD123SD xmmreg,xmmreg,xmmrm64 FMA,FUTURE
+ VFMADD231SS xmmreg,xmmreg,xmmrm32 FMA,FUTURE
+ VFMADD231SD xmmreg,xmmreg,xmmrm64 FMA,FUTURE
+ VFMADD321SS xmmreg,xmmreg,xmmrm32 FMA,FUTURE
+ VFMADD321SD xmmreg,xmmreg,xmmrm64 FMA,FUTURE
+ VFMSUB132SS xmmreg,xmmreg,xmmrm32 FMA,FUTURE
+ VFMSUB132SD xmmreg,xmmreg,xmmrm64 FMA,FUTURE
+ VFMSUB312SS xmmreg,xmmreg,xmmrm32 FMA,FUTURE
+ VFMSUB312SD xmmreg,xmmreg,xmmrm64 FMA,FUTURE
+ VFMSUB213SS xmmreg,xmmreg,xmmrm32 FMA,FUTURE
+ VFMSUB213SD xmmreg,xmmreg,xmmrm64 FMA,FUTURE
+ VFMSUB123SS xmmreg,xmmreg,xmmrm32 FMA,FUTURE
+ VFMSUB123SD xmmreg,xmmreg,xmmrm64 FMA,FUTURE
+ VFMSUB231SS xmmreg,xmmreg,xmmrm32 FMA,FUTURE
+ VFMSUB231SD xmmreg,xmmreg,xmmrm64 FMA,FUTURE
+ VFMSUB321SS xmmreg,xmmreg,xmmrm32 FMA,FUTURE
+ VFMSUB321SD xmmreg,xmmreg,xmmrm64 FMA,FUTURE
+ VFNMADD132SS xmmreg,xmmreg,xmmrm32 FMA,FUTURE
+ VFNMADD132SD xmmreg,xmmreg,xmmrm64 FMA,FUTURE
+ VFNMADD312SS xmmreg,xmmreg,xmmrm32 FMA,FUTURE
+ VFNMADD312SD xmmreg,xmmreg,xmmrm64 FMA,FUTURE
+ VFNMADD213SS xmmreg,xmmreg,xmmrm32 FMA,FUTURE
+ VFNMADD213SD xmmreg,xmmreg,xmmrm64 FMA,FUTURE
+ VFNMADD123SS xmmreg,xmmreg,xmmrm32 FMA,FUTURE
+ VFNMADD123SD xmmreg,xmmreg,xmmrm64 FMA,FUTURE
+ VFNMADD231SS xmmreg,xmmreg,xmmrm32 FMA,FUTURE
+ VFNMADD231SD xmmreg,xmmreg,xmmrm64 FMA,FUTURE
+ VFNMADD321SS xmmreg,xmmreg,xmmrm32 FMA,FUTURE
+ VFNMADD321SD xmmreg,xmmreg,xmmrm64 FMA,FUTURE
+ VFNMSUB132SS xmmreg,xmmreg,xmmrm32 FMA,FUTURE
+ VFNMSUB132SD xmmreg,xmmreg,xmmrm64 FMA,FUTURE
+ VFNMSUB312SS xmmreg,xmmreg,xmmrm32 FMA,FUTURE
+ VFNMSUB312SD xmmreg,xmmreg,xmmrm64 FMA,FUTURE
+ VFNMSUB213SS xmmreg,xmmreg,xmmrm32 FMA,FUTURE
+ VFNMSUB213SD xmmreg,xmmreg,xmmrm64 FMA,FUTURE
+ VFNMSUB123SS xmmreg,xmmreg,xmmrm32 FMA,FUTURE
+ VFNMSUB123SD xmmreg,xmmreg,xmmrm64 FMA,FUTURE
+ VFNMSUB231SS xmmreg,xmmreg,xmmrm32 FMA,FUTURE
+ VFNMSUB231SD xmmreg,xmmreg,xmmrm64 FMA,FUTURE
+ VFNMSUB321SS xmmreg,xmmreg,xmmrm32 FMA,FUTURE
+ VFNMSUB321SD xmmreg,xmmreg,xmmrm64 FMA,FUTURE
+
+B.1.29 VIA (Centaur) security instructions
+
+ XSTORE PENT,CYRIX
+ XCRYPTECB PENT,CYRIX
+ XCRYPTCBC PENT,CYRIX
+ XCRYPTCTR PENT,CYRIX
+ XCRYPTCFB PENT,CYRIX
+ XCRYPTOFB PENT,CYRIX
+ MONTMUL PENT,CYRIX
+ XSHA1 PENT,CYRIX
+ XSHA256 PENT,CYRIX
+
+B.1.30 AMD Lightweight Profiling (LWP) instructions
+
+ LLWPCB reg16 AMD
+ LLWPCB reg32 AMD,386
+ LLWPCB reg64 AMD,X64
+ SLWPCB reg16 AMD
+ SLWPCB reg32 AMD,386
+ SLWPCB reg64 AMD,X64
+ LWPVAL reg16,rm32,imm16 AMD,386
+ LWPVAL reg32,rm32,imm32 AMD,386
+ LWPVAL reg64,rm32,imm32 AMD,X64
+ LWPINS reg16,rm32,imm16 AMD,386
+ LWPINS reg32,rm32,imm32 AMD,386
+ LWPINS reg64,rm32,imm32 AMD,X64
+
+B.1.31 AMD XOP, FMA4 and CVT16 instructions (SSE5)
+
+ VCVTPH2PS xmmreg,xmmrm64*,imm8 AMD,SSE5
+ VCVTPH2PS ymmreg,xmmrm128,imm8 AMD,SSE5
+ VCVTPH2PS ymmreg,ymmrm128*,imm8 AMD,SSE5
+ VCVTPS2PH xmmrm64,xmmreg*,imm8 AMD,SSE5
+ VCVTPS2PH xmmrm128,ymmreg,imm8 AMD,SSE5
+ VCVTPS2PH ymmrm128,ymmreg*,imm8 AMD,SSE5
+ VFMADDPD xmmreg,xmmreg*,xmmrm128,xmmreg AMD,SSE5
+ VFMADDPD ymmreg,ymmreg*,ymmrm256,ymmreg AMD,SSE5
+ VFMADDPD xmmreg,xmmreg*,xmmreg,xmmrm128 AMD,SSE5
+ VFMADDPD ymmreg,ymmreg*,ymmreg,ymmrm256 AMD,SSE5
+ VFMADDPS xmmreg,xmmreg*,xmmrm128,xmmreg AMD,SSE5
+ VFMADDPS ymmreg,ymmreg*,ymmrm256,ymmreg AMD,SSE5
+ VFMADDPS xmmreg,xmmreg*,xmmreg,xmmrm128 AMD,SSE5
+ VFMADDPS ymmreg,ymmreg*,ymmreg,ymmrm256 AMD,SSE5
+ VFMADDSD xmmreg,xmmreg*,xmmrm64,xmmreg AMD,SSE5
+ VFMADDSD xmmreg,xmmreg*,xmmreg,xmmrm64 AMD,SSE5
+ VFMADDSS xmmreg,xmmreg*,xmmrm32,xmmreg AMD,SSE5
+ VFMADDSS xmmreg,xmmreg*,xmmreg,xmmrm32 AMD,SSE5
+ VFMADDSUBPD xmmreg,xmmreg*,xmmrm128,xmmreg AMD,SSE5
+ VFMADDSUBPD ymmreg,ymmreg*,ymmrm256,ymmreg AMD,SSE5
+ VFMADDSUBPD xmmreg,xmmreg*,xmmreg,xmmrm128 AMD,SSE5
+ VFMADDSUBPD ymmreg,ymmreg*,ymmreg,ymmrm256 AMD,SSE5
+ VFMADDSUBPS xmmreg,xmmreg*,xmmrm128,xmmreg AMD,SSE5
+ VFMADDSUBPS ymmreg,ymmreg*,ymmrm256,ymmreg AMD,SSE5
+ VFMADDSUBPS xmmreg,xmmreg*,xmmreg,xmmrm128 AMD,SSE5
+ VFMADDSUBPS ymmreg,ymmreg*,ymmreg,ymmrm256 AMD,SSE5
+ VFMSUBADDPD xmmreg,xmmreg*,xmmrm128,xmmreg AMD,SSE5
+ VFMSUBADDPD ymmreg,ymmreg*,ymmrm256,ymmreg AMD,SSE5
+ VFMSUBADDPD xmmreg,xmmreg*,xmmreg,xmmrm128 AMD,SSE5
+ VFMSUBADDPD ymmreg,ymmreg*,ymmreg,ymmrm256 AMD,SSE5
+ VFMSUBADDPS xmmreg,xmmreg*,xmmrm128,xmmreg AMD,SSE5
+ VFMSUBADDPS ymmreg,ymmreg*,ymmrm256,ymmreg AMD,SSE5
+ VFMSUBADDPS xmmreg,xmmreg*,xmmreg,xmmrm128 AMD,SSE5
+ VFMSUBADDPS ymmreg,ymmreg*,ymmreg,ymmrm256 AMD,SSE5
+ VFMSUBPD xmmreg,xmmreg*,xmmrm128,xmmreg AMD,SSE5
+ VFMSUBPD ymmreg,ymmreg*,ymmrm256,ymmreg AMD,SSE5
+ VFMSUBPD xmmreg,xmmreg*,xmmreg,xmmrm128 AMD,SSE5
+ VFMSUBPD ymmreg,ymmreg*,ymmreg,ymmrm256 AMD,SSE5
+ VFMSUBPS xmmreg,xmmreg*,xmmrm128,xmmreg AMD,SSE5
+ VFMSUBPS ymmreg,ymmreg*,ymmrm256,ymmreg AMD,SSE5
+ VFMSUBPS xmmreg,xmmreg*,xmmreg,xmmrm128 AMD,SSE5
+ VFMSUBPS ymmreg,ymmreg*,ymmreg,ymmrm256 AMD,SSE5
+ VFMSUBSD xmmreg,xmmreg*,xmmrm64,xmmreg AMD,SSE5
+ VFMSUBSD xmmreg,xmmreg*,xmmreg,xmmrm64 AMD,SSE5
+ VFMSUBSS xmmreg,xmmreg*,xmmrm32,xmmreg AMD,SSE5
+ VFMSUBSS xmmreg,xmmreg*,xmmreg,xmmrm32 AMD,SSE5
+ VFNMADDPD xmmreg,xmmreg*,xmmrm128,xmmreg AMD,SSE5
+ VFNMADDPD ymmreg,ymmreg*,ymmrm256,ymmreg AMD,SSE5
+ VFNMADDPD xmmreg,xmmreg*,xmmreg,xmmrm128 AMD,SSE5
+ VFNMADDPD ymmreg,ymmreg*,ymmreg,ymmrm256 AMD,SSE5
+ VFNMADDPS xmmreg,xmmreg*,xmmrm128,xmmreg AMD,SSE5
+ VFNMADDPS ymmreg,ymmreg*,ymmrm256,ymmreg AMD,SSE5
+ VFNMADDPS xmmreg,xmmreg*,xmmreg,xmmrm128 AMD,SSE5
+ VFNMADDPS ymmreg,ymmreg*,ymmreg,ymmrm256 AMD,SSE5
+ VFNMADDSD xmmreg,xmmreg*,xmmrm64,xmmreg AMD,SSE5
+ VFNMADDSD xmmreg,xmmreg*,xmmreg,xmmrm64 AMD,SSE5
+ VFNMADDSS xmmreg,xmmreg*,xmmrm32,xmmreg AMD,SSE5
+ VFNMADDSS xmmreg,xmmreg*,xmmreg,xmmrm32 AMD,SSE5
+ VFNMSUBPD xmmreg,xmmreg*,xmmrm128,xmmreg AMD,SSE5
+ VFNMSUBPD ymmreg,ymmreg*,ymmrm256,ymmreg AMD,SSE5
+ VFNMSUBPD xmmreg,xmmreg*,xmmreg,xmmrm128 AMD,SSE5
+ VFNMSUBPD ymmreg,ymmreg*,ymmreg,ymmrm256 AMD,SSE5
+ VFNMSUBPS xmmreg,xmmreg*,xmmrm128,xmmreg AMD,SSE5
+ VFNMSUBPS ymmreg,ymmreg*,ymmrm256,ymmreg AMD,SSE5
+ VFNMSUBPS xmmreg,xmmreg*,xmmreg,xmmrm128 AMD,SSE5
+ VFNMSUBPS ymmreg,ymmreg*,ymmreg,ymmrm256 AMD,SSE5
+ VFNMSUBSD xmmreg,xmmreg*,xmmrm64,xmmreg AMD,SSE5
+ VFNMSUBSD xmmreg,xmmreg*,xmmreg,xmmrm64 AMD,SSE5
+ VFNMSUBSS xmmreg,xmmreg*,xmmrm32,xmmreg AMD,SSE5
+ VFNMSUBSS xmmreg,xmmreg*,xmmreg,xmmrm32 AMD,SSE5
+ VFRCZPD xmmreg,xmmrm128* AMD,SSE5
+ VFRCZPD ymmreg,ymmrm256* AMD,SSE5
+ VFRCZPS xmmreg,xmmrm128* AMD,SSE5
+ VFRCZPS ymmreg,ymmrm256* AMD,SSE5
+ VFRCZSD xmmreg,xmmrm64* AMD,SSE5
+ VFRCZSS xmmreg,xmmrm32* AMD,SSE5
+ VPCMOV xmmreg,xmmreg*,xmmrm128,xmmreg AMD,SSE5
+ VPCMOV ymmreg,ymmreg*,ymmrm256,ymmreg AMD,SSE5
+ VPCMOV xmmreg,xmmreg*,xmmreg,xmmrm128 AMD,SSE5
+ VPCMOV ymmreg,ymmreg*,ymmreg,ymmrm256 AMD,SSE5
+ VPCOMB xmmreg,xmmreg*,xmmrm128,imm8 AMD,SSE5
+ VPCOMD xmmreg,xmmreg*,xmmrm128,imm8 AMD,SSE5
+ VPCOMQ xmmreg,xmmreg*,xmmrm128,imm8 AMD,SSE5
+ VPCOMUB xmmreg,xmmreg*,xmmrm128,imm8 AMD,SSE5
+ VPCOMUD xmmreg,xmmreg*,xmmrm128,imm8 AMD,SSE5
+ VPCOMUQ xmmreg,xmmreg*,xmmrm128,imm8 AMD,SSE5
+ VPCOMUW xmmreg,xmmreg*,xmmrm128,imm8 AMD,SSE5
+ VPCOMW xmmreg,xmmreg*,xmmrm128,imm8 AMD,SSE5
+ VPHADDBD xmmreg,xmmrm128* AMD,SSE5
+ VPHADDBQ xmmreg,xmmrm128* AMD,SSE5
+ VPHADDBW xmmreg,xmmrm128* AMD,SSE5
+ VPHADDDQ xmmreg,xmmrm128* AMD,SSE5
+ VPHADDUBD xmmreg,xmmrm128* AMD,SSE5
+ VPHADDUBQ xmmreg,xmmrm128* AMD,SSE5
+ VPHADDUBW xmmreg,xmmrm128* AMD,SSE5
+ VPHADDUDQ xmmreg,xmmrm128* AMD,SSE5
+ VPHADDUWD xmmreg,xmmrm128* AMD,SSE5
+ VPHADDUWQ xmmreg,xmmrm128* AMD,SSE5
+ VPHADDWD xmmreg,xmmrm128* AMD,SSE5
+ VPHADDWQ xmmreg,xmmrm128* AMD,SSE5
+ VPHSUBBW xmmreg,xmmrm128* AMD,SSE5
+ VPHSUBDQ xmmreg,xmmrm128* AMD,SSE5
+ VPHSUBWD xmmreg,xmmrm128* AMD,SSE5
+ VPMACSDD xmmreg,xmmreg*,xmmrm128,xmmreg AMD,SSE5
+ VPMACSDQH xmmreg,xmmreg*,xmmrm128,xmmreg AMD,SSE5
+ VPMACSDQL xmmreg,xmmreg*,xmmrm128,xmmreg AMD,SSE5
+ VPMACSSDD xmmreg,xmmreg*,xmmrm128,xmmreg AMD,SSE5
+ VPMACSSDQH xmmreg,xmmreg*,xmmrm128,xmmreg AMD,SSE5
+ VPMACSSDQL xmmreg,xmmreg*,xmmrm128,xmmreg AMD,SSE5
+ VPMACSSWD xmmreg,xmmreg*,xmmrm128,xmmreg AMD,SSE5
+ VPMACSSWW xmmreg,xmmreg*,xmmrm128,xmmreg AMD,SSE5
+ VPMACSWD xmmreg,xmmreg*,xmmrm128,xmmreg AMD,SSE5
+ VPMACSWW xmmreg,xmmreg*,xmmrm128,xmmreg AMD,SSE5
+ VPMADCSSWD xmmreg,xmmreg*,xmmrm128,xmmreg AMD,SSE5
+ VPMADCSWD xmmreg,xmmreg*,xmmrm128,xmmreg AMD,SSE5
+ VPPERM xmmreg,xmmreg*,xmmreg,xmmrm128 AMD,SSE5
+ VPPERM xmmreg,xmmreg*,xmmrm128,xmmreg AMD,SSE5
+ VPROTB xmmreg,xmmrm128*,xmmreg AMD,SSE5
+ VPROTB xmmreg,xmmreg*,xmmrm128 AMD,SSE5
+ VPROTB xmmreg,xmmrm128*,imm8 AMD,SSE5
+ VPROTD xmmreg,xmmrm128*,xmmreg AMD,SSE5
+ VPROTD xmmreg,xmmreg*,xmmrm128 AMD,SSE5
+ VPROTD xmmreg,xmmrm128*,imm8 AMD,SSE5
+ VPROTQ xmmreg,xmmrm128*,xmmreg AMD,SSE5
+ VPROTQ xmmreg,xmmreg*,xmmrm128 AMD,SSE5
+ VPROTQ xmmreg,xmmrm128*,imm8 AMD,SSE5
+ VPROTW xmmreg,xmmrm128*,xmmreg AMD,SSE5
+ VPROTW xmmreg,xmmreg*,xmmrm128 AMD,SSE5
+ VPROTW xmmreg,xmmrm128*,imm8 AMD,SSE5
+ VPSHAB xmmreg,xmmrm128*,xmmreg AMD,SSE5
+ VPSHAB xmmreg,xmmreg*,xmmrm128 AMD,SSE5
+ VPSHAD xmmreg,xmmrm128*,xmmreg AMD,SSE5
+ VPSHAD xmmreg,xmmreg*,xmmrm128 AMD,SSE5
+ VPSHAQ xmmreg,xmmrm128*,xmmreg AMD,SSE5
+ VPSHAQ xmmreg,xmmreg*,xmmrm128 AMD,SSE5
+ VPSHAW xmmreg,xmmrm128*,xmmreg AMD,SSE5
+ VPSHAW xmmreg,xmmreg*,xmmrm128 AMD,SSE5
+ VPSHLB xmmreg,xmmrm128*,xmmreg AMD,SSE5
+ VPSHLB xmmreg,xmmreg*,xmmrm128 AMD,SSE5
+ VPSHLD xmmreg,xmmrm128*,xmmreg AMD,SSE5
+ VPSHLD xmmreg,xmmreg*,xmmrm128 AMD,SSE5
+ VPSHLQ xmmreg,xmmrm128*,xmmreg AMD,SSE5
+ VPSHLQ xmmreg,xmmreg*,xmmrm128 AMD,SSE5
+ VPSHLW xmmreg,xmmrm128*,xmmreg AMD,SSE5
+ VPSHLW xmmreg,xmmreg*,xmmrm128 AMD,SSE5
+
+B.1.32 Systematic names for the hinting nop instructions
+
+ HINT_NOP0 rm16 P6,UNDOC
+ HINT_NOP0 rm32 P6,UNDOC
+ HINT_NOP0 rm64 X64,UNDOC
+ HINT_NOP1 rm16 P6,UNDOC
+ HINT_NOP1 rm32 P6,UNDOC
+ HINT_NOP1 rm64 X64,UNDOC
+ HINT_NOP2 rm16 P6,UNDOC
+ HINT_NOP2 rm32 P6,UNDOC
+ HINT_NOP2 rm64 X64,UNDOC
+ HINT_NOP3 rm16 P6,UNDOC
+ HINT_NOP3 rm32 P6,UNDOC
+ HINT_NOP3 rm64 X64,UNDOC
+ HINT_NOP4 rm16 P6,UNDOC
+ HINT_NOP4 rm32 P6,UNDOC
+ HINT_NOP4 rm64 X64,UNDOC
+ HINT_NOP5 rm16 P6,UNDOC
+ HINT_NOP5 rm32 P6,UNDOC
+ HINT_NOP5 rm64 X64,UNDOC
+ HINT_NOP6 rm16 P6,UNDOC
+ HINT_NOP6 rm32 P6,UNDOC
+ HINT_NOP6 rm64 X64,UNDOC
+ HINT_NOP7 rm16 P6,UNDOC
+ HINT_NOP7 rm32 P6,UNDOC
+ HINT_NOP7 rm64 X64,UNDOC
+ HINT_NOP8 rm16 P6,UNDOC
+ HINT_NOP8 rm32 P6,UNDOC
+ HINT_NOP8 rm64 X64,UNDOC
+ HINT_NOP9 rm16 P6,UNDOC
+ HINT_NOP9 rm32 P6,UNDOC
+ HINT_NOP9 rm64 X64,UNDOC
+ HINT_NOP10 rm16 P6,UNDOC
+ HINT_NOP10 rm32 P6,UNDOC
+ HINT_NOP10 rm64 X64,UNDOC
+ HINT_NOP11 rm16 P6,UNDOC
+ HINT_NOP11 rm32 P6,UNDOC
+ HINT_NOP11 rm64 X64,UNDOC
+ HINT_NOP12 rm16 P6,UNDOC
+ HINT_NOP12 rm32 P6,UNDOC
+ HINT_NOP12 rm64 X64,UNDOC
+ HINT_NOP13 rm16 P6,UNDOC
+ HINT_NOP13 rm32 P6,UNDOC
+ HINT_NOP13 rm64 X64,UNDOC
+ HINT_NOP14 rm16 P6,UNDOC
+ HINT_NOP14 rm32 P6,UNDOC
+ HINT_NOP14 rm64 X64,UNDOC
+ HINT_NOP15 rm16 P6,UNDOC
+ HINT_NOP15 rm32 P6,UNDOC
+ HINT_NOP15 rm64 X64,UNDOC
+ HINT_NOP16 rm16 P6,UNDOC
+ HINT_NOP16 rm32 P6,UNDOC
+ HINT_NOP16 rm64 X64,UNDOC
+ HINT_NOP17 rm16 P6,UNDOC
+ HINT_NOP17 rm32 P6,UNDOC
+ HINT_NOP17 rm64 X64,UNDOC
+ HINT_NOP18 rm16 P6,UNDOC
+ HINT_NOP18 rm32 P6,UNDOC
+ HINT_NOP18 rm64 X64,UNDOC
+ HINT_NOP19 rm16 P6,UNDOC
+ HINT_NOP19 rm32 P6,UNDOC
+ HINT_NOP19 rm64 X64,UNDOC
+ HINT_NOP20 rm16 P6,UNDOC
+ HINT_NOP20 rm32 P6,UNDOC
+ HINT_NOP20 rm64 X64,UNDOC
+ HINT_NOP21 rm16 P6,UNDOC
+ HINT_NOP21 rm32 P6,UNDOC
+ HINT_NOP21 rm64 X64,UNDOC
+ HINT_NOP22 rm16 P6,UNDOC
+ HINT_NOP22 rm32 P6,UNDOC
+ HINT_NOP22 rm64 X64,UNDOC
+ HINT_NOP23 rm16 P6,UNDOC
+ HINT_NOP23 rm32 P6,UNDOC
+ HINT_NOP23 rm64 X64,UNDOC
+ HINT_NOP24 rm16 P6,UNDOC
+ HINT_NOP24 rm32 P6,UNDOC
+ HINT_NOP24 rm64 X64,UNDOC
+ HINT_NOP25 rm16 P6,UNDOC
+ HINT_NOP25 rm32 P6,UNDOC
+ HINT_NOP25 rm64 X64,UNDOC
+ HINT_NOP26 rm16 P6,UNDOC
+ HINT_NOP26 rm32 P6,UNDOC
+ HINT_NOP26 rm64 X64,UNDOC
+ HINT_NOP27 rm16 P6,UNDOC
+ HINT_NOP27 rm32 P6,UNDOC
+ HINT_NOP27 rm64 X64,UNDOC
+ HINT_NOP28 rm16 P6,UNDOC
+ HINT_NOP28 rm32 P6,UNDOC
+ HINT_NOP28 rm64 X64,UNDOC
+ HINT_NOP29 rm16 P6,UNDOC
+ HINT_NOP29 rm32 P6,UNDOC
+ HINT_NOP29 rm64 X64,UNDOC
+ HINT_NOP30 rm16 P6,UNDOC
+ HINT_NOP30 rm32 P6,UNDOC
+ HINT_NOP30 rm64 X64,UNDOC
+ HINT_NOP31 rm16 P6,UNDOC
+ HINT_NOP31 rm32 P6,UNDOC
+ HINT_NOP31 rm64 X64,UNDOC
+ HINT_NOP32 rm16 P6,UNDOC
+ HINT_NOP32 rm32 P6,UNDOC
+ HINT_NOP32 rm64 X64,UNDOC
+ HINT_NOP33 rm16 P6,UNDOC
+ HINT_NOP33 rm32 P6,UNDOC
+ HINT_NOP33 rm64 X64,UNDOC
+ HINT_NOP34 rm16 P6,UNDOC
+ HINT_NOP34 rm32 P6,UNDOC
+ HINT_NOP34 rm64 X64,UNDOC
+ HINT_NOP35 rm16 P6,UNDOC
+ HINT_NOP35 rm32 P6,UNDOC
+ HINT_NOP35 rm64 X64,UNDOC
+ HINT_NOP36 rm16 P6,UNDOC
+ HINT_NOP36 rm32 P6,UNDOC
+ HINT_NOP36 rm64 X64,UNDOC
+ HINT_NOP37 rm16 P6,UNDOC
+ HINT_NOP37 rm32 P6,UNDOC
+ HINT_NOP37 rm64 X64,UNDOC
+ HINT_NOP38 rm16 P6,UNDOC
+ HINT_NOP38 rm32 P6,UNDOC
+ HINT_NOP38 rm64 X64,UNDOC
+ HINT_NOP39 rm16 P6,UNDOC
+ HINT_NOP39 rm32 P6,UNDOC
+ HINT_NOP39 rm64 X64,UNDOC
+ HINT_NOP40 rm16 P6,UNDOC
+ HINT_NOP40 rm32 P6,UNDOC
+ HINT_NOP40 rm64 X64,UNDOC
+ HINT_NOP41 rm16 P6,UNDOC
+ HINT_NOP41 rm32 P6,UNDOC
+ HINT_NOP41 rm64 X64,UNDOC
+ HINT_NOP42 rm16 P6,UNDOC
+ HINT_NOP42 rm32 P6,UNDOC
+ HINT_NOP42 rm64 X64,UNDOC
+ HINT_NOP43 rm16 P6,UNDOC
+ HINT_NOP43 rm32 P6,UNDOC
+ HINT_NOP43 rm64 X64,UNDOC
+ HINT_NOP44 rm16 P6,UNDOC
+ HINT_NOP44 rm32 P6,UNDOC
+ HINT_NOP44 rm64 X64,UNDOC
+ HINT_NOP45 rm16 P6,UNDOC
+ HINT_NOP45 rm32 P6,UNDOC
+ HINT_NOP45 rm64 X64,UNDOC
+ HINT_NOP46 rm16 P6,UNDOC
+ HINT_NOP46 rm32 P6,UNDOC
+ HINT_NOP46 rm64 X64,UNDOC
+ HINT_NOP47 rm16 P6,UNDOC
+ HINT_NOP47 rm32 P6,UNDOC
+ HINT_NOP47 rm64 X64,UNDOC
+ HINT_NOP48 rm16 P6,UNDOC
+ HINT_NOP48 rm32 P6,UNDOC
+ HINT_NOP48 rm64 X64,UNDOC
+ HINT_NOP49 rm16 P6,UNDOC
+ HINT_NOP49 rm32 P6,UNDOC
+ HINT_NOP49 rm64 X64,UNDOC
+ HINT_NOP50 rm16 P6,UNDOC
+ HINT_NOP50 rm32 P6,UNDOC
+ HINT_NOP50 rm64 X64,UNDOC
+ HINT_NOP51 rm16 P6,UNDOC
+ HINT_NOP51 rm32 P6,UNDOC
+ HINT_NOP51 rm64 X64,UNDOC
+ HINT_NOP52 rm16 P6,UNDOC
+ HINT_NOP52 rm32 P6,UNDOC
+ HINT_NOP52 rm64 X64,UNDOC
+ HINT_NOP53 rm16 P6,UNDOC
+ HINT_NOP53 rm32 P6,UNDOC
+ HINT_NOP53 rm64 X64,UNDOC
+ HINT_NOP54 rm16 P6,UNDOC
+ HINT_NOP54 rm32 P6,UNDOC
+ HINT_NOP54 rm64 X64,UNDOC
+ HINT_NOP55 rm16 P6,UNDOC
+ HINT_NOP55 rm32 P6,UNDOC
+ HINT_NOP55 rm64 X64,UNDOC
+ HINT_NOP56 rm16 P6,UNDOC
+ HINT_NOP56 rm32 P6,UNDOC
+ HINT_NOP56 rm64 X64,UNDOC
+ HINT_NOP57 rm16 P6,UNDOC
+ HINT_NOP57 rm32 P6,UNDOC
+ HINT_NOP57 rm64 X64,UNDOC
+ HINT_NOP58 rm16 P6,UNDOC
+ HINT_NOP58 rm32 P6,UNDOC
+ HINT_NOP58 rm64 X64,UNDOC
+ HINT_NOP59 rm16 P6,UNDOC
+ HINT_NOP59 rm32 P6,UNDOC
+ HINT_NOP59 rm64 X64,UNDOC
+ HINT_NOP60 rm16 P6,UNDOC
+ HINT_NOP60 rm32 P6,UNDOC
+ HINT_NOP60 rm64 X64,UNDOC
+ HINT_NOP61 rm16 P6,UNDOC
+ HINT_NOP61 rm32 P6,UNDOC
+ HINT_NOP61 rm64 X64,UNDOC
+ HINT_NOP62 rm16 P6,UNDOC
+ HINT_NOP62 rm32 P6,UNDOC
+ HINT_NOP62 rm64 X64,UNDOC
+ HINT_NOP63 rm16 P6,UNDOC
+ HINT_NOP63 rm32 P6,UNDOC
+ HINT_NOP63 rm64 X64,UNDOC
+
+Appendix C: NASM Version History
+--------------------------------
+
+ C.1 NASM 2 Series
+
+ The NASM 2 series support x86-64, and is the production version of
+ NASM since 2007.
+
+ C.1.1 Version 2.08
+
+ (*) A number of enhancements/fixes in macros area.
+
+ (*) Support for arbitrarily terminating macro expansions
+ `%exitmacro'. See section 4.3.12.
+
+ (*) Support for recursive macro expansion `%rmacro/irmacro'. See
+ section 4.3.1.
+
+ (*) Support for converting strings to tokens. See section 4.1.9.
+
+ (*) Fuzzy operand size logic introduced.
+
+ (*) Fix COFF stack overrun on too long export identifiers.
+
+ (*) Fix Macho-O alignment bug.
+
+ (*) Fix crashes with -fwin32 on file with many exports.
+
+ (*) Fix stack overrun for too long [DEBUG id].
+
+ (*) Fix incorrect sbyte usage in IMUL (hit only if optimization flag
+ passed).
+
+ (*) Append ending token for `.stabs' records in the ELF output
+ format.
+
+ (*) New NSIS script which uses ModernUI and MultiUser approach.
+
+ (*) Visual Studio 2008 NASM integration (rules file).
+
+ (*) Warn a user if a constant is too long (and as result will be
+ stripped).
+
+ (*) The obsoleted pre-XOP AMD SSE5 instruction set which was never
+ actualized was removed.
+
+ (*) Fix stack overrun on too long error file name passed from the
+ command line.
+
+ (*) Bind symbols to the .text section by default (ie in case if
+ SECTION directive was omitted) in the ELF output format.
+
+ (*) Fix sync points array index wrapping.
+
+ (*) A few fixes for FMA4 and XOP instruction templates.
+
+ (*) Add AMD Lightweight Profiling (LWP) instructions.
+
+ C.1.2 Version 2.07
+
+ (*) NASM is now under the 2-clause BSD license. See section 1.1.2.
+
+ (*) Fix the section type for the `.strtab' section in the `elf64'
+ output format.
+
+ (*) Fix the handling of `COMMON' directives in the `obj' output
+ format.
+
+ (*) New `ith' and `srec' output formats; these are variants of the
+ `bin' output format which output Intel hex and Motorola S-
+ records, respectively. See section 7.2 and section 7.3.
+
+ (*) `rdf2ihx' replaced with an enhanced `rdf2bin', which can output
+ binary, COM, Intel hex or Motorola S-records.
+
+ (*) The Windows installer now puts the NASM directory first in the
+ `PATH' of the "NASM Shell".
+
+ (*) Revert the early expansion behavior of `%+' to pre-2.06
+ behavior: `%+' is only expanded late.
+
+ (*) Yet another Mach-O alignment fix.
+
+ (*) Don't delete the list file on errors. Also, include error and
+ warning information in the list file.
+
+ (*) Support for 64-bit Mach-O output, see section 7.8.
+
+ (*) Fix assert failure on certain operations that involve strings
+ with high-bit bytes.
+
+ C.1.3 Version 2.06
+
+ (*) This release is dedicated to the memory of Charles A. Crayne,
+ long time NASM developer as well as moderator of
+ `comp.lang.asm.x86' and author of the book _Serious Assembler_.
+ We miss you, Chuck.
+
+ (*) Support for indirect macro expansion (`%[...]'). See section
+ 4.1.3.
+
+ (*) `%pop' can now take an argument, see section 4.7.1.
+
+ (*) The argument to `%use' is no longer macro-expanded. Use `%[...]'
+ if macro expansion is desired.
+
+ (*) Support for thread-local storage in ELF32 and ELF64. See section
+ 7.9.4.
+
+ (*) Fix crash on `%ifmacro' without an argument.
+
+ (*) Correct the arguments to the `POPCNT' instruction.
+
+ (*) Fix section alignment in the Mach-O format.
+
+ (*) Update AVX support to version 5 of the Intel specification.
+
+ (*) Fix the handling of accesses to context-local macros from higher
+ levels in the context stack.
+
+ (*) Treat `WAIT' as a prefix rather than as an instruction, thereby
+ allowing constructs like `O16 FSAVE' to work correctly.
+
+ (*) Support for structures with a non-zero base offset. See section
+ 4.11.10.
+
+ (*) Correctly handle preprocessor token concatenation (see section
+ 4.3.8) involving floating-point numbers.
+
+ (*) The `PINSR' series of instructions have been corrected and
+ rationalized.
+
+ (*) Removed AMD SSE5, replaced with the new XOP/FMA4/CVT16 (rev
+ 3.03) spec.
+
+ (*) The ELF backends no longer automatically generate a `.comment'
+ section.
+
+ (*) Add additional "well-known" ELF sections with default
+ attributes. See section 7.9.2.
+
+ C.1.4 Version 2.05.01
+
+ (*) Fix the `-w'/`-W' option parsing, which was broken in NASM 2.05.
+
+ C.1.5 Version 2.05
+
+ (*) Fix redundant REX.W prefix on `JMP reg64'.
+
+ (*) Make the behaviour of `-O0' match NASM 0.98 legacy behavior. See
+ section 2.1.22.
+
+ (*) `-w-user' can be used to suppress the output of `%warning'
+ directives. See section 2.1.24.
+
+ (*) Fix bug where `ALIGN' would issue a full alignment datum instead
+ of zero bytes.
+
+ (*) Fix offsets in list files.
+
+ (*) Fix `%include' inside multi-line macros or loops.
+
+ (*) Fix error where NASM would generate a spurious warning on valid
+ optimizations of immediate values.
+
+ (*) Fix arguments to a number of the `CVT' SSE instructions.
+
+ (*) Fix RIP-relative offsets when the instruction carries an
+ immediate.
+
+ (*) Massive overhaul of the ELF64 backend for spec compliance.
+
+ (*) Fix the Geode `PFRCPV' and `PFRSQRTV' instruction.
+
+ (*) Fix the SSE 4.2 `CRC32' instruction.
+
+ C.1.6 Version 2.04
+
+ (*) Sanitize macro handing in the `%error' directive.
+
+ (*) New `%warning' directive to issue user-controlled warnings.
+
+ (*) `%error' directives are now deferred to the final assembly
+ phase.
+
+ (*) New `%fatal' directive to immediately terminate assembly.
+
+ (*) New `%strcat' directive to join quoted strings together.
+
+ (*) New `%use' macro directive to support standard macro directives.
+ See section 4.6.4.
+
+ (*) Excess default parameters to `%macro' now issues a warning by
+ default. See section 4.3.
+
+ (*) Fix `%ifn' and `%elifn'.
+
+ (*) Fix nested `%else' clauses.
+
+ (*) Correct the handling of nested `%rep's.
+
+ (*) New `%unmacro' directive to undeclare a multi-line macro. See
+ section 4.3.11.
+
+ (*) Builtin macro `__PASS__' which expands to the current assembly
+ pass. See section 4.11.9.
+
+ (*) `__utf16__' and `__utf32__' operators to generate UTF-16 and
+ UTF-32 strings. See section 3.4.5.
+
+ (*) Fix bug in case-insensitive matching when compiled on platforms
+ that don't use the `configure' script. Of the official release
+ binaries, that only affected the OS/2 binary.
+
+ (*) Support for x87 packed BCD constants. See section 3.4.7.
+
+ (*) Correct the `LTR' and `SLDT' instructions in 64-bit mode.
+
+ (*) Fix unnecessary REX.W prefix on indirect jumps in 64-bit mode.
+
+ (*) Add AVX versions of the AES instructions (`VAES'...).
+
+ (*) Fix the 256-bit FMA instructions.
+
+ (*) Add 256-bit AVX stores per the latest AVX spec.
+
+ (*) VIA XCRYPT instructions can now be written either with or
+ without `REP', apparently different versions of the VIA spec
+ wrote them differently.
+
+ (*) Add missing 64-bit `MOVNTI' instruction.
+
+ (*) Fix the operand size of `VMREAD' and `VMWRITE'.
+
+ (*) Numerous bug fixes, especially to the AES, AVX and VTX
+ instructions.
+
+ (*) The optimizer now always runs until it converges. It also runs
+ even when disabled, but doesn't optimize. This allows most
+ forward references to be resolved properly.
+
+ (*) `%push' no longer needs a context identifier; omitting the
+ context identifier results in an anonymous context.
+
+ C.1.7 Version 2.03.01
+
+ (*) Fix buffer overflow in the listing module.
+
+ (*) Fix the handling of hexadecimal escape codes in `...` strings.
+
+ (*) The Postscript/PDF documentation has been reformatted.
+
+ (*) The `-F' option now implies `-g'.
+
+ C.1.8 Version 2.03
+
+ (*) Add support for Intel AVX, CLMUL and FMA instructions, including
+ YMM registers.
+
+ (*) `dy', `resy' and `yword' for 32-byte operands.
+
+ (*) Fix some SSE5 instructions.
+
+ (*) Intel `INVEPT', `INVVPID' and `MOVBE' instructions.
+
+ (*) Fix checking for critical expressions when the optimizer is
+ enabled.
+
+ (*) Support the DWARF debugging format for ELF targets.
+
+ (*) Fix optimizations of signed bytes.
+
+ (*) Fix operation on bigendian machines.
+
+ (*) Fix buffer overflow in the preprocessor.
+
+ (*) `SAFESEH' support for Win32, `IMAGEREL' for Win64 (SEH).
+
+ (*) `%?' and `%??' to refer to the name of a macro itself. In
+ particular, `%idefine keyword $%?' can be used to make a keyword
+ "disappear".
+
+ (*) New options for dependency generation: `-MD', `-MF', `-MP',
+ `-MT', `-MQ'.
+
+ (*) New preprocessor directives `%pathsearch' and `%depend'; INCBIN
+ reimplemented as a macro.
+
+ (*) `%include' now resolves macros in a sane manner.
+
+ (*) `%substr' can now be used to get other than one-character
+ substrings.
+
+ (*) New type of character/string constants, using backquotes
+ (``...`'), which support C-style escape sequences.
+
+ (*) `%defstr' and `%idefstr' to stringize macro definitions before
+ creation.
+
+ (*) Fix forward references used in `EQU' statements.
+
+ C.1.9 Version 2.02
+
+ (*) Additional fixes for MMX operands with explicit `qword', as well
+ as (hopefully) SSE operands with `oword'.
+
+ (*) Fix handling of truncated strings with `DO'.
+
+ (*) Fix segfaults due to memory overwrites when floating-point
+ constants were used.
+
+ (*) Fix segfaults due to missing include files.
+
+ (*) Fix OpenWatcom Makefiles for DOS and OS/2.
+
+ (*) Add autogenerated instruction list back into the documentation.
+
+ (*) ELF: Fix segfault when generating stabs, and no symbols have
+ been defined.
+
+ (*) ELF: Experimental support for DWARF debugging information.
+
+ (*) New compile date and time standard macros.
+
+ (*) `%ifnum' now returns true for negative numbers.
+
+ (*) New `%iftoken' test for a single token.
+
+ (*) New `%ifempty' test for empty expansion.
+
+ (*) Add support for the `XSAVE' instruction group.
+
+ (*) Makefile for Netware/gcc.
+
+ (*) Fix issue with some warnings getting emitted way too many times.
+
+ (*) Autogenerated instruction list added to the documentation.
+
+C.1.10 Version 2.01
+
+ (*) Fix the handling of MMX registers with explicit `qword' tags on
+ memory (broken in 2.00 due to 64-bit changes.)
+
+ (*) Fix the PREFETCH instructions.
+
+ (*) Fix the documentation.
+
+ (*) Fix debugging info when using `-f elf' (backwards compatibility
+ alias for `-f elf32').
+
+ (*) Man pages for rdoff tools (from the Debian project.)
+
+ (*) ELF: handle large numbers of sections.
+
+ (*) Fix corrupt output when the optimizer runs out of passes.
+
+C.1.11 Version 2.00
+
+ (*) Added c99 data-type compliance.
+
+ (*) Added general x86-64 support.
+
+ (*) Added win64 (x86-64 COFF) output format.
+
+ (*) Added `__BITS__' standard macro.
+
+ (*) Renamed the `elf' output format to `elf32' for clarity.
+
+ (*) Added `elf64' and `macho' (MacOS X) output formats.
+
+ (*) Added Numeric constants in `dq' directive.
+
+ (*) Added `oword', `do' and `reso' pseudo operands.
+
+ (*) Allow underscores in numbers.
+
+ (*) Added 8-, 16- and 128-bit floating-point formats.
+
+ (*) Added binary, octal and hexadecimal floating-point.
+
+ (*) Correct the generation of floating-point constants.
+
+ (*) Added floating-point option control.
+
+ (*) Added Infinity and NaN floating point support.
+
+ (*) Added ELF Symbol Visibility support.
+
+ (*) Added setting OSABI value in ELF header directive.
+
+ (*) Added Generate Makefile Dependencies option.
+
+ (*) Added Unlimited Optimization Passes option.
+
+ (*) Added `%IFN' and `%ELIFN' support.
+
+ (*) Added Logical Negation Operator.
+
+ (*) Enhanced Stack Relative Preprocessor Directives.
+
+ (*) Enhanced ELF Debug Formats.
+
+ (*) Enhanced Send Errors to a File option.
+
+ (*) Added SSSE3, SSE4.1, SSE4.2, SSE5 support.
+
+ (*) Added a large number of additional instructions.
+
+ (*) Significant performance improvements.
+
+ (*) `-w+warning' and `-w-warning' can now be written as -Wwarning
+ and -Wno-warning, respectively. See section 2.1.24.
+
+ (*) Add `-w+error' to treat warnings as errors. See section 2.1.24.
+
+ (*) Add `-w+all' and `-w-all' to enable or disable all suppressible
+ warnings. See section 2.1.24.
+
+ C.2 NASM 0.98 Series
+
+ The 0.98 series was the production versions of NASM from 1999 to
+ 2007.
+
+ C.2.1 Version 0.98.39
+
+ (*) fix buffer overflow
+
+ (*) fix outas86's `.bss' handling
+
+ (*) "make spotless" no longer deletes config.h.in.
+
+ (*) `%(el)if(n)idn' insensitivity to string quotes difference
+ (#809300).
+
+ (*) (nasm.c)`__OUTPUT_FORMAT__' changed to string value instead of
+ symbol.
+
+ C.2.2 Version 0.98.38
+
+ (*) Add Makefile for 16-bit DOS binaries under OpenWatcom, and
+ modify `mkdep.pl' to be able to generate completely pathless
+ dependencies, as required by OpenWatcom wmake (it supports path
+ searches, but not explicit paths.)
+
+ (*) Fix the `STR' instruction.
+
+ (*) Fix the ELF output format, which was broken under certain
+ circumstances due to the addition of stabs support.
+
+ (*) Quick-fix Borland format debug-info for `-f obj'
+
+ (*) Fix for `%rep' with no arguments (#560568)
+
+ (*) Fix concatenation of preprocessor function call (#794686)
+
+ (*) Fix long label causes coredump (#677841)
+
+ (*) Use autoheader as well as autoconf to keep configure from
+ generating ridiculously long command lines.
+
+ (*) Make sure that all of the formats which support debugging output
+ actually will suppress debugging output when `-g' not specified.
+
+ C.2.3 Version 0.98.37
+
+ (*) Paths given in `-I' switch searched for `incbin'-ed as well as
+ `%include'-ed files.
+
+ (*) Added stabs debugging for the ELF output format, patch from
+ Martin Wawro.
+
+ (*) Fix `output/outbin.c' to allow origin > 80000000h.
+
+ (*) Make `-U' switch work.
+
+ (*) Fix the use of relative offsets with explicit prefixes, e.g.
+ `a32 loop foo'.
+
+ (*) Remove `backslash()'.
+
+ (*) Fix the `SMSW' and `SLDT' instructions.
+
+ (*) `-O2' and `-O3' are no longer aliases for `-O10' and `-O15'. If
+ you mean the latter, please say so! :)
+
+ C.2.4 Version 0.98.36
+
+ (*) Update rdoff - librarian/archiver - common rec - docs!
+
+ (*) Fix signed/unsigned problems.
+
+ (*) Fix `JMP FAR label' and `CALL FAR label'.
+
+ (*) Add new multisection support - map files - fix align bug
+
+ (*) Fix sysexit, movhps/movlps reg,reg bugs in insns.dat
+
+ (*) `Q' or `O' suffixes indicate octal
+
+ (*) Support Prescott new instructions (PNI).
+
+ (*) Cyrix `XSTORE' instruction.
+
+ C.2.5 Version 0.98.35
+
+ (*) Fix build failure on 16-bit DOS (Makefile.bc3 workaround for
+ compiler bug.)
+
+ (*) Fix dependencies and compiler warnings.
+
+ (*) Add "const" in a number of places.
+
+ (*) Add -X option to specify error reporting format (use -Xvc to
+ integrate with Microsoft Visual Studio.)
+
+ (*) Minor changes for code legibility.
+
+ (*) Drop use of tmpnam() in rdoff (security fix.)
+
+ C.2.6 Version 0.98.34
+
+ (*) Correct additional address-size vs. operand-size confusions.
+
+ (*) Generate dependencies for all Makefiles automatically.
+
+ (*) Add support for unimplemented (but theoretically available)
+ registers such as tr0 and cr5. Segment registers 6 and 7 are
+ called segr6 and segr7 for the operations which they can be
+ represented.
+
+ (*) Correct some disassembler bugs related to redundant address-size
+ prefixes. Some work still remains in this area.
+
+ (*) Correctly generate an error for things like "SEG eax".
+
+ (*) Add the JMPE instruction, enabled by "CPU IA64".
+
+ (*) Correct compilation on newer gcc/glibc platforms.
+
+ (*) Issue an error on things like "jmp far eax".
+
+ C.2.7 Version 0.98.33
+
+ (*) New __NASM_PATCHLEVEL__ and __NASM_VERSION_ID__ standard macros
+ to round out the version-query macros. version.pl now
+ understands X.YYplWW or X.YY.ZZplWW as a version number,
+ equivalent to X.YY.ZZ.WW (or X.YY.0.WW, as appropriate).
+
+ (*) New keyword "strict" to disable the optimization of specific
+ operands.
+
+ (*) Fix the handing of size overrides with JMP instructions
+ (instructions such as "jmp dword foo".)
+
+ (*) Fix the handling of "ABSOLUTE label", where "label" points into
+ a relocatable segment.
+
+ (*) Fix OBJ output format with lots of externs.
+
+ (*) More documentation updates.
+
+ (*) Add -Ov option to get verbose information about optimizations.
+
+ (*) Undo a braindead change which broke `%elif' directives.
+
+ (*) Makefile updates.
+
+ C.2.8 Version 0.98.32
+
+ (*) Fix NASM crashing when `%macro' directives were left
+ unterminated.
+
+ (*) Lots of documentation updates.
+
+ (*) Complete rewrite of the PostScript/PDF documentation generator.
+
+ (*) The MS Visual C++ Makefile was updated and corrected.
+
+ (*) Recognize .rodata as a standard section name in ELF.
+
+ (*) Fix some obsolete Perl4-isms in Perl scripts.
+
+ (*) Fix configure.in to work with autoconf 2.5x.
+
+ (*) Fix a couple of "make cleaner" misses.
+
+ (*) Make the normal "./configure && make" work with Cygwin.
+
+ C.2.9 Version 0.98.31
+
+ (*) Correctly build in a separate object directory again.
+
+ (*) Derive all references to the version number from the version
+ file.
+
+ (*) New standard macros __NASM_SUBMINOR__ and __NASM_VER__ macros.
+
+ (*) Lots of Makefile updates and bug fixes.
+
+ (*) New `%ifmacro' directive to test for multiline macros.
+
+ (*) Documentation updates.
+
+ (*) Fixes for 16-bit OBJ format output.
+
+ (*) Changed the NASM environment variable to NASMENV.
+
+C.2.10 Version 0.98.30
+
+ (*) Changed doc files a lot: completely removed old READMExx and
+ Wishlist files, incorporating all information in CHANGES and
+ TODO.
+
+ (*) I waited a long time to rename zoutieee.c to (original)
+ outieee.c
+
+ (*) moved all output modules to output/ subdirectory.
+
+ (*) Added 'make strip' target to strip debug info from nasm &
+ ndisasm.
+
+ (*) Added INSTALL file with installation instructions.
+
+ (*) Added -v option description to nasm man.
+
+ (*) Added dist makefile target to produce source distributions.
+
+ (*) 16-bit support for ELF output format (GNU extension, but
+ useful.)
+
+C.2.11 Version 0.98.28
+
+ (*) Fastcooked this for Debian's Woody release: Frank applied the
+ INCBIN bug patch to 0.98.25alt and called it 0.98.28 to not
+ confuse poor little apt-get.
+
+C.2.12 Version 0.98.26
+
+ (*) Reorganised files even better from 0.98.25alt
+
+C.2.13 Version 0.98.25alt
+
+ (*) Prettified the source tree. Moved files to more reasonable
+ places.
+
+ (*) Added findleak.pl script to misc/ directory.
+
+ (*) Attempted to fix doc.
+
+C.2.14 Version 0.98.25
+
+ (*) Line continuation character `\'.
+
+ (*) Docs inadvertantly reverted - "dos packaging".
+
+C.2.15 Version 0.98.24p1
+
+ (*) FIXME: Someone, document this please.
+
+C.2.16 Version 0.98.24
+
+ (*) Documentation - Ndisasm doc added to Nasm.doc.
+
+C.2.17 Version 0.98.23
+
+ (*) Attempted to remove rdoff version1
+
+ (*) Lino Mastrodomenico's patches to preproc.c (%$$ bug?).
+
+C.2.18 Version 0.98.22
+
+ (*) Update rdoff2 - attempt to remove v1.
+
+C.2.19 Version 0.98.21
+
+ (*) Optimization fixes.
+
+C.2.20 Version 0.98.20
+
+ (*) Optimization fixes.
+
+C.2.21 Version 0.98.19
+
+ (*) H. J. Lu's patch back out.
+
+C.2.22 Version 0.98.18
+
+ (*) Added ".rdata" to "-f win32".
+
+C.2.23 Version 0.98.17
+
+ (*) H. J. Lu's "bogus elf" patch. (Red Hat problem?)
+
+C.2.24 Version 0.98.16
+
+ (*) Fix whitespace before "[section ..." bug.
+
+C.2.25 Version 0.98.15
+
+ (*) Rdoff changes (?).
+
+ (*) Fix fixes to memory leaks.
+
+C.2.26 Version 0.98.14
+
+ (*) Fix memory leaks.
+
+C.2.27 Version 0.98.13
+
+ (*) There was no 0.98.13
+
+C.2.28 Version 0.98.12
+
+ (*) Update optimization (new function of "-O1")
+
+ (*) Changes to test/bintest.asm (?).
+
+C.2.29 Version 0.98.11
+
+ (*) Optimization changes.
+
+ (*) Ndisasm fixed.
+
+C.2.30 Version 0.98.10
+
+ (*) There was no 0.98.10
+
+C.2.31 Version 0.98.09
+
+ (*) Add multiple sections support to "-f bin".
+
+ (*) Changed GLOBAL_TEMP_BASE in outelf.c from 6 to 15.
+
+ (*) Add "-v" as an alias to the "-r" switch.
+
+ (*) Remove "#ifdef" from Tasm compatibility options.
+
+ (*) Remove redundant size-overrides on "mov ds, ex", etc.
+
+ (*) Fixes to SSE2, other insns.dat (?).
+
+ (*) Enable uppercase "I" and "P" switches.
+
+ (*) Case insinsitive "seg" and "wrt".
+
+ (*) Update install.sh (?).
+
+ (*) Allocate tokens in blocks.
+
+ (*) Improve "invalid effective address" messages.
+
+C.2.32 Version 0.98.08
+
+ (*) Add "`%strlen'" and "`%substr'" macro operators
+
+ (*) Fixed broken c16.mac.
+
+ (*) Unterminated string error reported.
+
+ (*) Fixed bugs as per 0.98bf
+
+C.2.33 Version 0.98.09b with John Coffman patches released 28-Oct-2001
+
+ Changes from 0.98.07 release to 98.09b as of 28-Oct-2001
+
+ (*) More closely compatible with 0.98 when -O0 is implied or
+ specified. Not strictly identical, since backward branches in
+ range of short offsets are recognized, and signed byte values
+ with no explicit size specification will be assembled as a
+ single byte.
+
+ (*) More forgiving with the PUSH instruction. 0.98 requires a size
+ to be specified always. 0.98.09b will imply the size from the
+ current BITS setting (16 or 32).
+
+ (*) Changed definition of the optimization flag:
+
+ -O0 strict two-pass assembly, JMP and Jcc are handled more like
+ 0.98, except that back- ward JMPs are short, if possible.
+
+ -O1 strict two-pass assembly, but forward branches are assembled
+ with code guaranteed to reach; may produce larger code than -O0, but
+ will produce successful assembly more often if branch offset sizes
+ are not specified.
+
+ -O2 multi-pass optimization, minimize branch offsets; also will
+ minimize signed immed- iate bytes, overriding size specification.
+
+ -O3 like -O2, but more passes taken, if needed
+
+C.2.34 Version 0.98.07 released 01/28/01
+
+ (*) Added Stepane Denis' SSE2 instructions to a *working* version of
+ the code - some earlier versions were based on broken code -
+ sorry 'bout that. version "0.98.07"
+
+ 01/28/01
+
+ (*) Cosmetic modifications to nasm.c, nasm.h, AUTHORS, MODIFIED
+
+C.2.35 Version 0.98.06f released 01/18/01
+
+ (*) - Add "metalbrain"s jecxz bug fix in insns.dat - alter
+ nasmdoc.src to match - version "0.98.06f"
+
+C.2.36 Version 0.98.06e released 01/09/01
+
+ (*) Removed the "outforms.h" file - it appears to be someone's old
+ backup of "outform.h". version "0.98.06e"
+
+ 01/09/01
+
+ (*) fbk - finally added the fix for the "multiple %includes bug",
+ known since 7/27/99 - reported originally (?) and sent to us by
+ Austin Lunnen - he reports that John Fine had a fix within the
+ day. Here it is...
+
+ (*) Nelson Rush resigns from the group. Big thanks to Nelson for his
+ leadership and enthusiasm in getting these changes incorporated
+ into Nasm!
+
+ (*) fbk - [list +], [list -] directives - ineptly implemented,
+ should be re-written or removed, perhaps.
+
+ (*) Brian Raiter / fbk - "elfso bug" fix - applied to aoutb format
+ as well - testing might be desirable...
+
+ 08/07/00
+
+ (*) James Seter - -postfix, -prefix command line switches.
+
+ (*) Yuri Zaporogets - rdoff utility changes.
+
+C.2.37 Version 0.98p1
+
+ (*) GAS-like palign (Panos Minos)
+
+ (*) FIXME: Someone, fill this in with details
+
+C.2.38 Version 0.98bf (bug-fixed)
+
+ (*) Fixed - elf and aoutb bug - shared libraries - multiple
+ "%include" bug in "-f obj" - jcxz, jecxz bug - unrecognized
+ option bug in ndisasm
+
+C.2.39 Version 0.98.03 with John Coffman's changes released 27-Jul-2000
+
+ (*) Added signed byte optimizations for the 0x81/0x83 class of
+ instructions: ADC, ADD, AND, CMP, OR, SBB, SUB, XOR: when used
+ as 'ADD reg16,imm' or 'ADD reg32,imm.' Also optimization of
+ signed byte form of 'PUSH imm' and 'IMUL reg,imm'/'IMUL
+ reg,reg,imm.' No size specification is needed.
+
+ (*) Added multi-pass JMP and Jcc offset optimization. Offsets on
+ forward references will preferentially use the short form,
+ without the need to code a specific size (short or near) for the
+ branch. Added instructions for 'Jcc label' to use the form
+ 'Jnotcc $+3/JMP label', in cases where a short offset is out of
+ bounds. If compiling for a 386 or higher CPU, then the 386 form
+ of Jcc will be used instead.
+
+ This feature is controlled by a new command-line switch: "O", (upper
+ case letter O). "-O0" reverts the assembler to no extra optimization
+ passes, "-O1" allows up to 5 extra passes, and "-O2"(default),
+ allows up to 10 extra optimization passes.
+
+ (*) Added a new directive: 'cpu XXX', where XXX is any of: 8086,
+ 186, 286, 386, 486, 586, pentium, 686, PPro, P2, P3 or Katmai.
+ All are case insensitive. All instructions will be selected only
+ if they apply to the selected cpu or lower. Corrected a couple
+ of bugs in cpu-dependence in 'insns.dat'.
+
+ (*) Added to 'standard.mac', the "use16" and "use32" forms of the
+ "bits 16/32" directive. This is nothing new, just conforms to a
+ lot of other assemblers. (minor)
+
+ (*) Changed label allocation from 320/32 (10000 labels @ 200K+) to
+ 32/37 (1000 labels); makes running under DOS much easier. Since
+ additional label space is allocated dynamically, this should
+ have no effect on large programs with lots of labels. The 37 is
+ a prime, believed to be better for hashing. (minor)
+
+C.2.40 Version 0.98.03
+
+ "Integrated patchfile 0.98-0.98.01. I call this version 0.98.03 for
+ historical reasons: 0.98.02 was trashed." --John Coffman
+ <johninsd@san.rr.com>, 27-Jul-2000
+
+ (*) Kendall Bennett's SciTech MGL changes
+
+ (*) Note that you must define "TASM_COMPAT" at compile-time to get
+ the Tasm Ideal Mode compatibility.
+
+ (*) All changes can be compiled in and out using the TASM_COMPAT
+ macros, and when compiled without TASM_COMPAT defined we get the
+ exact same binary as the unmodified 0.98 sources.
+
+ (*) standard.mac, macros.c: Added macros to ignore TASM directives
+ before first include
+
+ (*) nasm.h: Added extern declaration for tasm_compatible_mode
+
+ (*) nasm.c: Added global variable tasm_compatible_mode
+
+ (*) Added command line switch for TASM compatible mode (-t)
+
+ (*) Changed version command line to reflect when compiled with TASM
+ additions
+
+ (*) Added response file processing to allow all arguments on a
+ single line (response file is @resp rather than -@resp for NASM
+ format).
+
+ (*) labels.c: Changes islocal() macro to support TASM style @@local
+ labels.
+
+ (*) Added islocalchar() macro to support TASM style @@local labels.
+
+ (*) parser.c: Added support for TASM style memory references (ie:
+ mov [DWORD eax],10 rather than the NASM style mov DWORD
+ [eax],10).
+
+ (*) preproc.c: Added new directives, `%arg', `%local', `%stacksize'
+ to directives table
+
+ (*) Added support for TASM style directives without a leading %
+ symbol.
+
+ (*) Integrated a block of changes from Andrew Zabolotny
+ <bit@eltech.ru>:
+
+ (*) A new keyword `%xdefine' and its case-insensitive counterpart
+ `%ixdefine'. They work almost the same way as `%define' and
+ `%idefine' but expand the definition immediately, not on the
+ invocation. Something like a cross between `%define' and
+ `%assign'. The "x" suffix stands for "eXpand", so "xdefine" can
+ be deciphered as "expand-and-define". Thus you can do things
+ like this:
+
+ %assign ofs 0
+
+ %macro arg 1
+ %xdefine %1 dword [esp+ofs]
+ %assign ofs ofs+4
+ %endmacro
+
+ (*) Changed the place where the expansion of %$name macros are
+ expanded. Now they are converted into ..@ctxnum.name form when
+ detokenizing, so there are no quirks as before when using %$name
+ arguments to macros, in macros etc. For example:
+
+ %macro abc 1
+ %define %1 hello
+ %endm
+
+ abc %$here
+ %$here
+
+ Now last line will be expanded into "hello" as expected. This also
+ allows for lots of goodies, a good example are extended "proc"
+ macros included in this archive.
+
+ (*) Added a check for "cstk" in smacro_defined() before calling
+ get_ctx() - this allows for things like:
+
+ %ifdef %$abc
+ %endif
+
+ to work without warnings even in no context.
+
+ (*) Added a check for "cstk" in %if*ctx and %elif*ctx directives -
+ this allows to use `%ifctx' without excessive warnings. If there
+ is no active context, `%ifctx' goes through "false" branch.
+
+ (*) Removed "user error: " prefix with `%error' directive: it just
+ clobbers the output and has absolutely no functionality.
+ Besides, this allows to write macros that does not differ from
+ built-in functions in any way.
+
+ (*) Added expansion of string that is output by `%error' directive.
+ Now you can do things like:
+
+ %define hello(x) Hello, x!
+
+ %define %$name andy
+ %error "hello(%$name)"
+
+ Same happened with `%include' directive.
+
+ (*) Now all directives that expect an identifier will try to expand
+ and concatenate everything without whitespaces in between before
+ usage. For example, with "unfixed" nasm the commands
+
+ %define %$abc hello
+ %define __%$abc goodbye
+ __%$abc
+
+ would produce "incorrect" output: last line will expand to
+
+ hello goodbyehello
+
+ Not quite what you expected, eh? :-) The answer is that preprocessor
+ treats the `%define' construct as if it would be
+
+ %define __ %$abc goodbye
+
+ (note the white space between __ and %$abc). After my "fix" it will
+ "correctly" expand into
+
+ goodbye
+
+ as expected. Note that I use quotes around words "correct",
+ "incorrect" etc because this is rather a feature not a bug; however
+ current behaviour is more logical (and allows more advanced macro
+ usage :-).
+
+ Same change was applied to:
+ `%push',`%macro',`%imacro',`%define',`%idefine',`%xdefine',`%ixdefine',
+ `%assign',`%iassign',`%undef'
+
+ (*) A new directive [WARNING {+|-}warning-id] have been added. It
+ works only if the assembly phase is enabled (i.e. it doesn't
+ work with nasm -e).
+
+ (*) A new warning type: macro-selfref. By default this warning is
+ disabled; when enabled NASM warns when a macro self-references
+ itself; for example the following source:
+
+ [WARNING macro-selfref]
+
+ %macro push 1-*
+ %rep %0
+ push %1
+ %rotate 1
+ %endrep
+ %endmacro
+
+ push eax,ebx,ecx
+
+ will produce a warning, but if we remove the first line we won't see
+ it anymore (which is The Right Thing To Do {tm} IMHO since C
+ preprocessor eats such constructs without warnings at all).
+
+ (*) Added a "error" routine to preprocessor which always will set
+ ERR_PASS1 bit in severity_code. This removes annoying repeated
+ errors on first and second passes from preprocessor.
+
+ (*) Added the %+ operator in single-line macros for concatenating
+ two identifiers. Usage example:
+
+ %define _myfunc _otherfunc
+ %define cextern(x) _ %+ x
+ cextern (myfunc)
+
+ After first expansion, third line will become "_myfunc". After this
+ expansion is performed again so it becomes "_otherunc".
+
+ (*) Now if preprocessor is in a non-emitting state, no warning or
+ error will be emitted. Example:
+
+ %if 1
+ mov eax,ebx
+ %else
+ put anything you want between these two brackets,
+ even macro-parameter references %1 or local
+ labels %$zz or macro-local labels %%zz - no
+ warning will be emitted.
+ %endif
+
+ (*) Context-local variables on expansion as a last resort are looked
+ up in outer contexts. For example, the following piece:
+
+ %push outer
+ %define %$a [esp]
+
+ %push inner
+ %$a
+ %pop
+ %pop
+
+ will expand correctly the fourth line to [esp]; if we'll define
+ another %$a inside the "inner" context, it will take precedence over
+ outer definition. However, this modification has been applied only
+ to expand_smacro and not to smacro_define: as a consequence
+ expansion looks in outer contexts, but `%ifdef' won't look in outer
+ contexts.
+
+ This behaviour is needed because we don't want nested contexts to
+ act on already defined local macros. Example:
+
+ %define %$arg1 [esp+4]
+ test eax,eax
+ if nz
+ mov eax,%$arg1
+ endif
+
+ In this example the "if" mmacro enters into the "if" context, so
+ %$arg1 is not valid anymore inside "if". Of course it could be
+ worked around by using explicitely %$$arg1 but this is ugly IMHO.
+
+ (*) Fixed memory leak in `%undef'. The origline wasn't freed before
+ exiting on success.
+
+ (*) Fixed trap in preprocessor when line expanded to empty set of
+ tokens. This happens, for example, in the following case:
+
+ #define SOMETHING
+ SOMETHING
+
+C.2.41 Version 0.98
+
+ All changes since NASM 0.98p3 have been produced by H. Peter Anvin
+ <hpa@zytor.com>.
+
+ (*) The documentation comment delimiter is
+
+ (*) Allow EQU definitions to refer to external labels; reported by
+ Pedro Gimeno.
+
+ (*) Re-enable support for RDOFF v1; reported by Pedro Gimeno.
+
+ (*) Updated License file per OK from Simon and Julian.
+
+C.2.42 Version 0.98p9
+
+ (*) Update documentation (although the instruction set reference
+ will have to wait; I don't want to hold up the 0.98 release for
+ it.)
+
+ (*) Verified that the NASM implementation of the PEXTRW and PMOVMSKB
+ instructions is correct. The encoding differs from what the
+ Intel manuals document, but the Pentium III behaviour matches
+ NASM, not the Intel manuals.
+
+ (*) Fix handling of implicit sizes in PSHUFW and PINSRW, reported by
+ Stefan Hoffmeister.
+
+ (*) Resurrect the -s option, which was removed when changing the
+ diagnostic output to stdout.
+
+C.2.43 Version 0.98p8
+
+ (*) Fix for "DB" when NASM is running on a bigendian machine.
+
+ (*) Invoke insns.pl once for each output script, making Makefile.in
+ legal for "make -j".
+
+ (*) Improve the Unix configure-based makefiles to make package
+ creation easier.
+
+ (*) Included an RPM .spec file for building RPM (RedHat Package
+ Manager) packages on Linux or Unix systems.
+
+ (*) Fix Makefile dependency problems.
+
+ (*) Change src/rdsrc.pl to include sectioning information in info
+ output; required for install-info to work.
+
+ (*) Updated the RDOFF distribution to version 2 from Jules; minor
+ massaging to make it compile in my environment.
+
+ (*) Split doc files that can be built by anyone with a Perl
+ interpreter off into a separate archive.
+
+ (*) "Dress rehearsal" release!
+
+C.2.44 Version 0.98p7
+
+ (*) Fixed opcodes with a third byte-sized immediate argument to not
+ complain if given "byte" on the immediate.
+
+ (*) Allow `%undef' to remove single-line macros with arguments. This
+ matches the behaviour of #undef in the C preprocessor.
+
+ (*) Allow -d, -u, -i and -p to be specified as -D, -U, -I and -P for
+ compatibility with most C compilers and preprocessors. This
+ allows Makefile options to be shared between cc and nasm, for
+ example.
+
+ (*) Minor cleanups.
+
+ (*) Went through the list of Katmai instructions and hopefully fixed
+ the (rather few) mistakes in it.
+
+ (*) (Hopefully) fixed a number of disassembler bugs related to
+ ambiguous instructions (disambiguated by -p) and SSE
+ instructions with REP.
+
+ (*) Fix for bug reported by Mark Junger: "call dword 0x12345678"
+ should work and may add an OSP (affected CALL, JMP, Jcc).
+
+ (*) Fix for environments when "stderr" isn't a compile-time
+ constant.
+
+C.2.45 Version 0.98p6
+
+ (*) Took officially over coordination of the 0.98 release; so drop
+ the p3.x notation. Skipped p4 and p5 to avoid confusion with
+ John Fine's J4 and J5 releases.
+
+ (*) Update the documentation; however, it still doesn't include
+ documentation for the various new instructions. I somehow wonder
+ if it makes sense to have an instruction set reference in the
+ assembler manual when Intel et al have PDF versions of their
+ manuals online.
+
+ (*) Recognize "idt" or "centaur" for the -p option to ndisasm.
+
+ (*) Changed error messages back to stderr where they belong, but add
+ an -E option to redirect them elsewhere (the DOS shell cannot
+ redirect stderr.)
+
+ (*) -M option to generate Makefile dependencies (based on code from
+ Alex Verstak.)
+
+ (*) `%undef' preprocessor directive, and -u option, that undefines a
+ single-line macro.
+
+ (*) OS/2 Makefile (Mkfiles/Makefile.os2) for Borland under OS/2;
+ from Chuck Crayne.
+
+ (*) Various minor bugfixes (reported by): - Dangling `%s' in
+ preproc.c (Martin Junker)
+
+ (*) THERE ARE KNOWN BUGS IN SSE AND THE OTHER KATMAI INSTRUCTIONS. I
+ am on a trip and didn't bring the Katmai instruction reference,
+ so I can't work on them right now.
+
+ (*) Updated the License file per agreement with Simon and Jules to
+ include a GPL distribution clause.
+
+C.2.46 Version 0.98p3.7
+
+ (*) (Hopefully) fixed the canned Makefiles to include the outrdf2
+ and zoutieee modules.
+
+ (*) Renamed changes.asm to changed.asm.
+
+C.2.47 Version 0.98p3.6
+
+ (*) Fixed a bunch of instructions that were added in 0.98p3.5 which
+ had memory operands, and the address-size prefix was missing
+ from the instruction pattern.
+
+C.2.48 Version 0.98p3.5
+
+ (*) Merged in changes from John S. Fine's 0.98-J5 release. John's
+ based 0.98-J5 on my 0.98p3.3 release; this merges the changes.
+
+ (*) Expanded the instructions flag field to a long so we can fit
+ more flags; mark SSE (KNI) and AMD or Katmai-specific
+ instructions as such.
+
+ (*) Fix the "PRIV" flag on a bunch of instructions, and create new
+ "PROT" flag for protected-mode-only instructions (orthogonal to
+ if the instruction is privileged!) and new "SMM" flag for SMM-
+ only instructions.
+
+ (*) Added AMD-only SYSCALL and SYSRET instructions.
+
+ (*) Make SSE actually work, and add new Katmai MMX instructions.
+
+ (*) Added a -p (preferred vendor) option to ndisasm so that it can
+ distinguish e.g. Cyrix opcodes also used in SSE. For example:
+
+ ndisasm -p cyrix aliased.bin
+ 00000000 670F514310 paddsiw mm0,[ebx+0x10]
+ 00000005 670F514320 paddsiw mm0,[ebx+0x20]
+ ndisasm -p intel aliased.bin
+ 00000000 670F514310 sqrtps xmm0,[ebx+0x10]
+ 00000005 670F514320 sqrtps xmm0,[ebx+0x20]
+
+ (*) Added a bunch of Cyrix-specific instructions.
+
+C.2.49 Version 0.98p3.4
+
+ (*) Made at least an attempt to modify all the additional Makefiles
+ (in the Mkfiles directory). I can't test it, but this was the
+ best I could do.
+
+ (*) DOS DJGPP+"Opus Make" Makefile from John S. Fine.
+
+ (*) changes.asm changes from John S. Fine.
+
+C.2.50 Version 0.98p3.3
+
+ (*) Patch from Conan Brink to allow nesting of `%rep' directives.
+
+ (*) If we're going to allow INT01 as an alias for INT1/ICEBP (one of
+ Jules 0.98p3 changes), then we should allow INT03 as an alias
+ for INT3 as well.
+
+ (*) Updated changes.asm to include the latest changes.
+
+ (*) Tried to clean up the <CR>s that had snuck in from a DOS/Windows
+ environment into my Unix environment, and try to make sure than
+ DOS/Windows users get them back.
+
+ (*) We would silently generate broken tools if insns.dat wasn't
+ sorted properly. Change insns.pl so that the order doesn't
+ matter.
+
+ (*) Fix bug in insns.pl (introduced by me) which would cause
+ conditional instructions to have an extra "cc" in disassembly,
+ e.g. "jnz" disassembled as "jccnz".
+
+C.2.51 Version 0.98p3.2
+
+ (*) Merged in John S. Fine's changes from his 0.98-J4 prerelease;
+ see http://www.csoft.net/cz/johnfine/
+
+ (*) Changed previous "spotless" Makefile target (appropriate for
+ distribution) to "distclean", and added "cleaner" target which
+ is same as "clean" except deletes files generated by Perl
+ scripts; "spotless" is union.
+
+ (*) Removed BASIC programs from distribution. Get a Perl interpreter
+ instead (see below.)
+
+ (*) Calling this "pre-release 3.2" rather than "p3-hpa2" because of
+ John's contributions.
+
+ (*) Actually link in the IEEE output format (zoutieee.c); fix a
+ bunch of compiler warnings in that file. Note I don't know what
+ IEEE output is supposed to look like, so these changes were made
+ "blind".
+
+C.2.52 Version 0.98p3-hpa
+
+ (*) Merged nasm098p3.zip with nasm-0.97.tar.gz to create a fully
+ buildable version for Unix systems (Makefile.in updates, etc.)
+
+ (*) Changed insns.pl to create the instruction tables in nasm.h and
+ names.c, so that a new instruction can be added by adding it
+ *only* to insns.dat.
+
+ (*) Added the following new instructions: SYSENTER, SYSEXIT, FXSAVE,
+ FXRSTOR, UD1, UD2 (the latter two are two opcodes that Intel
+ guarantee will never be used; one of them is documented as UD2
+ in Intel documentation, the other one just as "Undefined Opcode"
+ -- calling it UD1 seemed to make sense.)
+
+ (*) MAX_SYMBOL was defined to be 9, but LOADALL286 and LOADALL386
+ are 10 characters long. Now MAX_SYMBOL is derived from
+ insns.dat.
+
+ (*) A note on the BASIC programs included: forget them. insns.bas is
+ already out of date. Get yourself a Perl interpreter for your
+ platform of choice at http://www.cpan.org/ports/index.html.
+
+C.2.53 Version 0.98 pre-release 3
+
+ (*) added response file support, improved command line handling, new
+ layout help screen
+
+ (*) fixed limit checking bug, 'OUT byte nn, reg' bug, and a couple
+ of rdoff related bugs, updated Wishlist; 0.98 Prerelease 3.
+
+C.2.54 Version 0.98 pre-release 2
+
+ (*) fixed bug in outcoff.c to do with truncating section names
+ longer than 8 characters, referencing beyond end of string; 0.98
+ pre-release 2
+
+C.2.55 Version 0.98 pre-release 1
+
+ (*) Fixed a bug whereby STRUC didn't work at all in RDF.
+
+ (*) Fixed a problem with group specification in PUBDEFs in OBJ.
+
+ (*) Improved ease of adding new output formats. Contribution due to
+ Fox Cutter.
+
+ (*) Fixed a bug in relocations in the `bin' format: was showing up
+ when a relocatable reference crossed an 8192-byte boundary in
+ any output section.
+
+ (*) Fixed a bug in local labels: local-label lookups were
+ inconsistent between passes one and two if an EQU occurred
+ between the definition of a global label and the subsequent use
+ of a local label local to that global.
+
+ (*) Fixed a seg-fault in the preprocessor (again) which happened
+ when you use a blank line as the first line of a multi-line
+ macro definition and then defined a label on the same line as a
+ call to that macro.
+
+ (*) Fixed a stale-pointer bug in the handling of the NASM
+ environment variable. Thanks to Thomas McWilliams.
+
+ (*) ELF had a hard limit on the number of sections which caused
+ segfaults when transgressed. Fixed.
+
+ (*) Added ability for ndisasm to read from stdin by using `-' as the
+ filename.
+
+ (*) ndisasm wasn't outputting the TO keyword. Fixed.
+
+ (*) Fixed error cascade on bogus expression in `%if' - an error in
+ evaluation was causing the entire `%if' to be discarded, thus
+ creating trouble later when the `%else' or `%endif' was
+ encountered.
+
+ (*) Forward reference tracking was instruction-granular not operand-
+ granular, which was causing 286-specific code to be generated
+ needlessly on code of the form `shr word [forwardref],1'. Thanks
+ to Jim Hague for sending a patch.
+
+ (*) All messages now appear on stdout, as sending them to stderr
+ serves no useful purpose other than to make redirection
+ difficult.
+
+ (*) Fixed the problem with EQUs pointing to an external symbol -
+ this now generates an error message.
+
+ (*) Allowed multiple size prefixes to an operand, of which only the
+ first is taken into account.
+
+ (*) Incorporated John Fine's changes, including fixes of a large
+ number of preprocessor bugs, some small problems in OBJ, and a
+ reworking of label handling to define labels before their line
+ is assembled, rather than after.
+
+ (*) Reformatted a lot of the source code to be more readable.
+ Included 'coding.txt' as a guideline for how to format code for
+ contributors.
+
+ (*) Stopped nested `%reps' causing a panic - they now cause a
+ slightly more friendly error message instead.
+
+ (*) Fixed floating point constant problems (patch by Pedro Gimeno)
+
+ (*) Fixed the return value of insn_size() not being checked for -1,
+ indicating an error.
+
+ (*) Incorporated 3Dnow! instructions.
+
+ (*) Fixed the 'mov eax, eax + ebx' bug.
+
+ (*) Fixed the GLOBAL EQU bug in ELF. Released developers release 3.
+
+ (*) Incorporated John Fine's command line parsing changes
+
+ (*) Incorporated David Lindauer's OMF debug support
+
+ (*) Made changes for LCC 4.0 support (`__NASM_CDecl__', removed
+ register size specification warning when sizes agree).
+
+ C.3 NASM 0.9 Series
+
+ Revisions before 0.98.
+
+ C.3.1 Version 0.97 released December 1997
+
+ (*) This was entirely a bug-fix release to 0.96, which seems to have
+ got cursed. Silly me.
+
+ (*) Fixed stupid mistake in OBJ which caused `MOV EAX,<constant>' to
+ fail. Caused by an error in the `MOV EAX,<segment>' support.
+
+ (*) ndisasm hung at EOF when compiled with lcc on Linux because lcc
+ on Linux somehow breaks feof(). ndisasm now does not rely on
+ feof().
+
+ (*) A heading in the documentation was missing due to a markup error
+ in the indexing. Fixed.
+
+ (*) Fixed failure to update all pointers on realloc() within
+ extended- operand code in parser.c. Was causing wrong behaviour
+ and seg faults on lines such as `dd 0.0,0.0,0.0,0.0,...'
+
+ (*) Fixed a subtle preprocessor bug whereby invoking one multi-line
+ macro on the first line of the expansion of another, when the
+ second had been invoked with a label defined before it, didn't
+ expand the inner macro.
+
+ (*) Added internal.doc back in to the distribution archives - it was
+ missing in 0.96 *blush*
+
+ (*) Fixed bug causing 0.96 to be unable to assemble its own test
+ files, specifically objtest.asm. *blush again*
+
+ (*) Fixed seg-faults and bogus error messages caused by mismatching
+ `%rep' and `%endrep' within multi-line macro definitions.
+
+ (*) Fixed a problem with buffer overrun in OBJ, which was causing
+ corruption at ends of long PUBDEF records.
+
+ (*) Separated DOS archives into main-program and documentation to
+ reduce download size.
+
+ C.3.2 Version 0.96 released November 1997
+
+ (*) Fixed a bug whereby, if `nasm sourcefile' would cause a filename
+ collision warning and put output into `nasm.out', then `nasm
+ sourcefile -o outputfile' still gave the warning even though the
+ `-o' was honoured. Fixed name pollution under Digital UNIX: one
+ of its header files defined R_SP, which broke the enum in
+ nasm.h.
+
+ (*) Fixed minor instruction table problems: FUCOM and FUCOMP didn't
+ have two-operand forms; NDISASM didn't recognise the longer
+ register forms of PUSH and POP (eg FF F3 for PUSH BX); TEST
+ mem,imm32 was flagged as undocumented; the 32-bit forms of CMOV
+ had 16-bit operand size prefixes; `AAD imm' and `AAM imm' are no
+ longer flagged as undocumented because the Intel Architecture
+ reference documents them.
+
+ (*) Fixed a problem with the local-label mechanism, whereby strange
+ types of symbol (EQUs, auto-defined OBJ segment base symbols)
+ interfered with the `previous global label' value and screwed up
+ local labels.
+
+ (*) Fixed a bug whereby the stub preprocessor didn't communicate
+ with the listing file generator, so that the -a and -l options
+ in conjunction would produce a useless listing file.
+
+ (*) Merged `os2' object file format back into `obj', after
+ discovering that `obj' _also_ shouldn't have a link pass
+ separator in a module containing a non-trivial MODEND. Flat
+ segments are now declared using the FLAT attribute. `os2' is no
+ longer a valid object format name: use `obj'.
+
+ (*) Removed the fixed-size temporary storage in the evaluator. Very
+ very long expressions (like `mov ax,1+1+1+1+...' for two hundred
+ 1s or so) should now no longer crash NASM.
+
+ (*) Fixed a bug involving segfaults on disassembly of MMX
+ instructions, by changing the meaning of one of the operand-type
+ flags in nasm.h. This may cause other apparently unrelated MMX
+ problems; it needs to be tested thoroughly.
+
+ (*) Fixed some buffer overrun problems with large OBJ output files.
+ Thanks to DJ Delorie for the bug report and fix.
+
+ (*) Made preprocess-only mode actually listen to the `%line' markers
+ as it prints them, so that it can report errors more sanely.
+
+ (*) Re-designed the evaluator to keep more sensible track of
+ expressions involving forward references: can now cope with
+ previously-nightmare situations such as:
+
+ mov ax,foo | bar
+ foo equ 1
+ bar equ 2
+
+ (*) Added the ALIGN and ALIGNB standard macros.
+
+ (*) Added PIC support in ELF: use of WRT to obtain the four extra
+ relocation types needed.
+
+ (*) Added the ability for output file formats to define their own
+ extensions to the GLOBAL, COMMON and EXTERN directives.
+
+ (*) Implemented common-variable alignment, and global-symbol type
+ and size declarations, in ELF.
+
+ (*) Implemented NEAR and FAR keywords for common variables, plus
+ far-common element size specification, in OBJ.
+
+ (*) Added a feature whereby EXTERNs and COMMONs in OBJ can be given
+ a default WRT specification (either a segment or a group).
+
+ (*) Transformed the Unix NASM archive into an auto-configuring
+ package.
+
+ (*) Added a sanity-check for people applying SEG to things which are
+ already segment bases: this previously went unnoticed by the SEG
+ processing and caused OBJ-driver panics later.
+
+ (*) Added the ability, in OBJ format, to deal with `MOV
+ EAX,<segment>' type references: OBJ doesn't directly support
+ dword-size segment base fixups, but as long as the low two bytes
+ of the constant term are zero, a word-size fixup can be
+ generated instead and it will work.
+
+ (*) Added the ability to specify sections' alignment requirements in
+ Win32 object files and pure binary files.
+
+ (*) Added preprocess-time expression evaluation: the `%assign' (and
+ `%iassign') directive and the bare `%if' (and `%elif')
+ conditional. Added relational operators to the evaluator, for
+ use only in `%if' constructs: the standard relationals = < > <=
+ >= <> (and C-like synonyms == and !=) plus low-precedence
+ logical operators &&, ^^ and ||.
+
+ (*) Added a preprocessor repeat construct: `%rep' / `%exitrep' /
+ `%endrep'.
+
+ (*) Added the __FILE__ and __LINE__ standard macros.
+
+ (*) Added a sanity check for number constants being greater than
+ 0xFFFFFFFF. The warning can be disabled.
+
+ (*) Added the %0 token whereby a variadic multi-line macro can tell
+ how many parameters it's been given in a specific invocation.
+
+ (*) Added `%rotate', allowing multi-line macro parameters to be
+ cycled.
+
+ (*) Added the `*' option for the maximum parameter count on multi-
+ line macros, allowing them to take arbitrarily many parameters.
+
+ (*) Added the ability for the user-level forms of EXTERN, GLOBAL and
+ COMMON to take more than one argument.
+
+ (*) Added the IMPORT and EXPORT directives in OBJ format, to deal
+ with Windows DLLs.
+
+ (*) Added some more preprocessor `%if' constructs: `%ifidn' /
+ `%ifidni' (exact textual identity), and `%ifid' / `%ifnum' /
+ `%ifstr' (token type testing).
+
+ (*) Added the ability to distinguish SHL AX,1 (the 8086 version)
+ from SHL AX,BYTE 1 (the 286-and-upwards version whose constant
+ happens to be 1).
+
+ (*) Added NetBSD/FreeBSD/OpenBSD's variant of a.out format, complete
+ with PIC shared library features.
+
+ (*) Changed NASM's idiosyncratic handling of FCLEX, FDISI, FENI,
+ FINIT, FSAVE, FSTCW, FSTENV, and FSTSW to bring it into line
+ with the otherwise accepted standard. The previous behaviour,
+ though it was a deliberate feature, was a deliberate feature
+ based on a misunderstanding. Apologies for the inconvenience.
+
+ (*) Improved the flexibility of ABSOLUTE: you can now give it an
+ expression rather than being restricted to a constant, and it
+ can take relocatable arguments as well.
+
+ (*) Added the ability for a variable to be declared as EXTERN
+ multiple times, and the subsequent definitions are just ignored.
+
+ (*) We now allow instruction prefixes (CS, DS, LOCK, REPZ etc) to be
+ alone on a line (without a following instruction).
+
+ (*) Improved sanity checks on whether the arguments to EXTERN,
+ GLOBAL and COMMON are valid identifiers.
+
+ (*) Added misc/exebin.mac to allow direct generation of .EXE files
+ by hacking up an EXE header using DB and DW; also added
+ test/binexe.asm to demonstrate the use of this. Thanks to Yann
+ Guidon for contributing the EXE header code.
+
+ (*) ndisasm forgot to check whether the input file had been
+ successfully opened. Now it does. Doh!
+
+ (*) Added the Cyrix extensions to the MMX instruction set.
+
+ (*) Added a hinting mechanism to allow [EAX+EBX] and [EBX+EAX] to be
+ assembled differently. This is important since [ESI+EBP] and
+ [EBP+ESI] have different default base segment registers.
+
+ (*) Added support for the PharLap OMF extension for 4096-byte
+ segment alignment.
+
+ C.3.3 Version 0.95 released July 1997
+
+ (*) Fixed yet another ELF bug. This one manifested if the user
+ relied on the default segment, and attempted to define global
+ symbols without first explicitly declaring the target segment.
+
+ (*) Added makefiles (for NASM and the RDF tools) to build Win32
+ console apps under Symantec C++. Donated by Mark Junker.
+
+ (*) Added `macros.bas' and `insns.bas', QBasic versions of the Perl
+ scripts that convert `standard.mac' to `macros.c' and convert
+ `insns.dat' to `insnsa.c' and `insnsd.c'. Also thanks to Mark
+ Junker.
+
+ (*) Changed the diassembled forms of the conditional instructions so
+ that JB is now emitted as JC, and other similar changes.
+ Suggested list by Ulrich Doewich.
+
+ (*) Added `@' to the list of valid characters to begin an identifier
+ with.
+
+ (*) Documentary changes, notably the addition of the `Common
+ Problems' section in nasm.doc.
+
+ (*) Fixed a bug relating to 32-bit PC-relative fixups in OBJ.
+
+ (*) Fixed a bug in perm_copy() in labels.c which was causing
+ exceptions in cleanup_labels() on some systems.
+
+ (*) Positivity sanity check in TIMES argument changed from a warning
+ to an error following a further complaint.
+
+ (*) Changed the acceptable limits on byte and word operands to allow
+ things like `~10111001b' to work.
+
+ (*) Fixed a major problem in the preprocessor which caused seg-
+ faults if macro definitions contained blank lines or comment-
+ only lines.
+
+ (*) Fixed inadequate error checking on the commas separating the
+ arguments to `db', `dw' etc.
+
+ (*) Fixed a crippling bug in the handling of macros with operand
+ counts defined with a `+' modifier.
+
+ (*) Fixed a bug whereby object file formats which stored the input
+ file name in the output file (such as OBJ and COFF) weren't
+ doing so correctly when the output file name was specified on
+ the command line.
+
+ (*) Removed [INC] and [INCLUDE] support for good, since they were
+ obsolete anyway.
+
+ (*) Fixed a bug in OBJ which caused all fixups to be output in 16-
+ bit (old-format) FIXUPP records, rather than putting the 32-bit
+ ones in FIXUPP32 (new-format) records.
+
+ (*) Added, tentatively, OS/2 object file support (as a minor variant
+ on OBJ).
+
+ (*) Updates to Fox Cutter's Borland C makefile, Makefile.bc2.
+
+ (*) Removed a spurious second fclose() on the output file.
+
+ (*) Added the `-s' command line option to redirect all messages
+ which would go to stderr (errors, help text) to stdout instead.
+
+ (*) Added the `-w' command line option to selectively suppress some
+ classes of assembly warning messages.
+
+ (*) Added the `-p' pre-include and `-d' pre-define command-line
+ options.
+
+ (*) Added an include file search path: the `-i' command line option.
+
+ (*) Fixed a silly little preprocessor bug whereby starting a line
+ with a `%!' environment-variable reference caused an `unknown
+ directive' error.
+
+ (*) Added the long-awaited listing file support: the `-l' command
+ line option.
+
+ (*) Fixed a problem with OBJ format whereby, in the absence of any
+ explicit segment definition, non-global symbols declared in the
+ implicit default segment generated spurious EXTDEF records in
+ the output.
+
+ (*) Added the NASM environment variable.
+
+ (*) From this version forward, Win32 console-mode binaries will be
+ included in the DOS distribution in addition to the 16-bit
+ binaries. Added Makefile.vc for this purpose.
+
+ (*) Added `return 0;' to test/objlink.c to prevent compiler
+ warnings.
+
+ (*) Added the __NASM_MAJOR__ and __NASM_MINOR__ standard defines.
+
+ (*) Added an alternative memory-reference syntax in which prefixing
+ an operand with `&' is equivalent to enclosing it in square
+ brackets, at the request of Fox Cutter.
+
+ (*) Errors in pass two now cause the program to return a non-zero
+ error code, which they didn't before.
+
+ (*) Fixed the single-line macro cycle detection, which didn't work
+ at all on macros with no parameters (caused an infinite loop).
+ Also changed the behaviour of single-line macro cycle detection
+ to work like cpp, so that macros like `extrn' as given in the
+ documentation can be implemented.
+
+ (*) Fixed the implementation of WRT, which was too restrictive in
+ that you couldn't do `mov ax,[di+abc wrt dgroup]' because
+ (di+abc) wasn't a relocatable reference.
+
+ C.3.4 Version 0.94 released April 1997
+
+ (*) Major item: added the macro processor.
+
+ (*) Added undocumented instructions SMI, IBTS, XBTS and LOADALL286.
+ Also reorganised CMPXCHG instruction into early-486 and Pentium
+ forms. Thanks to Thobias Jones for the information.
+
+ (*) Fixed two more stupid bugs in ELF, which were causing `ld' to
+ continue to seg-fault in a lot of non-trivial cases.
+
+ (*) Fixed a seg-fault in the label manager.
+
+ (*) Stopped FBLD and FBSTP from _requiring_ the TWORD keyword, which
+ is the only option for BCD loads/stores in any case.
+
+ (*) Ensured FLDCW, FSTCW and FSTSW can cope with the WORD keyword,
+ if anyone bothers to provide it. Previously they complained
+ unless no keyword at all was present.
+
+ (*) Some forms of FDIV/FDIVR and FSUB/FSUBR were still inverted: a
+ vestige of a bug that I thought had been fixed in 0.92. This was
+ fixed, hopefully for good this time...
+
+ (*) Another minor phase error (insofar as a phase error can _ever_
+ be minor) fixed, this one occurring in code of the form
+
+ rol ax,forward_reference
+ forward_reference equ 1
+
+ (*) The number supplied to TIMES is now sanity-checked for
+ positivity, and also may be greater than 64K (which previously
+ didn't work on 16-bit systems).
+
+ (*) Added Watcom C makefiles, and misc/pmw.bat, donated by Dominik
+ Behr.
+
+ (*) Added the INCBIN pseudo-opcode.
+
+ (*) Due to the advent of the preprocessor, the [INCLUDE] and [INC]
+ directives have become obsolete. They are still supported in
+ this version, with a warning, but won't be in the next.
+
+ (*) Fixed a bug in OBJ format, which caused incorrect object records
+ to be output when absolute labels were made global.
+
+ (*) Updates to RDOFF subdirectory, and changes to outrdf.c.
+
+ C.3.5 Version 0.93 released January 1997
+
+ This release went out in a great hurry after semi-crippling bugs
+ were found in 0.92.
+
+ (*) Really _did_ fix the stack overflows this time. *blush*
+
+ (*) Had problems with EA instruction sizes changing between passes,
+ when an offset contained a forward reference and so 4 bytes were
+ allocated for the offset in pass one; by pass two the symbol had
+ been defined and happened to be a small absolute value, so only
+ 1 byte got allocated, causing instruction size mismatch between
+ passes and hence incorrect address calculations. Fixed.
+
+ (*) Stupid bug in the revised ELF section generation fixed
+ (associated string-table section for .symtab was hard-coded as
+ 7, even when this didn't fit with the real section table). Was
+ causing `ld' to seg-fault under Linux.
+
+ (*) Included a new Borland C makefile, Makefile.bc2, donated by Fox
+ Cutter <lmb@comtch.iea.com>.
+
+ C.3.6 Version 0.92 released January 1997
+
+ (*) The FDIVP/FDIVRP and FSUBP/FSUBRP pairs had been inverted: this
+ was fixed. This also affected the LCC driver.
+
+ (*) Fixed a bug regarding 32-bit effective addresses of the form
+ `[other_register+ESP]'.
+
+ (*) Documentary changes, notably documentation of the fact that
+ Borland Win32 compilers use `obj' rather than `win32' object
+ format.
+
+ (*) Fixed the COMENT record in OBJ files, which was formatted
+ incorrectly.
+
+ (*) Fixed a bug causing segfaults in large RDF files.
+
+ (*) OBJ format now strips initial periods from segment and group
+ definitions, in order to avoid complications with the local
+ label syntax.
+
+ (*) Fixed a bug in disassembling far calls and jumps in NDISASM.
+
+ (*) Added support for user-defined sections in COFF and ELF files.
+
+ (*) Compiled the DOS binaries with a sensible amount of stack, to
+ prevent stack overflows on any arithmetic expression containing
+ parentheses.
+
+ (*) Fixed a bug in handling of files that do not terminate in a
+ newline.
+
+ C.3.7 Version 0.91 released November 1996
+
+ (*) Loads of bug fixes.
+
+ (*) Support for RDF added.
+
+ (*) Support for DBG debugging format added.
+
+ (*) Support for 32-bit extensions to Microsoft OBJ format added.
+
+ (*) Revised for Borland C: some variable names changed, makefile
+ added.
+
+ (*) LCC support revised to actually work.
+
+ (*) JMP/CALL NEAR/FAR notation added.
+
+ (*) `a16', `o16', `a32' and `o32' prefixes added.
+
+ (*) Range checking on short jumps implemented.
+
+ (*) MMX instruction support added.
+
+ (*) Negative floating point constant support added.
+
+ (*) Memory handling improved to bypass 64K barrier under DOS.
+
+ (*) `$' prefix to force treatment of reserved words as identifiers
+ added.
+
+ (*) Default-size mechanism for object formats added.
+
+ (*) Compile-time configurability added.
+
+ (*) `#', `@', `~' and c{?} are now valid characters in labels.
+
+ (*) `-e' and `-k' options in NDISASM added.
+
+ C.3.8 Version 0.90 released October 1996
+
+ First release version. First support for object file output. Other
+ changes from previous version (0.3x) too numerous to document.