changed svn layout

git-svn-id: svn://ultimatepp.org/upp/trunk@281 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
mdelfede 2008-06-07 22:31:27 +00:00
commit 263ff5f895
2665 changed files with 642923 additions and 0 deletions

View file

@ -0,0 +1,4 @@
#ifndef _plugin_ndisasm_icpp_init_stub
#define _plugin_ndisasm_icpp_init_stub
#include "Core/init"
#endif

View file

@ -0,0 +1,119 @@
This is the AUTHORS file for the NASM project located at:
http://nasm.2y.net/
Names should be inserted as follows:
N: Name Here
E: Email Here
D: Description Here
D: Additional Description Here.... and so on
Such is life.
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
N: Julian Hall
E: Jules@acris.co.uk
D: Original author and co-conspirator
N: Simon Tatham
E: anakin@pobox.com
D: Original author and co-conspirator
N: Nelson Rush
E: palisade@users.sourceforge.net
D: Some guy.
N: Frank Kotler
E: fbkotler@nettaxi.com
D: Bug smashing.
D: Documentation - "KATMAI" and "3DNow!" instructions supported by 0.98
D: General coordination and moral support.
N: Stephen Silver
E: nasm@argentum.freeserve.co.uk
D: Documentation - "3dNow!" instructions and misc.
D: insns.dat fixes and new instructions.
N: AMD Inc. (names of developers here?)
E:
D: 3DNow instructions
D: New Athlon instructions
D: Makefile.vc fix
N: John Coffman
E: johninsd@users.sourceforge.net
D: added Jcc optimizations; CPU level checks
D: bug fixes, compilation fixes
N: Yuri Zaporogets
E: yuriz@users.sourceforge.net
D: RDOFF support
N: H. Peter Anvin
E: hpa@zytor.com
D: Organized 0.98 release and Linux binaries; new CVS tree.
N: John Fine
E: johnfine@earthlink.net
D: Preprocessor and OBJ (OMF) output format driver
D: Organized DOS versions of 0.98 release
N: Kendall Bennet
E: KendallB@scitechsoft.com
D: NASM enhancements
D: macros
D: Syntax modifications
N: Gary Clark
E:
D: AMD 3DNow! instructions
N: Andrew Crabtree
E:
D: Debugging support
N: Rafael R. Sevilla
E: dido@pacific.net.ph
D: RDF2HEX utility
N: Jaime Tejedor Gómez, aka Metalbrain
E: metalbrain_coder@gmx.net
D: jecxz bug fix
N: James Seter
E: pharos@zsnes.com
D: --POSTFIX, --PREFIX switches
D: ?
N: Edward J. Beroset
E: beroset@mindspring.com
D: added %substr and %strlen
N: Stanislav Karchebny, aka berkus, madfire, daemonhunter
E: madfire@users.sourceforge.net
D: multiple sections support for -fbin format
D: cvs maintenance
D: webpage at http://nasm.2y.net maintenance
N: Debbie Wiles, aka debs
E: debs@dwiles.demon.co.uk
D: Work on docs, added undocumented instructions (esp SSE2 and 3D-Now!)
D: Added other documentation and tidied up docs
D: Added a few instructions to insns.dat and tidied it up.
N: Trevor Woerner
E: FIXME
D: Quiet compiler warnings
N: Michael K. Ter Louw
E: mterlo1 "at" uic "dot" edu
D: Multisection support for "-f bin"
N: Martin Wawro
E: FIXME
D: stabs debug support for "-f elf"
N: Alexei Frounze
E: alexfru@users.sourceforge.net
D: "-I" paths searched for "incbined" files
D: bugswatting

View file

@ -0,0 +1,462 @@
GNU LESSER GENERAL PUBLIC LICENSE
Version 2.1, February 1999
Copyright (C) 1991, 1999 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
[This is the first released version of the Lesser GPL. It also counts
as the successor of the GNU Library Public License, version 2, hence
the version number 2.1.]
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
Licenses are intended to guarantee your freedom to share and change
free software--to make sure the software is free for all its users.
This license, the Lesser General Public License, applies to some
specially designated software packages--typically libraries--of the
Free Software Foundation and other authors who decide to use it. You
can use it too, but we suggest you first think carefully about whether
this license or the ordinary General Public License is the better
strategy to use in any particular case, based on the explanations
below.
When we speak of free software, we are referring to freedom of use,
not price. Our General Public Licenses are designed to make sure that
you have the freedom to distribute copies of free software (and charge
for this service if you wish); that you receive source code or can get
it if you want it; that you can change the software and use pieces of
it in new free programs; and that you are informed that you can do
these things.
To protect your rights, we need to make restrictions that forbid
distributors to deny you these rights or to ask you to surrender these
rights. These restrictions translate to certain responsibilities for
you if you distribute copies of the library or if you modify it.
For example, if you distribute copies of the library, whether gratis
or for a fee, you must give the recipients all the rights that we gave
you. You must make sure that they, too, receive or can get the source
code. If you link other code with the library, you must provide
complete object files to the recipients, so that they can relink them
with the library after making changes to the library and recompiling
it. And you must show them these terms so they know their rights.
We protect your rights with a two-step method: (1) we copyright the
library, and (2) we offer you this license, which gives you legal
permission to copy, distribute and/or modify the library.
To protect each distributor, we want to make it very clear that
there is no warranty for the free library. Also, if the library is
modified by someone else and passed on, the recipients should know
that what they have is not the original version, so that the original
author's reputation will not be affected by problems that might be
introduced by others.
^L
Finally, software patents pose a constant threat to the existence of
any free program. We wish to make sure that a company cannot
effectively restrict the users of a free program by obtaining a
restrictive license from a patent holder. Therefore, we insist that
any patent license obtained for a version of the library must be
consistent with the full freedom of use specified in this license.
Most GNU software, including some libraries, is covered by the
ordinary GNU General Public License. This license, the GNU Lesser
General Public License, applies to certain designated libraries, and
is quite different from the ordinary General Public License. We use
this license for certain libraries in order to permit linking those
libraries into non-free programs.
When a program is linked with a library, whether statically or using
a shared library, the combination of the two is legally speaking a
combined work, a derivative of the original library. The ordinary
General Public License therefore permits such linking only if the
entire combination fits its criteria of freedom. The Lesser General
Public License permits more lax criteria for linking other code with
the library.
We call this license the "Lesser" General Public License because it
does Less to protect the user's freedom than the ordinary General
Public License. It also provides other free software developers Less
of an advantage over competing non-free programs. These disadvantages
are the reason we use the ordinary General Public License for many
libraries. However, the Lesser license provides advantages in certain
special circumstances.
For example, on rare occasions, there may be a special need to
encourage the widest possible use of a certain library, so that it
becomes a de-facto standard. To achieve this, non-free programs must
be allowed to use the library. A more frequent case is that a free
library does the same job as widely used non-free libraries. In this
case, there is little to gain by limiting the free library to free
software only, so we use the Lesser General Public License.
In other cases, permission to use a particular library in non-free
programs enables a greater number of people to use a large body of
free software. For example, permission to use the GNU C Library in
non-free programs enables many more people to use the whole GNU
operating system, as well as its variant, the GNU/Linux operating
system.
Although the Lesser General Public License is Less protective of the
users' freedom, it does ensure that the user of a program that is
linked with the Library has the freedom and the wherewithal to run
that program using a modified version of the Library.
The precise terms and conditions for copying, distribution and
modification follow. Pay close attention to the difference between a
"work based on the library" and a "work that uses the library". The
former contains code derived from the library, whereas the latter must
be combined with the library in order to run.
^L
GNU LESSER GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any software library or other
program which contains a notice placed by the copyright holder or
other authorized party saying it may be distributed under the terms of
this Lesser General Public License (also called "this License").
Each licensee is addressed as "you".
A "library" means a collection of software functions and/or data
prepared so as to be conveniently linked with application programs
(which use some of those functions and data) to form executables.
The "Library", below, refers to any such software library or work
which has been distributed under these terms. A "work based on the
Library" means either the Library or any derivative work under
copyright law: that is to say, a work containing the Library or a
portion of it, either verbatim or with modifications and/or translated
straightforwardly into another language. (Hereinafter, translation is
included without limitation in the term "modification".)
"Source code" for a work means the preferred form of the work for
making modifications to it. For a library, complete source code means
all the source code for all modules it contains, plus any associated
interface definition files, plus the scripts used to control
compilation and installation of the library.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running a program using the Library is not restricted, and output from
such a program is covered only if its contents constitute a work based
on the Library (independent of the use of the Library in a tool for
writing it). Whether that is true depends on what the Library does
and what the program that uses the Library does.
1. You may copy and distribute verbatim copies of the Library's
complete source code as you receive it, in any medium, provided that
you conspicuously and appropriately publish on each copy an
appropriate copyright notice and disclaimer of warranty; keep intact
all the notices that refer to this License and to the absence of any
warranty; and distribute a copy of this License along with the
Library.
You may charge a fee for the physical act of transferring a copy,
and you may at your option offer warranty protection in exchange for a
fee.
2. You may modify your copy or copies of the Library or any portion
of it, thus forming a work based on the Library, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) The modified work must itself be a software library.
b) You must cause the files modified to carry prominent notices
stating that you changed the files and the date of any change.
c) You must cause the whole of the work to be licensed at no
charge to all third parties under the terms of this License.
d) If a facility in the modified Library refers to a function or a
table of data to be supplied by an application program that uses
the facility, other than as an argument passed when the facility
is invoked, then you must make a good faith effort to ensure that,
in the event an application does not supply such function or
table, the facility still operates, and performs whatever part of
its purpose remains meaningful.
(For example, a function in a library to compute square roots has
a purpose that is entirely well-defined independent of the
application. Therefore, Subsection 2d requires that any
application-supplied function or table used by this function must
be optional: if the application does not supply it, the square
root function must still compute square roots.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Library,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Library, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote
it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Library.
In addition, mere aggregation of another work not based on the Library
with the Library (or with a work based on the Library) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may opt to apply the terms of the ordinary GNU General Public
License instead of this License to a given copy of the Library. To do
this, you must alter all the notices that refer to this License, so
that they refer to the ordinary GNU General Public License, version 2,
instead of to this License. (If a newer version than version 2 of the
ordinary GNU General Public License has appeared, then you can specify
that version instead if you wish.) Do not make any other change in
these notices.
^L
Once this change is made in a given copy, it is irreversible for
that copy, so the ordinary GNU General Public License applies to all
subsequent copies and derivative works made from that copy.
This option is useful when you wish to copy part of the code of
the Library into a program that is not a library.
4. You may copy and distribute the Library (or a portion or
derivative of it, under Section 2) in object code or executable form
under the terms of Sections 1 and 2 above provided that you accompany
it with the complete corresponding machine-readable source code, which
must be distributed under the terms of Sections 1 and 2 above on a
medium customarily used for software interchange.
If distribution of object code is made by offering access to copy
from a designated place, then offering equivalent access to copy the
source code from the same place satisfies the requirement to
distribute the source code, even though third parties are not
compelled to copy the source along with the object code.
5. A program that contains no derivative of any portion of the
Library, but is designed to work with the Library by being compiled or
linked with it, is called a "work that uses the Library". Such a
work, in isolation, is not a derivative work of the Library, and
therefore falls outside the scope of this License.
However, linking a "work that uses the Library" with the Library
creates an executable that is a derivative of the Library (because it
contains portions of the Library), rather than a "work that uses the
library". The executable is therefore covered by this License.
Section 6 states terms for distribution of such executables.
When a "work that uses the Library" uses material from a header file
that is part of the Library, the object code for the work may be a
derivative work of the Library even though the source code is not.
Whether this is true is especially significant if the work can be
linked without the Library, or if the work is itself a library. The
threshold for this to be true is not precisely defined by law.
If such an object file uses only numerical parameters, data
structure layouts and accessors, and small macros and small inline
functions (ten lines or less in length), then the use of the object
file is unrestricted, regardless of whether it is legally a derivative
work. (Executables containing this object code plus portions of the
Library will still fall under Section 6.)
Otherwise, if the work is a derivative of the Library, you may
distribute the object code for the work under the terms of Section 6.
Any executables containing that work also fall under Section 6,
whether or not they are linked directly with the Library itself.
^L
6. As an exception to the Sections above, you may also combine or
link a "work that uses the Library" with the Library to produce a
work containing portions of the Library, and distribute that work
under terms of your choice, provided that the terms permit
modification of the work for the customer's own use and reverse
engineering for debugging such modifications.
You must give prominent notice with each copy of the work that the
Library is used in it and that the Library and its use are covered by
this License. You must supply a copy of this License. If the work
during execution displays copyright notices, you must include the
copyright notice for the Library among them, as well as a reference
directing the user to the copy of this License. Also, you must do one
of these things:
a) Accompany the work with the complete corresponding
machine-readable source code for the Library including whatever
changes were used in the work (which must be distributed under
Sections 1 and 2 above); and, if the work is an executable linked
with the Library, with the complete machine-readable "work that
uses the Library", as object code and/or source code, so that the
user can modify the Library and then relink to produce a modified
executable containing the modified Library. (It is understood
that the user who changes the contents of definitions files in the
Library will not necessarily be able to recompile the application
to use the modified definitions.)
b) Use a suitable shared library mechanism for linking with the
Library. A suitable mechanism is one that (1) uses at run time a
copy of the library already present on the user's computer system,
rather than copying library functions into the executable, and (2)
will operate properly with a modified version of the library, if
the user installs one, as long as the modified version is
interface-compatible with the version that the work was made with.
c) Accompany the work with a written offer, valid for at least
three years, to give the same user the materials specified in
Subsection 6a, above, for a charge no more than the cost of
performing this distribution.
d) If distribution of the work is made by offering access to copy
from a designated place, offer equivalent access to copy the above
specified materials from the same place.
e) Verify that the user has already received a copy of these
materials or that you have already sent this user a copy.
For an executable, the required form of the "work that uses the
Library" must include any data and utility programs needed for
reproducing the executable from it. However, as a special exception,
the materials to be distributed need not include anything that is
normally distributed (in either source or binary form) with the major
components (compiler, kernel, and so on) of the operating system on
which the executable runs, unless that component itself accompanies
the executable.
It may happen that this requirement contradicts the license
restrictions of other proprietary libraries that do not normally
accompany the operating system. Such a contradiction means you cannot
use both them and the Library together in an executable that you
distribute.
^L
7. You may place library facilities that are a work based on the
Library side-by-side in a single library together with other library
facilities not covered by this License, and distribute such a combined
library, provided that the separate distribution of the work based on
the Library and of the other library facilities is otherwise
permitted, and provided that you do these two things:
a) Accompany the combined library with a copy of the same work
based on the Library, uncombined with any other library
facilities. This must be distributed under the terms of the
Sections above.
b) Give prominent notice with the combined library of the fact
that part of it is a work based on the Library, and explaining
where to find the accompanying uncombined form of the same work.
8. You may not copy, modify, sublicense, link with, or distribute
the Library except as expressly provided under this License. Any
attempt otherwise to copy, modify, sublicense, link with, or
distribute the Library is void, and will automatically terminate your
rights under this License. However, parties who have received copies,
or rights, from you under this License will not have their licenses
terminated so long as such parties remain in full compliance.
9. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Library or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Library (or any work based on the
Library), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Library or works based on it.
10. Each time you redistribute the Library (or any work based on the
Library), the recipient automatically receives a license from the
original licensor to copy, distribute, link with or modify the Library
subject to these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties with
this License.
^L
11. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Library at all. For example, if a patent
license would not permit royalty-free redistribution of the Library by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Library.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply, and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
12. If the distribution and/or use of the Library is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Library under this License
may add an explicit geographical distribution limitation excluding those
countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
13. The Free Software Foundation may publish revised and/or new
versions of the Lesser General Public License from time to time.
Such new versions will be similar in spirit to the present version,
but may differ in detail to address new problems or concerns.
Each version is given a distinguishing version number. If the Library
specifies a version number of this License which applies to it and
"any later version", you have the option of following the terms and
conditions either of that version or of any later version published by
the Free Software Foundation. If the Library does not specify a
license version number, you may choose any version ever published by
the Free Software Foundation.
^L
14. If you wish to incorporate parts of the Library into other free
programs whose distribution conditions are incompatible with these,
write to the author to ask for permission. For software which is
copyrighted by the Free Software Foundation, write to the Free
Software Foundation; we sometimes make exceptions for this. Our
decision will be guided by the two goals of preserving the free status
of all derivatives of our free software and of promoting the sharing
and reuse of software generally.
NO WARRANTY
15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
DAMAGES.
END OF TERMS AND CONDITIONS
^L

View file

@ -0,0 +1,21 @@
NASM, the Netwide Assembler.
Many many developers all over the net respect NASM for what it is
- a widespread (thus netwide), portable (thus netwide!), very
flexible and mature assembler tool with support for many output
formats (thus netwide!!).
Now we have good news for you: NASM is licensed under LGPL.
This means its development is open to even wider society of
programmers wishing to improve their lovely assembler.
The NASM project is now situated at SourceForge.net, the most
famous Open Source development center on The Net.
Visit our development page at http://nasm.2y.net/ and our
SF project at http://sf.net/projects/nasm/
See the file CHANGES for the description of changes between revisions.
With best regards,
NASM crew.

View file

@ -0,0 +1,750 @@
/* disasm.c where all the _work_ gets done in the Netwide Disassembler
*
* The Netwide Assembler is copyright (C) 1996 Simon Tatham and
* Julian Hall. All rights reserved. The software is
* redistributable under the licence given in the file "Licence"
* distributed in the NASM archive.
*
* initial version 27/iii/95 by Simon Tatham
*/
#define _CRT_SECURE_NO_DEPRECATE
#include <stdio.h>
#include <string.h>
#include "nasm.h"
#include "disasm.h"
#include "sync.h"
#include "insns.h"
#include "names.c"
extern struct itemplate **itable[];
/*
* Flags that go into the `segment' field of `insn' structures
* during disassembly.
*/
#define SEG_RELATIVE 1
#define SEG_32BIT 2
#define SEG_RMREG 4
#define SEG_DISP8 8
#define SEG_DISP16 16
#define SEG_DISP32 32
#define SEG_NODISP 64
#define SEG_SIGNED 128
static int whichreg(long regflags, int regval)
{
#include "regdis.c"
if (!(REG_AL & ~regflags))
return R_AL;
if (!(REG_AX & ~regflags))
return R_AX;
if (!(REG_EAX & ~regflags))
return R_EAX;
if (!(REG_DL & ~regflags))
return R_DL;
if (!(REG_DX & ~regflags))
return R_DX;
if (!(REG_EDX & ~regflags))
return R_EDX;
if (!(REG_CL & ~regflags))
return R_CL;
if (!(REG_CX & ~regflags))
return R_CX;
if (!(REG_ECX & ~regflags))
return R_ECX;
if (!(FPU0 & ~regflags))
return R_ST0;
if (!(REG_CS & ~regflags))
return (regval == 1) ? R_CS : 0;
if (!(REG_DESS & ~regflags))
return (regval == 0 || regval == 2 || regval == 3 ? sreg[regval] : 0);
if (!(REG_FSGS & ~regflags))
return (regval == 4 || regval == 5 ? sreg[regval] : 0);
if (!(REG_SEG67 & ~regflags))
return (regval == 6 || regval == 7 ? sreg[regval] : 0);
/* All the entries below look up regval in an 8-entry array */
if (regval < 0 || regval > 7)
return 0;
if (!((REGMEM|BITS8) & ~regflags))
return reg8[regval];
if (!((REGMEM|BITS16) & ~regflags))
return reg16[regval];
if (!((REGMEM|BITS32) & ~regflags))
return reg32[regval];
if (!(REG_SREG & ~regflags))
return sreg[regval];
if (!(REG_CREG & ~regflags))
return creg[regval];
if (!(REG_DREG & ~regflags))
return dreg[regval];
if (!(REG_TREG & ~regflags))
return treg[regval];
if (!(FPUREG & ~regflags))
return fpureg[regval];
if (!(MMXREG & ~regflags))
return mmxreg[regval];
if (!(XMMREG & ~regflags))
return xmmreg[regval];
return 0;
}
static const char *whichcond(int condval)
{
static int conds[] = {
C_O, C_NO, C_C, C_NC, C_Z, C_NZ, C_NA, C_A,
C_S, C_NS, C_PE, C_PO, C_L, C_NL, C_NG, C_G
};
return conditions[conds[condval]];
}
/*
* Process an effective address (ModRM) specification.
*/
static unsigned char *do_ea (unsigned char *data, int modrm, int asize,
int segsize, operand *op)
{
int mod, rm, scale, index, base;
mod = (modrm >> 6) & 03;
rm = modrm & 07;
if (mod == 3) { /* pure register version */
op->basereg = rm;
op->segment |= SEG_RMREG;
return data;
}
op->addr_size = 0;
if (asize == 16) {
/*
* <mod> specifies the displacement size (none, byte or
* word), and <rm> specifies the register combination.
* Exception: mod=0,rm=6 does not specify [BP] as one might
* expect, but instead specifies [disp16].
*/
op->indexreg = op->basereg = -1;
op->scale = 1; /* always, in 16 bits */
switch (rm) {
case 0: op->basereg = R_BX; op->indexreg = R_SI; break;
case 1: op->basereg = R_BX; op->indexreg = R_DI; break;
case 2: op->basereg = R_BP; op->indexreg = R_SI; break;
case 3: op->basereg = R_BP; op->indexreg = R_DI; break;
case 4: op->basereg = R_SI; break;
case 5: op->basereg = R_DI; break;
case 6: op->basereg = R_BP; break;
case 7: op->basereg = R_BX; break;
}
if (rm == 6 && mod == 0) { /* special case */
op->basereg = -1;
if (segsize != 16)
op->addr_size = 16;
mod = 2; /* fake disp16 */
}
switch (mod) {
case 0:
op->segment |= SEG_NODISP;
break;
case 1:
op->segment |= SEG_DISP8;
op->offset = (signed char) *data++;
break;
case 2:
op->segment |= SEG_DISP16;
op->offset = *data++;
op->offset |= ((unsigned) *data++) << 8;
break;
}
return data;
} else {
/*
* Once again, <mod> specifies displacement size (this time
* none, byte or *dword*), while <rm> specifies the base
* register. Again, [EBP] is missing, replaced by a pure
* disp32 (this time that's mod=0,rm=*5*). However, rm=4
* indicates not a single base register, but instead the
* presence of a SIB byte...
*/
op->indexreg = -1;
switch (rm) {
case 0: op->basereg = R_EAX; break;
case 1: op->basereg = R_ECX; break;
case 2: op->basereg = R_EDX; break;
case 3: op->basereg = R_EBX; break;
case 5: op->basereg = R_EBP; break;
case 6: op->basereg = R_ESI; break;
case 7: op->basereg = R_EDI; break;
}
if (rm == 5 && mod == 0) {
op->basereg = -1;
if (segsize != 32)
op->addr_size = 32;
mod = 2; /* fake disp32 */
}
if (rm == 4) { /* process SIB */
scale = (*data >> 6) & 03;
index = (*data >> 3) & 07;
base = *data & 07;
data++;
op->scale = 1 << scale;
switch (index) {
case 0: op->indexreg = R_EAX; break;
case 1: op->indexreg = R_ECX; break;
case 2: op->indexreg = R_EDX; break;
case 3: op->indexreg = R_EBX; break;
case 4: op->indexreg = -1; break;
case 5: op->indexreg = R_EBP; break;
case 6: op->indexreg = R_ESI; break;
case 7: op->indexreg = R_EDI; break;
}
switch (base) {
case 0: op->basereg = R_EAX; break;
case 1: op->basereg = R_ECX; break;
case 2: op->basereg = R_EDX; break;
case 3: op->basereg = R_EBX; break;
case 4: op->basereg = R_ESP; break;
case 6: op->basereg = R_ESI; break;
case 7: op->basereg = R_EDI; break;
case 5:
if (mod == 0) {
mod = 2;
op->basereg = -1;
} else
op->basereg = R_EBP;
break;
}
}
switch (mod) {
case 0:
op->segment |= SEG_NODISP;
break;
case 1:
op->segment |= SEG_DISP8;
op->offset = (signed char) *data++;
break;
case 2:
op->segment |= SEG_DISP32;
op->offset = *data++;
op->offset |= ((unsigned) *data++) << 8;
op->offset |= ((long) *data++) << 16;
op->offset |= ((long) *data++) << 24;
break;
}
return data;
}
}
/*
* Determine whether the instruction template in t corresponds to the data
* stream in data. Return the number of bytes matched if so.
*/
static int matches (struct itemplate *t, unsigned char *data, int asize,
int osize, int segsize, int rep, insn *ins)
{
unsigned char * r = (unsigned char *)(t->code);
unsigned char * origdata = data;
int a_used = FALSE, o_used = FALSE;
int drep = 0;
if ( rep == 0xF2 )
drep = P_REPNE;
else if ( rep == 0xF3 )
drep = P_REP;
while (*r)
{
int c = *r++;
if (c >= 01 && c <= 03) {
while (c--)
if (*r++ != *data++)
return FALSE;
}
if (c == 04) {
switch (*data++) {
case 0x07: ins->oprs[0].basereg = 0; break;
case 0x17: ins->oprs[0].basereg = 2; break;
case 0x1F: ins->oprs[0].basereg = 3; break;
default: return FALSE;
}
}
if (c == 05) {
switch (*data++) {
case 0xA1: ins->oprs[0].basereg = 4; break;
case 0xA9: ins->oprs[0].basereg = 5; break;
default: return FALSE;
}
}
if (c == 06) {
switch (*data++) {
case 0x06: ins->oprs[0].basereg = 0; break;
case 0x0E: ins->oprs[0].basereg = 1; break;
case 0x16: ins->oprs[0].basereg = 2; break;
case 0x1E: ins->oprs[0].basereg = 3; break;
default: return FALSE;
}
}
if (c == 07) {
switch (*data++) {
case 0xA0: ins->oprs[0].basereg = 4; break;
case 0xA8: ins->oprs[0].basereg = 5; break;
default: return FALSE;
}
}
if (c >= 010 && c <= 012) {
int t = *r++, d = *data++;
if (d < t || d > t+7)
return FALSE;
else {
ins->oprs[c-010].basereg = d-t;
ins->oprs[c-010].segment |= SEG_RMREG;
}
}
if (c == 017)
if (*data++)
return FALSE;
if (c >= 014 && c <= 016) {
ins->oprs[c-014].offset = (signed char) *data++;
ins->oprs[c-014].segment |= SEG_SIGNED;
}
if (c >= 020 && c <= 022)
ins->oprs[c-020].offset = *data++;
if (c >= 024 && c <= 026)
ins->oprs[c-024].offset = *data++;
if (c >= 030 && c <= 032) {
ins->oprs[c-030].offset = *data++;
ins->oprs[c-030].offset |= (((unsigned) *data++) << 8);
}
if (c >= 034 && c <= 036) {
ins->oprs[c-034].offset = *data++;
ins->oprs[c-034].offset |= (((unsigned) *data++) << 8);
if (osize == 32) {
ins->oprs[c-034].offset |= (((long) *data++) << 16);
ins->oprs[c-034].offset |= (((long) *data++) << 24);
}
if (segsize != asize)
ins->oprs[c-034].addr_size = asize;
}
if (c >= 040 && c <= 042) {
ins->oprs[c-040].offset = *data++;
ins->oprs[c-040].offset |= (((unsigned) *data++) << 8);
ins->oprs[c-040].offset |= (((long) *data++) << 16);
ins->oprs[c-040].offset |= (((long) *data++) << 24);
}
if (c >= 044 && c <= 046) {
ins->oprs[c-044].offset = *data++;
ins->oprs[c-044].offset |= (((unsigned) *data++) << 8);
if (asize == 32) {
ins->oprs[c-044].offset |= (((long) *data++) << 16);
ins->oprs[c-044].offset |= (((long) *data++) << 24);
}
if (segsize != asize)
ins->oprs[c-044].addr_size = asize;
}
if (c >= 050 && c <= 052) {
ins->oprs[c-050].offset = (signed char) *data++;
ins->oprs[c-050].segment |= SEG_RELATIVE;
}
if (c >= 060 && c <= 062) {
ins->oprs[c-060].offset = *data++;
ins->oprs[c-060].offset |= (((unsigned) *data++) << 8);
ins->oprs[c-060].segment |= SEG_RELATIVE;
ins->oprs[c-060].segment &= ~SEG_32BIT;
}
if (c >= 064 && c <= 066) {
ins->oprs[c-064].offset = *data++;
ins->oprs[c-064].offset |= (((unsigned) *data++) << 8);
if (osize == 32) {
ins->oprs[c-064].offset |= (((long) *data++) << 16);
ins->oprs[c-064].offset |= (((long) *data++) << 24);
ins->oprs[c-064].segment |= SEG_32BIT;
} else
ins->oprs[c-064].segment &= ~SEG_32BIT;
ins->oprs[c-064].segment |= SEG_RELATIVE;
if (segsize != osize) {
ins->oprs[c-064].type =
(ins->oprs[c-064].type & NON_SIZE)
| ((osize == 16) ? BITS16 : BITS32);
}
}
if (c >= 070 && c <= 072) {
ins->oprs[c-070].offset = *data++;
ins->oprs[c-070].offset |= (((unsigned) *data++) << 8);
ins->oprs[c-070].offset |= (((long) *data++) << 16);
ins->oprs[c-070].offset |= (((long) *data++) << 24);
ins->oprs[c-070].segment |= SEG_32BIT | SEG_RELATIVE;
}
if (c >= 0100 && c < 0130) {
int modrm = *data++;
ins->oprs[c & 07].basereg = (modrm >> 3) & 07;
ins->oprs[c & 07].segment |= SEG_RMREG;
data = do_ea (data, modrm, asize, segsize,
&ins->oprs[(c >> 3) & 07]);
}
if (c >= 0130 && c <= 0132) {
ins->oprs[c-0130].offset = *data++;
ins->oprs[c-0130].offset |= (((unsigned) *data++) << 8);
}
if (c >= 0140 && c <= 0142) {
ins->oprs[c-0140].offset = *data++;
ins->oprs[c-0140].offset |= (((unsigned) *data++) << 8);
ins->oprs[c-0140].offset |= (((long) *data++) << 16);
ins->oprs[c-0140].offset |= (((long) *data++) << 24);
}
if (c >= 0200 && c <= 0277) {
int modrm = *data++;
if (((modrm >> 3) & 07) != (c & 07))
return FALSE; /* spare field doesn't match up */
data = do_ea (data, modrm, asize, segsize,
&ins->oprs[(c >> 3) & 07]);
}
if (c >= 0300 && c <= 0302) {
if (asize)
ins->oprs[c-0300].segment |= SEG_32BIT;
else
ins->oprs[c-0300].segment &= ~SEG_32BIT;
a_used = TRUE;
}
if (c == 0310) {
if (asize == 32)
return FALSE;
else
a_used = TRUE;
}
if (c == 0311) {
if (asize == 16)
return FALSE;
else
a_used = TRUE;
}
if (c == 0312) {
if (asize != segsize)
return FALSE;
else
a_used = TRUE;
}
if (c == 0320) {
if (osize == 32)
return FALSE;
else
o_used = TRUE;
}
if (c == 0321) {
if (osize == 16)
return FALSE;
else
o_used = TRUE;
}
if (c == 0322) {
if (osize != segsize)
return FALSE;
else
o_used = TRUE;
}
if (c == 0330) {
int t = *r++, d = *data++;
if (d < t || d > t+15)
return FALSE;
else
ins->condition = d - t;
}
if (c == 0331) {
if ( rep )
return FALSE;
}
if (c == 0332) {
if (drep == P_REP)
drep = P_REPE;
}
if (c == 0333) {
if ( rep != 0xF3 )
return FALSE;
drep = 0;
}
}
/*
* Check for unused rep or a/o prefixes.
*/
ins->nprefix = 0;
if (drep)
ins->prefixes[ins->nprefix++] = drep;
if (!a_used && asize != segsize)
ins->prefixes[ins->nprefix++] = (asize == 16 ? P_A16 : P_A32);
if (!o_used && osize != segsize)
ins->prefixes[ins->nprefix++] = (osize == 16 ? P_O16 : P_O32);
return data - origdata;
}
long disasm (unsigned char *data, char *output, int segsize, long offset,
int autosync, unsigned long prefer)
{
struct itemplate **p, **best_p;
int length, best_length = 0;
char *segover;
int rep, lock, asize, osize, i, slen, colon;
unsigned char *origdata;
int works;
insn tmp_ins, ins;
unsigned long goodness, best;
/*
* Scan for prefixes.
*/
asize = osize = segsize;
segover = NULL;
rep = lock = 0;
origdata = data;
for (;;) {
if (*data == 0xF3 || *data == 0xF2)
rep = *data++;
else if (*data == 0xF0)
lock = *data++;
else if (*data == 0x2E || *data == 0x36 || *data == 0x3E ||
*data == 0x26 || *data == 0x64 || *data == 0x65) {
switch (*data++) {
case 0x2E: segover = "cs"; break;
case 0x36: segover = "ss"; break;
case 0x3E: segover = "ds"; break;
case 0x26: segover = "es"; break;
case 0x64: segover = "fs"; break;
case 0x65: segover = "gs"; break;
}
} else if (*data == 0x66)
osize = 48 - segsize, data++;
else if (*data == 0x67)
asize = 48 - segsize, data++;
else
break;
}
tmp_ins.oprs[0].segment = tmp_ins.oprs[1].segment =
tmp_ins.oprs[2].segment =
tmp_ins.oprs[0].addr_size = tmp_ins.oprs[1].addr_size =
tmp_ins.oprs[2].addr_size = (segsize == 16 ? 0 : SEG_32BIT);
tmp_ins.condition = -1;
best = ~0UL; /* Worst possible */
best_p = NULL;
for (p = itable[*data]; *p; p++) {
if ( (length = matches(*p, data, asize, osize,
segsize, rep, &tmp_ins)) ) {
works = TRUE;
/*
* Final check to make sure the types of r/m match up.
*/
for (i = 0; i < (*p)->operands; i++) {
if (
/* If it's a mem-only EA but we have a register, die. */
((tmp_ins.oprs[i].segment & SEG_RMREG) &&
!(MEMORY & ~(*p)->opd[i])) ||
/* If it's a reg-only EA but we have a memory ref, die. */
(!(tmp_ins.oprs[i].segment & SEG_RMREG) &&
!(REGNORM & ~(*p)->opd[i]) &&
!((*p)->opd[i] & REG_SMASK)) ||
/* Register type mismatch (eg FS vs REG_DESS): die. */
((((*p)->opd[i] & (REGISTER | FPUREG)) ||
(tmp_ins.oprs[i].segment & SEG_RMREG)) &&
!whichreg ((*p)->opd[i], tmp_ins.oprs[i].basereg))) {
works = FALSE;
break;
}
}
if (works) {
goodness = ((*p)->flags & IF_PFMASK) ^ prefer;
if ( goodness < best ) {
/* This is the best one found so far */
best = goodness;
best_p = p;
best_length = length;
ins = tmp_ins;
}
}
}
}
if (!best_p)
return 0; /* no instruction was matched */
/* Pick the best match */
p = best_p;
length = best_length;
slen = 0;
if (lock)
slen += sprintf(output+slen, "lock ");
for (i = 0; i < ins.nprefix; i++)
switch (ins.prefixes[i]) {
case P_REP: slen += sprintf(output+slen, "rep "); break;
case P_REPE: slen += sprintf(output+slen, "repe "); break;
case P_REPNE: slen += sprintf(output+slen, "repne "); break;
case P_A16: slen += sprintf(output+slen, "a16 "); break;
case P_A32: slen += sprintf(output+slen, "a32 "); break;
case P_O16: slen += sprintf(output+slen, "o16 "); break;
case P_O32: slen += sprintf(output+slen, "o32 "); break;
}
for (i = 0; i < elements(ico); i++)
if ((*p)->opcode == ico[i]) {
slen += sprintf(output+slen, "%s%s", icn[i],
whichcond(ins.condition));
break;
}
if (i >= elements(ico))
slen += sprintf(output+slen, "%s", insn_names[(*p)->opcode]);
colon = FALSE;
length += data - origdata; /* fix up for prefixes */
for (i=0; i<(*p)->operands; i++) {
output[slen++] = (colon ? ':' : i==0 ? ' ' : ',');
if (ins.oprs[i].segment & SEG_RELATIVE) {
ins.oprs[i].offset += offset + length;
/*
* sort out wraparound
*/
if (!(ins.oprs[i].segment & SEG_32BIT))
ins.oprs[i].offset &= 0xFFFF;
/*
* add sync marker, if autosync is on
*/
if (autosync)
add_sync (ins.oprs[i].offset, 0L);
}
if ((*p)->opd[i] & COLON)
colon = TRUE;
else
colon = FALSE;
if (((*p)->opd[i] & (REGISTER | FPUREG)) ||
(ins.oprs[i].segment & SEG_RMREG))
{
ins.oprs[i].basereg = whichreg ((*p)->opd[i],
ins.oprs[i].basereg);
if ( (*p)->opd[i] & TO )
slen += sprintf(output+slen, "to ");
slen += sprintf(output+slen, "%s",
reg_names[ins.oprs[i].basereg-EXPR_REG_START]);
} else if (!(UNITY & ~(*p)->opd[i])) {
output[slen++] = '1';
} else if ( (*p)->opd[i] & IMMEDIATE ) {
if ( (*p)->opd[i] & BITS8 ) {
slen += sprintf(output+slen, "byte ");
if (ins.oprs[i].segment & SEG_SIGNED) {
if (ins.oprs[i].offset < 0) {
ins.oprs[i].offset *= -1;
output[slen++] = '-';
} else
output[slen++] = '+';
}
} else if ( (*p)->opd[i] & BITS16 ) {
slen += sprintf(output+slen, "word ");
} else if ( (*p)->opd[i] & BITS32 ) {
slen += sprintf(output+slen, "dword ");
} else if ( (*p)->opd[i] & NEAR ) {
slen += sprintf(output+slen, "near ");
} else if ( (*p)->opd[i] & SHORT ) {
slen += sprintf(output+slen, "short ");
}
slen += sprintf(output+slen, "0x%lx", ins.oprs[i].offset);
} else if ( !(MEM_OFFS & ~(*p)->opd[i]) ) {
slen += sprintf(output+slen, "[%s%s%s0x%lx]",
(segover ? segover : ""),
(segover ? ":" : ""),
(ins.oprs[i].addr_size == 32 ? "dword " :
ins.oprs[i].addr_size == 16 ? "word " : ""),
ins.oprs[i].offset);
segover = NULL;
} else if ( !(REGMEM & ~(*p)->opd[i]) ) {
int started = FALSE;
if ( (*p)->opd[i] & BITS8 )
slen += sprintf(output+slen, "byte ");
if ( (*p)->opd[i] & BITS16 )
slen += sprintf(output+slen, "word ");
if ( (*p)->opd[i] & BITS32 )
slen += sprintf(output+slen, "dword ");
if ( (*p)->opd[i] & BITS64 )
slen += sprintf(output+slen, "qword ");
if ( (*p)->opd[i] & BITS80 )
slen += sprintf(output+slen, "tword ");
if ( (*p)->opd[i] & FAR )
slen += sprintf(output+slen, "far ");
if ( (*p)->opd[i] & NEAR )
slen += sprintf(output+slen, "near ");
output[slen++] = '[';
if (ins.oprs[i].addr_size)
slen += sprintf(output+slen, "%s",
(ins.oprs[i].addr_size == 32 ? "dword " :
ins.oprs[i].addr_size == 16 ? "word " : ""));
if (segover) {
slen += sprintf(output+slen, "%s:", segover);
segover = NULL;
}
if (ins.oprs[i].basereg != -1) {
slen += sprintf(output+slen, "%s",
reg_names[(ins.oprs[i].basereg -
EXPR_REG_START)]);
started = TRUE;
}
if (ins.oprs[i].indexreg != -1) {
if (started)
output[slen++] = '+';
slen += sprintf(output+slen, "%s",
reg_names[(ins.oprs[i].indexreg -
EXPR_REG_START)]);
if (ins.oprs[i].scale > 1)
slen += sprintf(output+slen, "*%d", ins.oprs[i].scale);
started = TRUE;
}
if (ins.oprs[i].segment & SEG_DISP8) {
int sign = '+';
if (ins.oprs[i].offset & 0x80) {
ins.oprs[i].offset = - (signed char) ins.oprs[i].offset;
sign = '-';
}
slen += sprintf(output+slen, "%c0x%lx", sign,
ins.oprs[i].offset);
} else if (ins.oprs[i].segment & SEG_DISP16) {
if (started)
output[slen++] = '+';
slen += sprintf(output+slen, "0x%lx", ins.oprs[i].offset);
} else if (ins.oprs[i].segment & SEG_DISP32) {
if (started)
output[slen++] = '+';
slen += sprintf(output+slen, "0x%lx", ins.oprs[i].offset);
}
output[slen++] = ']';
} else {
slen += sprintf(output+slen, "<operand%d>", i);
}
}
output[slen] = '\0';
if (segover) { /* unused segment override */
char *p = output;
int count = slen+1;
while (count--)
p[count+3] = p[count];
strncpy (output, segover, 2);
output[2] = ' ';
}
return length;
}
long eatbyte (unsigned char *data, char *output)
{
sprintf(output, "db 0x%02X", *data);
return 1;
}

View file

@ -0,0 +1,18 @@
/* disasm.h header file for disasm.c
*
* The Netwide Assembler is copyright (C) 1996 Simon Tatham and
* Julian Hall. All rights reserved. The software is
* redistributable under the licence given in the file "Licence"
* distributed in the NASM archive.
*/
#ifndef NASM_DISASM_H
#define NASM_DISASM_H
#define INSN_MAX 32 /* one instruction can't be longer than this */
long disasm (unsigned char *data, char *output, int segsize, long offset,
int autosync, unsigned long prefer);
long eatbyte (unsigned char *data, char *output);
#endif

View file

@ -0,0 +1,99 @@
/* insns.h header file for insns.c
* $Id: insns.h,v 1.1 2005/02/07 00:26:03 rylek Exp $
*
* The Netwide Assembler is copyright (C) 1996 Simon Tatham and
* Julian Hall. All rights reserved. The software is
* redistributable under the licence given in the file "Licence"
* distributed in the NASM archive.
*/
#ifndef NASM_INSNS_H
#define NASM_INSNS_H
#include "insnsi.h" /* instruction opcode enum */
/* max length of any instruction, register name etc. */
#if MAX_INSLEN > 9 /* MAX_INSLEN defined in insnsi.h */
#define MAX_KEYWORD MAX_INSLEN
#else
#define MAX_KEYWORD 9
#endif
struct itemplate {
int opcode; /* the token, passed from "parser.c" */
int operands; /* number of operands */
long opd[3]; /* bit flags for operand types */
const char *code; /* the code it assembles to */
unsigned long flags; /* some flags */
};
/*
* this define is used to signify the end of an itemplate
*/
#define ITEMPLATE_END {-1,-1,{-1,-1,-1},NULL,0}
/*
* Instruction template flags. These specify which processor
* targets the instruction is eligible for, whether it is
* privileged or undocumented, and also specify extra error
* checking on the matching of the instruction.
*
* IF_SM stands for Size Match: any operand whose size is not
* explicitly specified by the template is `really' intended to be
* the same size as the first size-specified operand.
* Non-specification is tolerated in the input instruction, but
* _wrong_ specification is not.
*
* IF_SM2 invokes Size Match on only the first _two_ operands, for
* three-operand instructions such as SHLD: it implies that the
* first two operands must match in size, but that the third is
* required to be _unspecified_.
*
* IF_SB invokes Size Byte: operands with unspecified size in the
* template are really bytes, and so no non-byte specification in
* the input instruction will be tolerated. IF_SW similarly invokes
* Size Word, and IF_SD invokes Size Doubleword.
*
* (The default state if neither IF_SM nor IF_SM2 is specified is
* that any operand with unspecified size in the template is
* required to have unspecified size in the instruction too...)
*/
#define IF_SM 0x00000001UL /* size match */
#define IF_SM2 0x00000002UL /* size match first two operands */
#define IF_SB 0x00000004UL /* unsized operands can't be non-byte */
#define IF_SW 0x00000008UL /* unsized operands can't be non-word */
#define IF_SD 0x00000010UL /* unsized operands can't be nondword */
#define IF_AR0 0x00000020UL /* SB, SW, SD applies to argument 0 */
#define IF_AR1 0x00000040UL /* SB, SW, SD applies to argument 1 */
#define IF_AR2 0x00000060UL /* SB, SW, SD applies to argument 2 */
#define IF_ARMASK 0x00000060UL /* mask for unsized argument spec */
#define IF_PRIV 0x00000100UL /* it's a privileged instruction */
#define IF_SMM 0x00000200UL /* it's only valid in SMM */
#define IF_PROT 0x00000400UL /* it's protected mode only */
#define IF_UNDOC 0x00001000UL /* it's an undocumented instruction */
#define IF_FPU 0x00002000UL /* it's an FPU instruction */
#define IF_MMX 0x00004000UL /* it's an MMX instruction */
#define IF_3DNOW 0x00008000UL /* it's a 3DNow! instruction */
#define IF_SSE 0x00010000UL /* it's a SSE (KNI, MMX2) instruction */
#define IF_SSE2 0x00020000UL /* it's a SSE2 instruction */
#define IF_SSE3 0x00040000UL /* it's a SSE3 (PNI) instruction */
#define IF_PMASK 0xFF000000UL /* the mask for processor types */
#define IF_PLEVEL 0x0F000000UL /* the mask for processor instr. level */
/* also the highest possible processor */
#define IF_PFMASK 0xF001FF00UL /* the mask for disassembly "prefer" */
#define IF_8086 0x00000000UL /* 8086 instruction */
#define IF_186 0x01000000UL /* 186+ instruction */
#define IF_286 0x02000000UL /* 286+ instruction */
#define IF_386 0x03000000UL /* 386+ instruction */
#define IF_486 0x04000000UL /* 486+ instruction */
#define IF_PENT 0x05000000UL /* Pentium instruction */
#define IF_P6 0x06000000UL /* P6 instruction */
#define IF_KATMAI 0x07000000UL /* Katmai instructions */
#define IF_WILLAMETTE 0x08000000UL /* Willamette instructions */
#define IF_PRESCOTT 0x09000000UL /* Prescott instructions */
#define IF_IA64 0x0F000000UL /* IA64 instructions */
#define IF_CYRIX 0x10000000UL /* Cyrix-specific instruction */
#define IF_AMD 0x20000000UL /* AMD-specific instruction */
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,572 @@
/* This file is auto-generated from insns.dat by insns.pl - don't edit it */
/* This file in included by nasm.h */
/* Instruction names */
enum {
I_AAA,
I_AAD,
I_AAM,
I_AAS,
I_ADC,
I_ADD,
I_ADDPD,
I_ADDPS,
I_ADDSD,
I_ADDSS,
I_ADDSUBPD,
I_ADDSUBPS,
I_AND,
I_ANDNPD,
I_ANDNPS,
I_ANDPD,
I_ANDPS,
I_ARPL,
I_BOUND,
I_BSF,
I_BSR,
I_BSWAP,
I_BT,
I_BTC,
I_BTR,
I_BTS,
I_CALL,
I_CBW,
I_CDQ,
I_CLC,
I_CLD,
I_CLFLUSH,
I_CLI,
I_CLTS,
I_CMC,
I_CMP,
I_CMPEQPD,
I_CMPEQPS,
I_CMPEQSD,
I_CMPEQSS,
I_CMPLEPD,
I_CMPLEPS,
I_CMPLESD,
I_CMPLESS,
I_CMPLTPD,
I_CMPLTPS,
I_CMPLTSD,
I_CMPLTSS,
I_CMPNEQPD,
I_CMPNEQPS,
I_CMPNEQSD,
I_CMPNEQSS,
I_CMPNLEPD,
I_CMPNLEPS,
I_CMPNLESD,
I_CMPNLESS,
I_CMPNLTPD,
I_CMPNLTPS,
I_CMPNLTSD,
I_CMPNLTSS,
I_CMPORDPD,
I_CMPORDPS,
I_CMPORDSD,
I_CMPORDSS,
I_CMPPD,
I_CMPPS,
I_CMPSB,
I_CMPSD,
I_CMPSS,
I_CMPSW,
I_CMPUNORDPD,
I_CMPUNORDPS,
I_CMPUNORDSD,
I_CMPUNORDSS,
I_CMPXCHG,
I_CMPXCHG486,
I_CMPXCHG8B,
I_COMISD,
I_COMISS,
I_CPUID,
I_CVTDQ2PD,
I_CVTDQ2PS,
I_CVTPD2DQ,
I_CVTPD2PI,
I_CVTPD2PS,
I_CVTPI2PD,
I_CVTPI2PS,
I_CVTPS2DQ,
I_CVTPS2PD,
I_CVTPS2PI,
I_CVTSD2SI,
I_CVTSD2SS,
I_CVTSI2SD,
I_CVTSI2SS,
I_CVTSS2SD,
I_CVTSS2SI,
I_CVTTPD2DQ,
I_CVTTPD2PI,
I_CVTTPS2DQ,
I_CVTTPS2PI,
I_CVTTSD2SI,
I_CVTTSS2SI,
I_CWD,
I_CWDE,
I_DAA,
I_DAS,
I_DB,
I_DD,
I_DEC,
I_DIV,
I_DIVPD,
I_DIVPS,
I_DIVSD,
I_DIVSS,
I_DQ,
I_DT,
I_DW,
I_EMMS,
I_ENTER,
I_EQU,
I_F2XM1,
I_FABS,
I_FADD,
I_FADDP,
I_FBLD,
I_FBSTP,
I_FCHS,
I_FCLEX,
I_FCMOVB,
I_FCMOVBE,
I_FCMOVE,
I_FCMOVNB,
I_FCMOVNBE,
I_FCMOVNE,
I_FCMOVNU,
I_FCMOVU,
I_FCOM,
I_FCOMI,
I_FCOMIP,
I_FCOMP,
I_FCOMPP,
I_FCOS,
I_FDECSTP,
I_FDISI,
I_FDIV,
I_FDIVP,
I_FDIVR,
I_FDIVRP,
I_FEMMS,
I_FENI,
I_FFREE,
I_FFREEP,
I_FIADD,
I_FICOM,
I_FICOMP,
I_FIDIV,
I_FIDIVR,
I_FILD,
I_FIMUL,
I_FINCSTP,
I_FINIT,
I_FIST,
I_FISTP,
I_FISTTP,
I_FISUB,
I_FISUBR,
I_FLD,
I_FLD1,
I_FLDCW,
I_FLDENV,
I_FLDL2E,
I_FLDL2T,
I_FLDLG2,
I_FLDLN2,
I_FLDPI,
I_FLDZ,
I_FMUL,
I_FMULP,
I_FNCLEX,
I_FNDISI,
I_FNENI,
I_FNINIT,
I_FNOP,
I_FNSAVE,
I_FNSTCW,
I_FNSTENV,
I_FNSTSW,
I_FPATAN,
I_FPREM,
I_FPREM1,
I_FPTAN,
I_FRNDINT,
I_FRSTOR,
I_FSAVE,
I_FSCALE,
I_FSETPM,
I_FSIN,
I_FSINCOS,
I_FSQRT,
I_FST,
I_FSTCW,
I_FSTENV,
I_FSTP,
I_FSTSW,
I_FSUB,
I_FSUBP,
I_FSUBR,
I_FSUBRP,
I_FTST,
I_FUCOM,
I_FUCOMI,
I_FUCOMIP,
I_FUCOMP,
I_FUCOMPP,
I_FWAIT,
I_FXAM,
I_FXCH,
I_FXRSTOR,
I_FXSAVE,
I_FXTRACT,
I_FYL2X,
I_FYL2XP1,
I_HADDPD,
I_HADDPS,
I_HLT,
I_HSUBPD,
I_HSUBPS,
I_IBTS,
I_ICEBP,
I_IDIV,
I_IMUL,
I_IN,
I_INC,
I_INCBIN,
I_INSB,
I_INSD,
I_INSW,
I_INT,
I_INT01,
I_INT03,
I_INT1,
I_INT3,
I_INTO,
I_INVD,
I_INVLPG,
I_IRET,
I_IRETD,
I_IRETW,
I_JCXZ,
I_JECXZ,
I_JMP,
I_JMPE,
I_LAHF,
I_LAR,
I_LDDQU,
I_LDMXCSR,
I_LDS,
I_LEA,
I_LEAVE,
I_LES,
I_LFENCE,
I_LFS,
I_LGDT,
I_LGS,
I_LIDT,
I_LLDT,
I_LMSW,
I_LOADALL,
I_LOADALL286,
I_LODSB,
I_LODSD,
I_LODSW,
I_LOOP,
I_LOOPE,
I_LOOPNE,
I_LOOPNZ,
I_LOOPZ,
I_LSL,
I_LSS,
I_LTR,
I_MASKMOVDQU,
I_MASKMOVQ,
I_MAXPD,
I_MAXPS,
I_MAXSD,
I_MAXSS,
I_MFENCE,
I_MINPD,
I_MINPS,
I_MINSD,
I_MINSS,
I_MONITOR,
I_MOV,
I_MOVAPD,
I_MOVAPS,
I_MOVD,
I_MOVDDUP,
I_MOVDQ2Q,
I_MOVDQA,
I_MOVDQU,
I_MOVHLPS,
I_MOVHPD,
I_MOVHPS,
I_MOVLHPS,
I_MOVLPD,
I_MOVLPS,
I_MOVMSKPD,
I_MOVMSKPS,
I_MOVNTDQ,
I_MOVNTI,
I_MOVNTPD,
I_MOVNTPS,
I_MOVNTQ,
I_MOVQ,
I_MOVQ2DQ,
I_MOVSB,
I_MOVSD,
I_MOVSHDUP,
I_MOVSLDUP,
I_MOVSS,
I_MOVSW,
I_MOVSX,
I_MOVUPD,
I_MOVUPS,
I_MOVZX,
I_MUL,
I_MULPD,
I_MULPS,
I_MULSD,
I_MULSS,
I_MWAIT,
I_NEG,
I_NOP,
I_NOT,
I_OR,
I_ORPD,
I_ORPS,
I_OUT,
I_OUTSB,
I_OUTSD,
I_OUTSW,
I_PACKSSDW,
I_PACKSSWB,
I_PACKUSWB,
I_PADDB,
I_PADDD,
I_PADDQ,
I_PADDSB,
I_PADDSIW,
I_PADDSW,
I_PADDUSB,
I_PADDUSW,
I_PADDW,
I_PAND,
I_PANDN,
I_PAUSE,
I_PAVEB,
I_PAVGB,
I_PAVGUSB,
I_PAVGW,
I_PCMPEQB,
I_PCMPEQD,
I_PCMPEQW,
I_PCMPGTB,
I_PCMPGTD,
I_PCMPGTW,
I_PDISTIB,
I_PEXTRW,
I_PF2ID,
I_PF2IW,
I_PFACC,
I_PFADD,
I_PFCMPEQ,
I_PFCMPGE,
I_PFCMPGT,
I_PFMAX,
I_PFMIN,
I_PFMUL,
I_PFNACC,
I_PFPNACC,
I_PFRCP,
I_PFRCPIT1,
I_PFRCPIT2,
I_PFRSQIT1,
I_PFRSQRT,
I_PFSUB,
I_PFSUBR,
I_PI2FD,
I_PI2FW,
I_PINSRW,
I_PMACHRIW,
I_PMADDWD,
I_PMAGW,
I_PMAXSW,
I_PMAXUB,
I_PMINSW,
I_PMINUB,
I_PMOVMSKB,
I_PMULHRIW,
I_PMULHRWA,
I_PMULHRWC,
I_PMULHUW,
I_PMULHW,
I_PMULLW,
I_PMULUDQ,
I_PMVGEZB,
I_PMVLZB,
I_PMVNZB,
I_PMVZB,
I_POP,
I_POPA,
I_POPAD,
I_POPAW,
I_POPF,
I_POPFD,
I_POPFW,
I_POR,
I_PREFETCH,
I_PREFETCHNTA,
I_PREFETCHT0,
I_PREFETCHT1,
I_PREFETCHT2,
I_PREFETCHW,
I_PSADBW,
I_PSHUFD,
I_PSHUFHW,
I_PSHUFLW,
I_PSHUFW,
I_PSLLD,
I_PSLLDQ,
I_PSLLQ,
I_PSLLW,
I_PSRAD,
I_PSRAW,
I_PSRLD,
I_PSRLDQ,
I_PSRLQ,
I_PSRLW,
I_PSUBB,
I_PSUBD,
I_PSUBQ,
I_PSUBSB,
I_PSUBSIW,
I_PSUBSW,
I_PSUBUSB,
I_PSUBUSW,
I_PSUBW,
I_PSWAPD,
I_PUNPCKHBW,
I_PUNPCKHDQ,
I_PUNPCKHQDQ,
I_PUNPCKHWD,
I_PUNPCKLBW,
I_PUNPCKLDQ,
I_PUNPCKLQDQ,
I_PUNPCKLWD,
I_PUSH,
I_PUSHA,
I_PUSHAD,
I_PUSHAW,
I_PUSHF,
I_PUSHFD,
I_PUSHFW,
I_PXOR,
I_RCL,
I_RCPPS,
I_RCPSS,
I_RCR,
I_RDMSR,
I_RDPMC,
I_RDSHR,
I_RDTSC,
I_RESB,
I_RESD,
I_RESQ,
I_REST,
I_RESW,
I_RET,
I_RETF,
I_RETN,
I_ROL,
I_ROR,
I_RSDC,
I_RSLDT,
I_RSM,
I_RSQRTPS,
I_RSQRTSS,
I_RSTS,
I_SAHF,
I_SAL,
I_SALC,
I_SAR,
I_SBB,
I_SCASB,
I_SCASD,
I_SCASW,
I_SFENCE,
I_SGDT,
I_SHL,
I_SHLD,
I_SHR,
I_SHRD,
I_SHUFPD,
I_SHUFPS,
I_SIDT,
I_SLDT,
I_SMI,
I_SMINT,
I_SMINTOLD,
I_SMSW,
I_SQRTPD,
I_SQRTPS,
I_SQRTSD,
I_SQRTSS,
I_STC,
I_STD,
I_STI,
I_STMXCSR,
I_STOSB,
I_STOSD,
I_STOSW,
I_STR,
I_SUB,
I_SUBPD,
I_SUBPS,
I_SUBSD,
I_SUBSS,
I_SVDC,
I_SVLDT,
I_SVTS,
I_SYSCALL,
I_SYSENTER,
I_SYSEXIT,
I_SYSRET,
I_TEST,
I_UCOMISD,
I_UCOMISS,
I_UD0,
I_UD1,
I_UD2,
I_UMOV,
I_UNPCKHPD,
I_UNPCKHPS,
I_UNPCKLPD,
I_UNPCKLPS,
I_VERR,
I_VERW,
I_WAIT,
I_WBINVD,
I_WRMSR,
I_WRSHR,
I_XADD,
I_XBTS,
I_XCHG,
I_XLAT,
I_XLATB,
I_XOR,
I_XORPD,
I_XORPS,
I_XSTORE,
I_CMOVcc,
I_Jcc,
I_SETcc
};
#define MAX_INSLEN 11

View file

@ -0,0 +1,580 @@
/* This file is auto-generated from insns.dat by insns.pl - don't edit it */
/* This file in included by names.c */
static const char *insn_names[] = {
"aaa",
"aad",
"aam",
"aas",
"adc",
"add",
"addpd",
"addps",
"addsd",
"addss",
"addsubpd",
"addsubps",
"and",
"andnpd",
"andnps",
"andpd",
"andps",
"arpl",
"bound",
"bsf",
"bsr",
"bswap",
"bt",
"btc",
"btr",
"bts",
"call",
"cbw",
"cdq",
"clc",
"cld",
"clflush",
"cli",
"clts",
"cmc",
"cmp",
"cmpeqpd",
"cmpeqps",
"cmpeqsd",
"cmpeqss",
"cmplepd",
"cmpleps",
"cmplesd",
"cmpless",
"cmpltpd",
"cmpltps",
"cmpltsd",
"cmpltss",
"cmpneqpd",
"cmpneqps",
"cmpneqsd",
"cmpneqss",
"cmpnlepd",
"cmpnleps",
"cmpnlesd",
"cmpnless",
"cmpnltpd",
"cmpnltps",
"cmpnltsd",
"cmpnltss",
"cmpordpd",
"cmpordps",
"cmpordsd",
"cmpordss",
"cmppd",
"cmpps",
"cmpsb",
"cmpsd",
"cmpss",
"cmpsw",
"cmpunordpd",
"cmpunordps",
"cmpunordsd",
"cmpunordss",
"cmpxchg",
"cmpxchg486",
"cmpxchg8b",
"comisd",
"comiss",
"cpuid",
"cvtdq2pd",
"cvtdq2ps",
"cvtpd2dq",
"cvtpd2pi",
"cvtpd2ps",
"cvtpi2pd",
"cvtpi2ps",
"cvtps2dq",
"cvtps2pd",
"cvtps2pi",
"cvtsd2si",
"cvtsd2ss",
"cvtsi2sd",
"cvtsi2ss",
"cvtss2sd",
"cvtss2si",
"cvttpd2dq",
"cvttpd2pi",
"cvttps2dq",
"cvttps2pi",
"cvttsd2si",
"cvttss2si",
"cwd",
"cwde",
"daa",
"das",
"db",
"dd",
"dec",
"div",
"divpd",
"divps",
"divsd",
"divss",
"dq",
"dt",
"dw",
"emms",
"enter",
"equ",
"f2xm1",
"fabs",
"fadd",
"faddp",
"fbld",
"fbstp",
"fchs",
"fclex",
"fcmovb",
"fcmovbe",
"fcmove",
"fcmovnb",
"fcmovnbe",
"fcmovne",
"fcmovnu",
"fcmovu",
"fcom",
"fcomi",
"fcomip",
"fcomp",
"fcompp",
"fcos",
"fdecstp",
"fdisi",
"fdiv",
"fdivp",
"fdivr",
"fdivrp",
"femms",
"feni",
"ffree",
"ffreep",
"fiadd",
"ficom",
"ficomp",
"fidiv",
"fidivr",
"fild",
"fimul",
"fincstp",
"finit",
"fist",
"fistp",
"fisttp",
"fisub",
"fisubr",
"fld",
"fld1",
"fldcw",
"fldenv",
"fldl2e",
"fldl2t",
"fldlg2",
"fldln2",
"fldpi",
"fldz",
"fmul",
"fmulp",
"fnclex",
"fndisi",
"fneni",
"fninit",
"fnop",
"fnsave",
"fnstcw",
"fnstenv",
"fnstsw",
"fpatan",
"fprem",
"fprem1",
"fptan",
"frndint",
"frstor",
"fsave",
"fscale",
"fsetpm",
"fsin",
"fsincos",
"fsqrt",
"fst",
"fstcw",
"fstenv",
"fstp",
"fstsw",
"fsub",
"fsubp",
"fsubr",
"fsubrp",
"ftst",
"fucom",
"fucomi",
"fucomip",
"fucomp",
"fucompp",
"fwait",
"fxam",
"fxch",
"fxrstor",
"fxsave",
"fxtract",
"fyl2x",
"fyl2xp1",
"haddpd",
"haddps",
"hlt",
"hsubpd",
"hsubps",
"ibts",
"icebp",
"idiv",
"imul",
"in",
"inc",
"incbin",
"insb",
"insd",
"insw",
"int",
"int01",
"int03",
"int1",
"int3",
"into",
"invd",
"invlpg",
"iret",
"iretd",
"iretw",
"jcxz",
"jecxz",
"jmp",
"jmpe",
"lahf",
"lar",
"lddqu",
"ldmxcsr",
"lds",
"lea",
"leave",
"les",
"lfence",
"lfs",
"lgdt",
"lgs",
"lidt",
"lldt",
"lmsw",
"loadall",
"loadall286",
"lodsb",
"lodsd",
"lodsw",
"loop",
"loope",
"loopne",
"loopnz",
"loopz",
"lsl",
"lss",
"ltr",
"maskmovdqu",
"maskmovq",
"maxpd",
"maxps",
"maxsd",
"maxss",
"mfence",
"minpd",
"minps",
"minsd",
"minss",
"monitor",
"mov",
"movapd",
"movaps",
"movd",
"movddup",
"movdq2q",
"movdqa",
"movdqu",
"movhlps",
"movhpd",
"movhps",
"movlhps",
"movlpd",
"movlps",
"movmskpd",
"movmskps",
"movntdq",
"movnti",
"movntpd",
"movntps",
"movntq",
"movq",
"movq2dq",
"movsb",
"movsd",
"movshdup",
"movsldup",
"movss",
"movsw",
"movsx",
"movupd",
"movups",
"movzx",
"mul",
"mulpd",
"mulps",
"mulsd",
"mulss",
"mwait",
"neg",
"nop",
"not",
"or",
"orpd",
"orps",
"out",
"outsb",
"outsd",
"outsw",
"packssdw",
"packsswb",
"packuswb",
"paddb",
"paddd",
"paddq",
"paddsb",
"paddsiw",
"paddsw",
"paddusb",
"paddusw",
"paddw",
"pand",
"pandn",
"pause",
"paveb",
"pavgb",
"pavgusb",
"pavgw",
"pcmpeqb",
"pcmpeqd",
"pcmpeqw",
"pcmpgtb",
"pcmpgtd",
"pcmpgtw",
"pdistib",
"pextrw",
"pf2id",
"pf2iw",
"pfacc",
"pfadd",
"pfcmpeq",
"pfcmpge",
"pfcmpgt",
"pfmax",
"pfmin",
"pfmul",
"pfnacc",
"pfpnacc",
"pfrcp",
"pfrcpit1",
"pfrcpit2",
"pfrsqit1",
"pfrsqrt",
"pfsub",
"pfsubr",
"pi2fd",
"pi2fw",
"pinsrw",
"pmachriw",
"pmaddwd",
"pmagw",
"pmaxsw",
"pmaxub",
"pminsw",
"pminub",
"pmovmskb",
"pmulhriw",
"pmulhrwa",
"pmulhrwc",
"pmulhuw",
"pmulhw",
"pmullw",
"pmuludq",
"pmvgezb",
"pmvlzb",
"pmvnzb",
"pmvzb",
"pop",
"popa",
"popad",
"popaw",
"popf",
"popfd",
"popfw",
"por",
"prefetch",
"prefetchnta",
"prefetcht0",
"prefetcht1",
"prefetcht2",
"prefetchw",
"psadbw",
"pshufd",
"pshufhw",
"pshuflw",
"pshufw",
"pslld",
"pslldq",
"psllq",
"psllw",
"psrad",
"psraw",
"psrld",
"psrldq",
"psrlq",
"psrlw",
"psubb",
"psubd",
"psubq",
"psubsb",
"psubsiw",
"psubsw",
"psubusb",
"psubusw",
"psubw",
"pswapd",
"punpckhbw",
"punpckhdq",
"punpckhqdq",
"punpckhwd",
"punpcklbw",
"punpckldq",
"punpcklqdq",
"punpcklwd",
"push",
"pusha",
"pushad",
"pushaw",
"pushf",
"pushfd",
"pushfw",
"pxor",
"rcl",
"rcpps",
"rcpss",
"rcr",
"rdmsr",
"rdpmc",
"rdshr",
"rdtsc",
"resb",
"resd",
"resq",
"rest",
"resw",
"ret",
"retf",
"retn",
"rol",
"ror",
"rsdc",
"rsldt",
"rsm",
"rsqrtps",
"rsqrtss",
"rsts",
"sahf",
"sal",
"salc",
"sar",
"sbb",
"scasb",
"scasd",
"scasw",
"sfence",
"sgdt",
"shl",
"shld",
"shr",
"shrd",
"shufpd",
"shufps",
"sidt",
"sldt",
"smi",
"smint",
"smintold",
"smsw",
"sqrtpd",
"sqrtps",
"sqrtsd",
"sqrtss",
"stc",
"std",
"sti",
"stmxcsr",
"stosb",
"stosd",
"stosw",
"str",
"sub",
"subpd",
"subps",
"subsd",
"subss",
"svdc",
"svldt",
"svts",
"syscall",
"sysenter",
"sysexit",
"sysret",
"test",
"ucomisd",
"ucomiss",
"ud0",
"ud1",
"ud2",
"umov",
"unpckhpd",
"unpckhps",
"unpcklpd",
"unpcklps",
"verr",
"verw",
"wait",
"wbinvd",
"wrmsr",
"wrshr",
"xadd",
"xbts",
"xchg",
"xlat",
"xlatb",
"xor",
"xorpd",
"xorps",
"xstore"
};
/* Conditional instructions */
static const char *icn[] = {
"cmov",
"j",
"set"
};
/* and the corresponding opcodes */
static int ico[] = {
I_CMOVcc,
I_Jcc,
I_SETcc
};

View file

@ -0,0 +1,20 @@
/* names.c included source file defining instruction and register
* names for the Netwide [Dis]Assembler
*
* The Netwide Assembler is copyright (C) 1996 Simon Tatham and
* Julian Hall. All rights reserved. The software is
* redistributable under the licence given in the file "Licence"
* distributed in the NASM archive.
*/
static const char *conditions[] = { /* condition code names */
"a", "ae", "b", "be", "c", "e", "g", "ge", "l", "le", "na", "nae",
"nb", "nbe", "nc", "ne", "ng", "nge", "nl", "nle", "no", "np",
"ns", "nz", "o", "p", "pe", "po", "s", "z"
};
/* Register names automatically generated from regs.dat */
#include "regs.c"
/* Instruction names automatically generated from insns.dat */
#include "insnsn.c"

View file

@ -0,0 +1,852 @@
/* nasm.h main header file for the Netwide Assembler: inter-module interface
*
* The Netwide Assembler is copyright (C) 1996 Simon Tatham and
* Julian Hall. All rights reserved. The software is
* redistributable under the licence given in the file "Licence"
* distributed in the NASM archive.
*
* initial version: 27/iii/95 by Simon Tatham
*/
#ifndef NASM_NASM_H
#define NASM_NASM_H
#include <stdio.h>
#include "version.h" /* generated NASM version macros */
#ifndef NULL
#define NULL 0
#endif
#ifndef FALSE
#define FALSE 0 /* comes in handy */
#endif
#ifndef TRUE
#define TRUE 1
#endif
#define NO_SEG -1L /* null segment value */
#define SEG_ABS 0x40000000L /* mask for far-absolute segments */
#ifndef FILENAME_MAX
#define FILENAME_MAX 256
#endif
#ifndef PREFIX_MAX
#define PREFIX_MAX 10
#endif
#ifndef POSTFIX_MAX
#define POSTFIX_MAX 10
#endif
#define IDLEN_MAX 4096
/*
* Name pollution problems: <time.h> on Digital UNIX pulls in some
* strange hardware header file which sees fit to define R_SP. We
* undefine it here so as not to break the enum below.
*/
#ifdef R_SP
#undef R_SP
#endif
/*
* We must declare the existence of this structure type up here,
* since we have to reference it before we define it...
*/
struct ofmt;
/*
* -------------------------
* Error reporting functions
* -------------------------
*/
/*
* An error reporting function should look like this.
*/
typedef void (*efunc) (int severity, const char *fmt, ...);
/*
* These are the error severity codes which get passed as the first
* argument to an efunc.
*/
#define ERR_DEBUG 0x00000008 /* put out debugging message */
#define ERR_WARNING 0x00000000 /* warn only: no further action */
#define ERR_NONFATAL 0x00000001 /* terminate assembly after phase */
#define ERR_FATAL 0x00000002 /* instantly fatal: exit with error */
#define ERR_PANIC 0x00000003 /* internal error: panic instantly
* and dump core for reference */
#define ERR_MASK 0x0000000F /* mask off the above codes */
#define ERR_NOFILE 0x00000010 /* don't give source file name/line */
#define ERR_USAGE 0x00000020 /* print a usage message */
#define ERR_PASS1 0x00000040 /* only print this error on pass one */
/*
* These codes define specific types of suppressible warning.
*/
#define ERR_WARN_MASK 0x0000FF00 /* the mask for this feature */
#define ERR_WARN_SHR 8 /* how far to shift right */
#define ERR_WARN_MNP 0x00000100 /* macro-num-parameters warning */
#define ERR_WARN_MSR 0x00000200 /* macro self-reference */
#define ERR_WARN_OL 0x00000300 /* orphan label (no colon, and
* alone on line) */
#define ERR_WARN_NOV 0x00000400 /* numeric overflow */
#define ERR_WARN_GNUELF 0x00000500 /* using GNU ELF extensions */
#define ERR_WARN_MAX 5 /* the highest numbered one */
/*
* -----------------------
* Other function typedefs
* -----------------------
*/
/*
* A label-lookup function should look like this.
*/
typedef int (*lfunc) (char *label, long *segment, long *offset);
/*
* And a label-definition function like this. The boolean parameter
* `is_norm' states whether the label is a `normal' label (which
* should affect the local-label system), or something odder like
* an EQU or a segment-base symbol, which shouldn't.
*/
typedef void (*ldfunc) (char *label, long segment, long offset, char *special,
int is_norm, int isextrn, struct ofmt *ofmt,
efunc error);
/*
* List-file generators should look like this:
*/
typedef struct {
/*
* Called to initialise the listing file generator. Before this
* is called, the other routines will silently do nothing when
* called. The `char *' parameter is the file name to write the
* listing to.
*/
void (*init) (char *, efunc);
/*
* Called to clear stuff up and close the listing file.
*/
void (*cleanup) (void);
/*
* Called to output binary data. Parameters are: the offset;
* the data; the data type. Data types are similar to the
* output-format interface, only OUT_ADDRESS will _always_ be
* displayed as if it's relocatable, so ensure that any non-
* relocatable address has been converted to OUT_RAWDATA by
* then. Note that OUT_RAWDATA+0 is a valid data type, and is a
* dummy call used to give the listing generator an offset to
* work with when doing things like uplevel(LIST_TIMES) or
* uplevel(LIST_INCBIN).
*/
void (*output) (long, const void *, unsigned long);
/*
* Called to send a text line to the listing generator. The
* `int' parameter is LIST_READ or LIST_MACRO depending on
* whether the line came directly from an input file or is the
* result of a multi-line macro expansion.
*/
void (*line) (int, char *);
/*
* Called to change one of the various levelled mechanisms in
* the listing generator. LIST_INCLUDE and LIST_MACRO can be
* used to increase the nesting level of include files and
* macro expansions; LIST_TIMES and LIST_INCBIN switch on the
* two binary-output-suppression mechanisms for large-scale
* pseudo-instructions.
*
* LIST_MACRO_NOLIST is synonymous with LIST_MACRO except that
* it indicates the beginning of the expansion of a `nolist'
* macro, so anything under that level won't be expanded unless
* it includes another file.
*/
void (*uplevel) (int);
/*
* Reverse the effects of uplevel.
*/
void (*downlevel) (int);
} ListGen;
/*
* The expression evaluator must be passed a scanner function; a
* standard scanner is provided as part of nasmlib.c. The
* preprocessor will use a different one. Scanners, and the
* token-value structures they return, look like this.
*
* The return value from the scanner is always a copy of the
* `t_type' field in the structure.
*/
struct tokenval {
int t_type;
long t_integer, t_inttwo;
char *t_charptr;
};
typedef int (*scanner) (void *private_data, struct tokenval *tv);
/*
* Token types returned by the scanner, in addition to ordinary
* ASCII character values, and zero for end-of-string.
*/
enum { /* token types, other than chars */
TOKEN_INVALID = -1, /* a placeholder value */
TOKEN_EOS = 0, /* end of string */
TOKEN_EQ = '=', TOKEN_GT = '>', TOKEN_LT = '<', /* aliases */
TOKEN_ID = 256, TOKEN_NUM, TOKEN_REG, TOKEN_INSN, /* major token types */
TOKEN_ERRNUM, /* numeric constant with error in */
TOKEN_HERE, TOKEN_BASE, /* $ and $$ */
TOKEN_SPECIAL, /* BYTE, WORD, DWORD, FAR, NEAR, etc */
TOKEN_PREFIX, /* A32, O16, LOCK, REPNZ, TIMES, etc */
TOKEN_SHL, TOKEN_SHR, /* << and >> */
TOKEN_SDIV, TOKEN_SMOD, /* // and %% */
TOKEN_GE, TOKEN_LE, TOKEN_NE, /* >=, <= and <> (!= is same as <>) */
TOKEN_DBL_AND, TOKEN_DBL_OR, TOKEN_DBL_XOR, /* &&, || and ^^ */
TOKEN_SEG, TOKEN_WRT, /* SEG and WRT */
TOKEN_FLOAT /* floating-point constant */
};
typedef struct {
long segment;
long offset;
int known;
} loc_t;
/*
* Expression-evaluator datatype. Expressions, within the
* evaluator, are stored as an array of these beasts, terminated by
* a record with type==0. Mostly, it's a vector type: each type
* denotes some kind of a component, and the value denotes the
* multiple of that component present in the expression. The
* exception is the WRT type, whose `value' field denotes the
* segment to which the expression is relative. These segments will
* be segment-base types, i.e. either odd segment values or SEG_ABS
* types. So it is still valid to assume that anything with a
* `value' field of zero is insignificant.
*/
typedef struct {
long type; /* a register, or EXPR_xxx */
long value; /* must be >= 32 bits */
} expr;
/*
* The evaluator can also return hints about which of two registers
* used in an expression should be the base register. See also the
* `operand' structure.
*/
struct eval_hints {
int base;
int type;
};
/*
* The actual expression evaluator function looks like this. When
* called, it expects the first token of its expression to already
* be in `*tv'; if it is not, set tv->t_type to TOKEN_INVALID and
* it will start by calling the scanner.
*
* If a forward reference happens during evaluation, the evaluator
* must set `*fwref' to TRUE if `fwref' is non-NULL.
*
* `critical' is non-zero if the expression may not contain forward
* references. The evaluator will report its own error if this
* occurs; if `critical' is 1, the error will be "symbol not
* defined before use", whereas if `critical' is 2, the error will
* be "symbol undefined".
*
* If `critical' has bit 8 set (in addition to its main value: 0x101
* and 0x102 correspond to 1 and 2) then an extended expression
* syntax is recognised, in which relational operators such as =, <
* and >= are accepted, as well as low-precedence logical operators
* &&, ^^ and ||.
*
* If `hints' is non-NULL, it gets filled in with some hints as to
* the base register in complex effective addresses.
*/
#define CRITICAL 0x100
typedef expr *(*evalfunc) (scanner sc, void *scprivate, struct tokenval *tv,
int *fwref, int critical, efunc error,
struct eval_hints *hints);
/*
* Special values for expr->type. ASSUMPTION MADE HERE: the number
* of distinct register names (i.e. possible "type" fields for an
* expr structure) does not exceed 124 (EXPR_REG_START through
* EXPR_REG_END).
*/
#define EXPR_REG_START 1
#define EXPR_REG_END 124
#define EXPR_UNKNOWN 125L /* for forward references */
#define EXPR_SIMPLE 126L
#define EXPR_WRT 127L
#define EXPR_SEGBASE 128L
/*
* Preprocessors ought to look like this:
*/
typedef struct {
/*
* Called at the start of a pass; given a file name, the number
* of the pass, an error reporting function, an evaluator
* function, and a listing generator to talk to.
*/
void (*reset) (char *, int, efunc, evalfunc, ListGen *);
/*
* Called to fetch a line of preprocessed source. The line
* returned has been malloc'ed, and so should be freed after
* use.
*/
char *(*getline) (void);
/*
* Called at the end of a pass.
*/
void (*cleanup) (int);
} Preproc;
/*
* ----------------------------------------------------------------
* Some lexical properties of the NASM source language, included
* here because they are shared between the parser and preprocessor
* ----------------------------------------------------------------
*/
/*
* isidstart matches any character that may start an identifier, and isidchar
* matches any character that may appear at places other than the start of an
* identifier. E.g. a period may only appear at the start of an identifier
* (for local labels), whereas a number may appear anywhere *but* at the
* start.
*/
#define isidstart(c) ( isalpha(c) || (c)=='_' || (c)=='.' || (c)=='?' \
|| (c)=='@' )
#define isidchar(c) ( isidstart(c) || isdigit(c) || (c)=='$' || (c)=='#' \
|| (c)=='~' )
/* Ditto for numeric constants. */
#define isnumstart(c) ( isdigit(c) || (c)=='$' )
#define isnumchar(c) ( isalnum(c) )
/* This returns the numeric value of a given 'digit'. */
#define numvalue(c) ((c)>='a' ? (c)-'a'+10 : (c)>='A' ? (c)-'A'+10 : (c)-'0')
/*
* Data-type flags that get passed to listing-file routines.
*/
enum {
LIST_READ, LIST_MACRO, LIST_MACRO_NOLIST, LIST_INCLUDE,
LIST_INCBIN, LIST_TIMES
};
/*
* -----------------------------------------------------------
* Format of the `insn' structure returned from `parser.c' and
* passed into `assemble.c'
* -----------------------------------------------------------
*/
/*
* Here we define the operand types. These are implemented as bit
* masks, since some are subsets of others; e.g. AX in a MOV
* instruction is a special operand type, whereas AX in other
* contexts is just another 16-bit register. (Also, consider CL in
* shift instructions, DX in OUT, etc.)
*/
/* size, and other attributes, of the operand */
#define BITS8 0x00000001L
#define BITS16 0x00000002L
#define BITS32 0x00000004L
#define BITS64 0x00000008L /* FPU only */
#define BITS80 0x00000010L /* FPU only */
#define FAR 0x00000020L /* grotty: this means 16:16 or */
/* 16:32, like in CALL/JMP */
#define NEAR 0x00000040L
#define SHORT 0x00000080L /* and this means what it says :) */
#define SIZE_MASK 0x000000FFL /* all the size attributes */
#define NON_SIZE (~SIZE_MASK)
#define TO 0x00000100L /* reverse effect in FADD, FSUB &c */
#define COLON 0x00000200L /* operand is followed by a colon */
#define STRICT 0x00000400L /* do not optimize this operand */
/* type of operand: memory reference, register, etc. */
#define MEMORY 0x00204000L
#define REGISTER 0x00001000L /* register number in 'basereg' */
#define IMMEDIATE 0x00002000L
#define REGMEM 0x00200000L /* for r/m, ie EA, operands */
#define REGNORM 0x00201000L /* 'normal' reg, qualifies as EA */
#define REG8 0x00201001L
#define REG16 0x00201002L
#define REG32 0x00201004L
#define MMXREG 0x00201008L /* MMX registers */
#define XMMREG 0x00201010L /* XMM Katmai reg */
#define FPUREG 0x01000000L /* floating point stack registers */
#define FPU0 0x01000800L /* FPU stack register zero */
/* special register operands: these may be treated differently */
#define REG_SMASK 0x00070000L /* a mask for the following */
#define REG_ACCUM 0x00211000L /* accumulator: AL, AX or EAX */
#define REG_AL 0x00211001L /* REG_ACCUM | BITSxx */
#define REG_AX 0x00211002L /* ditto */
#define REG_EAX 0x00211004L /* and again */
#define REG_COUNT 0x00221000L /* counter: CL, CX or ECX */
#define REG_CL 0x00221001L /* REG_COUNT | BITSxx */
#define REG_CX 0x00221002L /* ditto */
#define REG_ECX 0x00221004L /* another one */
#define REG_DL 0x00241001L
#define REG_DX 0x00241002L
#define REG_EDX 0x00241004L
#define REG_SREG 0x00081002L /* any segment register */
#define REG_CS 0x01081002L /* CS */
#define REG_DESS 0x02081002L /* DS, ES, SS (non-CS 86 registers) */
#define REG_FSGS 0x04081002L /* FS, GS (386 extended registers) */
#define REG_SEG67 0x08081002L /* Non-implemented segment registers */
#define REG_CDT 0x00101004L /* CRn, DRn and TRn */
#define REG_CREG 0x08101004L /* CRn */
#define REG_DREG 0x10101004L /* DRn */
#define REG_TREG 0x20101004L /* TRn */
/* special type of EA */
#define MEM_OFFS 0x00604000L /* simple [address] offset */
/* special type of immediate operand */
#define ONENESS 0x00800000L /* so UNITY == IMMEDIATE | ONENESS */
#define UNITY 0x00802000L /* for shift/rotate instructions */
#define BYTENESS 0x40000000L /* so SBYTE == IMMEDIATE | BYTENESS */
#define SBYTE 0x40002000L /* for op r16/32,immediate instrs. */
/* Register names automatically generated from regs.dat */
#include "regs.h"
enum { /* condition code names */
C_A, C_AE, C_B, C_BE, C_C, C_E, C_G, C_GE, C_L, C_LE, C_NA, C_NAE,
C_NB, C_NBE, C_NC, C_NE, C_NG, C_NGE, C_NL, C_NLE, C_NO, C_NP,
C_NS, C_NZ, C_O, C_P, C_PE, C_PO, C_S, C_Z
};
/*
* Note that because segment registers may be used as instruction
* prefixes, we must ensure the enumerations for prefixes and
* register names do not overlap.
*/
enum { /* instruction prefixes */
PREFIX_ENUM_START = REG_ENUM_LIMIT,
P_A16 = PREFIX_ENUM_START, P_A32, P_LOCK, P_O16, P_O32, P_REP, P_REPE,
P_REPNE, P_REPNZ, P_REPZ, P_TIMES
};
enum { /* extended operand types */
EOT_NOTHING, EOT_DB_STRING, EOT_DB_NUMBER
};
enum { /* special EA flags */
EAF_BYTEOFFS = 1, /* force offset part to byte size */
EAF_WORDOFFS = 2, /* force offset part to [d]word size */
EAF_TIMESTWO = 4 /* really do EAX*2 not EAX+EAX */
};
enum { /* values for `hinttype' */
EAH_NOHINT = 0, /* no hint at all - our discretion */
EAH_MAKEBASE = 1, /* try to make given reg the base */
EAH_NOTBASE = 2 /* try _not_ to make reg the base */
};
typedef struct { /* operand to an instruction */
long type; /* type of operand */
int addr_size; /* 0 means default; 16; 32 */
int basereg, indexreg, scale; /* registers and scale involved */
int hintbase, hinttype; /* hint as to real base register */
long segment; /* immediate segment, if needed */
long offset; /* any immediate number */
long wrt; /* segment base it's relative to */
int eaflags; /* special EA flags */
int opflags; /* see OPFLAG_* defines below */
} operand;
#define OPFLAG_FORWARD 1 /* operand is a forward reference */
#define OPFLAG_EXTERN 2 /* operand is an external reference */
typedef struct extop { /* extended operand */
struct extop *next; /* linked list */
long type; /* defined above */
char *stringval; /* if it's a string, then here it is */
int stringlen; /* ... and here's how long it is */
long segment; /* if it's a number/address, then... */
long offset; /* ... it's given here ... */
long wrt; /* ... and here */
} extop;
#define MAXPREFIX 4
typedef struct { /* an instruction itself */
char *label; /* the label defined, or NULL */
int prefixes[MAXPREFIX]; /* instruction prefixes, if any */
int nprefix; /* number of entries in above */
int opcode; /* the opcode - not just the string */
int condition; /* the condition code, if Jcc/SETcc */
int operands; /* how many operands? 0-3
* (more if db et al) */
operand oprs[3]; /* the operands, defined as above */
extop *eops; /* extended operands */
int eops_float; /* true if DD and floating */
long times; /* repeat count (TIMES prefix) */
int forw_ref; /* is there a forward reference? */
} insn;
enum geninfo { GI_SWITCH };
/*
* ------------------------------------------------------------
* The data structure defining an output format driver, and the
* interfaces to the functions therein.
* ------------------------------------------------------------
*/
struct ofmt {
/*
* This is a short (one-liner) description of the type of
* output generated by the driver.
*/
const char *fullname;
/*
* This is a single keyword used to select the driver.
*/
const char *shortname;
/*
* this is reserved for out module specific help.
* It is set to NULL in all the out modules but is not implemented
* in the main program
*/
const char *helpstring;
/*
* this is a pointer to the first element of the debug information
*/
struct dfmt **debug_formats;
/*
* and a pointer to the element that is being used
* note: this is set to the default at compile time and changed if the
* -F option is selected. If developing a set of new debug formats for
* an output format, be sure to set this to whatever default you want
*
*/
struct dfmt *current_dfmt;
/*
* This, if non-NULL, is a NULL-terminated list of `char *'s
* pointing to extra standard macros supplied by the object
* format (e.g. a sensible initial default value of __SECT__,
* and user-level equivalents for any format-specific
* directives).
*/
const char **stdmac;
/*
* This procedure is called at the start of an output session.
* It tells the output format what file it will be writing to,
* what routine to report errors through, and how to interface
* to the label manager and expression evaluator if necessary.
* It also gives it a chance to do other initialisation.
*/
void (*init) (FILE *fp, efunc error, ldfunc ldef, evalfunc eval);
/*
* This procedure is called to pass generic information to the
* object file. The first parameter gives the information type
* (currently only command line switches)
* and the second parameter gives the value. This function returns
* 1 if recognized, 0 if unrecognized
*/
int (*setinfo)(enum geninfo type, char **string);
/*
* This procedure is called by assemble() to write actual
* generated code or data to the object file. Typically it
* doesn't have to actually _write_ it, just store it for
* later.
*
* The `type' argument specifies the type of output data, and
* usually the size as well: its contents are described below.
*/
void (*output) (long segto, const void *data, unsigned long type,
long segment, long wrt);
/*
* This procedure is called once for every symbol defined in
* the module being assembled. It gives the name and value of
* the symbol, in NASM's terms, and indicates whether it has
* been declared to be global. Note that the parameter "name",
* when passed, will point to a piece of static storage
* allocated inside the label manager - it's safe to keep using
* that pointer, because the label manager doesn't clean up
* until after the output driver has.
*
* Values of `is_global' are: 0 means the symbol is local; 1
* means the symbol is global; 2 means the symbol is common (in
* which case `offset' holds the _size_ of the variable).
* Anything else is available for the output driver to use
* internally.
*
* This routine explicitly _is_ allowed to call the label
* manager to define further symbols, if it wants to, even
* though it's been called _from_ the label manager. That much
* re-entrancy is guaranteed in the label manager. However, the
* label manager will in turn call this routine, so it should
* be prepared to be re-entrant itself.
*
* The `special' parameter contains special information passed
* through from the command that defined the label: it may have
* been an EXTERN, a COMMON or a GLOBAL. The distinction should
* be obvious to the output format from the other parameters.
*/
void (*symdef) (char *name, long segment, long offset, int is_global,
char *special);
/*
* This procedure is called when the source code requests a
* segment change. It should return the corresponding segment
* _number_ for the name, or NO_SEG if the name is not a valid
* segment name.
*
* It may also be called with NULL, in which case it is to
* return the _default_ section number for starting assembly in.
*
* It is allowed to modify the string it is given a pointer to.
*
* It is also allowed to specify a default instruction size for
* the segment, by setting `*bits' to 16 or 32. Or, if it
* doesn't wish to define a default, it can leave `bits' alone.
*/
long (*section) (char *name, int pass, int *bits);
/*
* This procedure is called to modify the segment base values
* returned from the SEG operator. It is given a segment base
* value (i.e. a segment value with the low bit set), and is
* required to produce in return a segment value which may be
* different. It can map segment bases to absolute numbers by
* means of returning SEG_ABS types.
*
* It should return NO_SEG if the segment base cannot be
* determined; the evaluator (which calls this routine) is
* responsible for throwing an error condition if that occurs
* in pass two or in a critical expression.
*/
long (*segbase) (long segment);
/*
* This procedure is called to allow the output driver to
* process its own specific directives. When called, it has the
* directive word in `directive' and the parameter string in
* `value'. It is called in both assembly passes, and `pass'
* will be either 1 or 2.
*
* This procedure should return zero if it does not _recognise_
* the directive, so that the main program can report an error.
* If it recognises the directive but then has its own errors,
* it should report them itself and then return non-zero. It
* should also return non-zero if it correctly processes the
* directive.
*/
int (*directive) (char *directive, char *value, int pass);
/*
* This procedure is called before anything else - even before
* the "init" routine - and is passed the name of the input
* file from which this output file is being generated. It
* should return its preferred name for the output file in
* `outname', if outname[0] is not '\0', and do nothing to
* `outname' otherwise. Since it is called before the driver is
* properly initialised, it has to be passed its error handler
* separately.
*
* This procedure may also take its own copy of the input file
* name for use in writing the output file: it is _guaranteed_
* that it will be called before the "init" routine.
*
* The parameter `outname' points to an area of storage
* guaranteed to be at least FILENAME_MAX in size.
*/
void (*filename) (char *inname, char *outname, efunc error);
/*
* This procedure is called after assembly finishes, to allow
* the output driver to clean itself up and free its memory.
* Typically, it will also be the point at which the object
* file actually gets _written_.
*
* One thing the cleanup routine should always do is to close
* the output file pointer.
*/
void (*cleanup) (int debuginfo);
};
/*
* values for the `type' parameter to an output function. Each one
* must have the actual number of _bytes_ added to it.
*
* Exceptions are OUT_RELxADR, which denote an x-byte relocation
* which will be a relative jump. For this we need to know the
* distance in bytes from the start of the relocated record until
* the end of the containing instruction. _This_ is what is stored
* in the size part of the parameter, in this case.
*
* Also OUT_RESERVE denotes reservation of N bytes of BSS space,
* and the contents of the "data" parameter is irrelevant.
*
* The "data" parameter for the output function points to a "long",
* containing the address in question, unless the type is
* OUT_RAWDATA, in which case it points to an "unsigned char"
* array.
*/
#define OUT_RAWDATA 0x00000000UL
#define OUT_ADDRESS 0x10000000UL
#define OUT_REL2ADR 0x20000000UL
#define OUT_REL4ADR 0x30000000UL
#define OUT_RESERVE 0x40000000UL
#define OUT_TYPMASK 0xF0000000UL
#define OUT_SIZMASK 0x0FFFFFFFUL
/*
* ------------------------------------------------------------
* The data structure defining a debug format driver, and the
* interfaces to the functions therein.
* ------------------------------------------------------------
*/
struct dfmt {
/*
* This is a short (one-liner) description of the type of
* output generated by the driver.
*/
const char *fullname;
/*
* This is a single keyword used to select the driver.
*/
const char *shortname;
/*
* init - called initially to set up local pointer to object format,
* void pointer to implementation defined data, file pointer (which
* probably won't be used, but who knows?), and error function.
*/
void (*init) (struct ofmt * of, void * id, FILE * fp, efunc error);
/*
* linenum - called any time there is output with a change of
* line number or file.
*/
void (*linenum) (const char * filename, long linenumber, long segto);
/*
* debug_deflabel - called whenever a label is defined. Parameters
* are the same as to 'symdef()' in the output format. This function
* would be called before the output format version.
*/
void (*debug_deflabel) (char * name, long segment, long offset,
int is_global, char * special);
/*
* debug_directive - called whenever a DEBUG directive other than 'LINE'
* is encountered. 'directive' contains the first parameter to the
* DEBUG directive, and params contains the rest. For example,
* 'DEBUG VAR _somevar:int' would translate to a call to this
* function with 'directive' equal to "VAR" and 'params' equal to
* "_somevar:int".
*/
void (*debug_directive) (const char * directive, const char * params);
/*
* typevalue - called whenever the assembler wishes to register a type
* for the last defined label. This routine MUST detect if a type was
* already registered and not re-register it.
*/
void (*debug_typevalue) (long type);
/*
* debug_output - called whenever output is required
* 'type' is the type of info required, and this is format-specific
*/
void (*debug_output) (int type, void *param);
/*
* cleanup - called after processing of file is complete
*/
void (*cleanup) (void);
};
/*
* The type definition macros
* for debugging
*
* low 3 bits: reserved
* next 5 bits: type
* next 24 bits: number of elements for arrays (0 for labels)
*/
#define TY_UNKNOWN 0x00
#define TY_LABEL 0x08
#define TY_BYTE 0x10
#define TY_WORD 0x18
#define TY_DWORD 0x20
#define TY_FLOAT 0x28
#define TY_QWORD 0x30
#define TY_TBYTE 0x38
#define TY_COMMON 0xE0
#define TY_SEG 0xE8
#define TY_EXTERN 0xF0
#define TY_EQU 0xF8
#define TYM_TYPE(x) ((x) & 0xF8)
#define TYM_ELEMENTS(x) (((x) & 0xFFFFFF00) >> 8)
#define TYS_ELEMENTS(x) ((x) << 8)
/*
* -----
* Other
* -----
*/
/*
* This is a useful #define which I keep meaning to use more often:
* the number of elements of a statically defined array.
*/
#define elements(x) ( sizeof(x) / sizeof(*(x)) )
extern int tasm_compatible_mode;
/*
* This declaration passes the "pass" number to all other modules
* "pass0" assumes the values: 0, 0, ..., 0, 1, 2
* where 0 = optimizing pass
* 1 = pass 1
* 2 = pass 2
*/
extern int pass0; /* this is globally known */
extern int optimizing;
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,263 @@
/* nasmlib.h header file for nasmlib.c
*
* The Netwide Assembler is copyright (C) 1996 Simon Tatham and
* Julian Hall. All rights reserved. The software is
* redistributable under the licence given in the file "Licence"
* distributed in the NASM archive.
*/
#ifndef NASM_NASMLIB_H
#define NASM_NASMLIB_H
/*
* If this is defined, the wrappers around malloc et al will
* transform into logging variants, which will cause NASM to create
* a file called `malloc.log' when run, and spew details of all its
* memory management into that. That can then be analysed to detect
* memory leaks and potentially other problems too.
*/
/* #define LOGALLOC */
/*
* Wrappers around malloc, realloc and free. nasm_malloc will
* fatal-error and die rather than return NULL; nasm_realloc will
* do likewise, and will also guarantee to work right on being
* passed a NULL pointer; nasm_free will do nothing if it is passed
* a NULL pointer.
*/
#ifdef NASM_NASM_H /* need efunc defined for this */
void nasm_set_malloc_error (efunc);
#ifndef LOGALLOC
void *nasm_malloc (size_t);
void *nasm_realloc (void *, size_t);
void nasm_free (void *);
char *nasm_strdup (const char *);
char *nasm_strndup (char *, size_t);
#else
void *nasm_malloc_log (char *, int, size_t);
void *nasm_realloc_log (char *, int, void *, size_t);
void nasm_free_log (char *, int, void *);
char *nasm_strdup_log (char *, int, const char *);
char *nasm_strndup_log (char *, int, char *, size_t);
#define nasm_malloc(x) nasm_malloc_log(__FILE__,__LINE__,x)
#define nasm_realloc(x,y) nasm_realloc_log(__FILE__,__LINE__,x,y)
#define nasm_free(x) nasm_free_log(__FILE__,__LINE__,x)
#define nasm_strdup(x) nasm_strdup_log(__FILE__,__LINE__,x)
#define nasm_strndup(x,y) nasm_strndup_log(__FILE__,__LINE__,x,y)
#endif
#endif
/*
* ANSI doesn't guarantee the presence of `stricmp' or
* `strcasecmp'.
*/
#if defined(stricmp) || defined(strcasecmp)
#if defined(stricmp)
#define nasm_stricmp stricmp
#else
#define nasm_stricmp strcasecmp
#endif
#else
int nasm_stricmp (const char *, const char *);
#endif
#if defined(strnicmp) || defined(strncasecmp)
#if defined(strnicmp)
#define nasm_strnicmp strnicmp
#else
#define nasm_strnicmp strncasecmp
#endif
#else
int nasm_strnicmp (const char *, const char *, int);
#endif
/*
* Convert a string into a number, using NASM number rules. Sets
* `*error' to TRUE if an error occurs, and FALSE otherwise.
*/
long readnum(char *str, int *error);
/*
* Convert a character constant into a number. Sets
* `*warn' to TRUE if an overflow occurs, and FALSE otherwise.
* str points to and length covers the middle of the string,
* without the quotes.
*/
long readstrnum(char *str, int length, int *warn);
/*
* seg_init: Initialise the segment-number allocator.
* seg_alloc: allocate a hitherto unused segment number.
*/
void seg_init(void);
long seg_alloc(void);
/*
* many output formats will be able to make use of this: a standard
* function to add an extension to the name of the input file
*/
#ifdef NASM_NASM_H
void standard_extension (char *inname, char *outname, char *extension,
efunc error);
#endif
/*
* some handy macros that will probably be of use in more than one
* output format: convert integers into little-endian byte packed
* format in memory
*/
#define WRITECHAR(p,v) \
do { \
*(p)++ = (v) & 0xFF; \
} while (0)
#define WRITESHORT(p,v) \
do { \
WRITECHAR(p,v); \
WRITECHAR(p,(v) >> 8); \
} while (0)
#define WRITELONG(p,v) \
do { \
WRITECHAR(p,v); \
WRITECHAR(p,(v) >> 8); \
WRITECHAR(p,(v) >> 16); \
WRITECHAR(p,(v) >> 24); \
} while (0)
/*
* and routines to do the same thing to a file
*/
void fwriteshort (int data, FILE *fp);
void fwritelong (long data, FILE *fp);
/*
* Routines to manage a dynamic random access array of longs which
* may grow in size to be more than the largest single malloc'able
* chunk.
*/
#define RAA_BLKSIZE 4096 /* this many longs allocated at once */
#define RAA_LAYERSIZE 1024 /* this many _pointers_ allocated */
typedef struct RAA RAA;
typedef union RAA_UNION RAA_UNION;
typedef struct RAA_LEAF RAA_LEAF;
typedef struct RAA_BRANCH RAA_BRANCH;
struct RAA {
/*
* Number of layers below this one to get to the real data. 0
* means this structure is a leaf, holding RAA_BLKSIZE real
* data items; 1 and above mean it's a branch, holding
* RAA_LAYERSIZE pointers to the next level branch or leaf
* structures.
*/
int layers;
/*
* Number of real data items spanned by one position in the
* `data' array at this level. This number is 1, trivially, for
* a leaf (level 0): for a level 1 branch it should be
* RAA_BLKSIZE, and for a level 2 branch it's
* RAA_LAYERSIZE*RAA_BLKSIZE.
*/
long stepsize;
union RAA_UNION {
struct RAA_LEAF {
long data[RAA_BLKSIZE];
} l;
struct RAA_BRANCH {
struct RAA *data[RAA_LAYERSIZE];
} b;
} u;
};
struct RAA *raa_init (void);
void raa_free (struct RAA *);
long raa_read (struct RAA *, long);
struct RAA *raa_write (struct RAA *r, long posn, long value);
/*
* Routines to manage a dynamic sequential-access array, under the
* same restriction on maximum mallocable block. This array may be
* written to in two ways: a contiguous chunk can be reserved of a
* given size, and a pointer returned, or single-byte data may be
* written. The array can also be read back in the same two ways:
* as a series of big byte-data blocks or as a list of structures
* of a given size.
*/
struct SAA {
/*
* members `end' and `elem_len' are only valid in first link in
* list; `rptr' and `rpos' are used for reading
*/
struct SAA *next, *end, *rptr;
long elem_len, length, posn, start, rpos;
char *data;
};
struct SAA *saa_init (long elem_len); /* 1 == byte */
void saa_free (struct SAA *);
void *saa_wstruct (struct SAA *); /* return a structure of elem_len */
void saa_wbytes (struct SAA *, const void *, long); /* write arbitrary bytes */
void saa_rewind (struct SAA *); /* for reading from beginning */
void *saa_rstruct (struct SAA *); /* return NULL on EOA */
void *saa_rbytes (struct SAA *, long *); /* return 0 on EOA */
void saa_rnbytes (struct SAA *, void *, long); /* read a given no. of bytes */
void saa_fread (struct SAA *s, long posn, void *p, long len); /* fixup */
void saa_fwrite (struct SAA *s, long posn, void *p, long len); /* fixup */
void saa_fpwrite (struct SAA *, FILE *);
#ifdef NASM_NASM_H
/*
* Standard scanner.
*/
extern char *stdscan_bufptr;
void stdscan_reset(void);
int stdscan (void *private_data, struct tokenval *tv);
#endif
#ifdef NASM_NASM_H
/*
* Library routines to manipulate expression data types.
*/
int is_reloc(expr *);
int is_simple(expr *);
int is_really_simple (expr *);
int is_unknown(expr *);
int is_just_unknown(expr *);
long reloc_value(expr *);
long reloc_seg(expr *);
long reloc_wrt(expr *);
#endif
/*
* Binary search routine. Returns index into `array' of an entry
* matching `string', or <0 if no match. `array' is taken to
* contain `size' elements.
*/
int bsi (char *string, const char **array, int size);
char *src_set_fname(char *newname);
long src_set_linnum(long newline);
long src_get_linnum(void);
/*
* src_get may be used if you simply want to know the source file and line.
* It is also used if you maintain private status about the source location
* It return 0 if the information was the same as the last time you
* checked, -1 if the name changed and (new-old) if just the line changed.
*/
int src_get(long *xline, char **xname);
void nasm_quote(char **str);
char *nasm_strcat(char *one, char *two);
void nasmlib_cleanup(void);
void null_debug_routine(const char *directive, const char *params);
extern struct dfmt null_debug_form;
extern struct dfmt *null_debug_arr[2];
#endif

View file

@ -0,0 +1,321 @@
/* ndisasm.c the Netwide Disassembler main module
*
* The Netwide Assembler is copyright (C) 1996 Simon Tatham and
* Julian Hall. All rights reserved. The software is
* redistributable under the licence given in the file "Licence"
* distributed in the NASM archive.
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <errno.h>
#include "insns.h"
#include "nasm.h"
#include "nasmlib.h"
#include "sync.h"
#include "disasm.h"
#define BPL 8 /* bytes per line of hex dump */
static const char *help =
"usage: ndisasm [-a] [-i] [-h] [-r] [-u] [-b bits] [-o origin] [-s sync...]\n"
" [-e bytes] [-k start,bytes] [-p vendor] file\n"
" -a or -i activates auto (intelligent) sync\n"
" -u sets USE32 (32-bit mode)\n"
" -b 16 or -b 32 sets number of bits too\n"
" -h displays this text\n"
" -r or -v displays the version number\n"
" -e skips <bytes> bytes of header\n"
" -k avoids disassembling <bytes> bytes from position <start>\n"
" -p selects the preferred vendor instruction set (intel, amd, cyrix, idt)\n";
static void output_ins (unsigned long, unsigned char *, int, char *);
static void skip (unsigned long dist, FILE *fp);
int main(int argc, char **argv)
{
unsigned char buffer[INSN_MAX * 2], *p, *q;
char outbuf[256];
char *pname = *argv;
char *filename = NULL;
unsigned long nextsync, synclen, initskip = 0L;
int lenread;
long lendis;
int autosync = FALSE;
int bits = 16;
int eof = FALSE;
unsigned long prefer = 0;
int rn_error;
long offset;
FILE *fp;
offset = 0;
init_sync();
while (--argc) {
char *v, *vv, *p = *++argv;
if (*p == '-' && p[1]) {
p++;
while (*p) switch (tolower(*p)) {
case 'a': /* auto or intelligent sync */
case 'i':
autosync = TRUE;
p++;
break;
case 'h':
fprintf(stderr, help);
return 0;
case 'r':
case 'v':
fprintf(stderr, "NDISASM version %s compiled " __DATE__ "\n", NASM_VER);
return 0;
case 'u': /* USE32 */
bits = 32;
p++;
break;
case 'b': /* bits */
v = p[1] ? p+1 : --argc ? *++argv : NULL;
if (!v) {
fprintf(stderr, "%s: `-b' requires an argument\n", pname);
return 1;
}
if (!strcmp(v, "16"))
bits = 16;
else if (!strcmp(v, "32"))
bits = 32;
else {
fprintf(stderr, "%s: argument to `-b' should"
" be `16' or `32'\n", pname);
}
p = ""; /* force to next argument */
break;
case 'o': /* origin */
v = p[1] ? p+1 : --argc ? *++argv : NULL;
if (!v) {
fprintf(stderr, "%s: `-o' requires an argument\n", pname);
return 1;
}
offset = readnum (v, &rn_error);
if (rn_error) {
fprintf(stderr, "%s: `-o' requires a numeric argument\n",
pname);
return 1;
}
p = ""; /* force to next argument */
break;
case 's': /* sync point */
v = p[1] ? p+1 : --argc ? *++argv : NULL;
if (!v) {
fprintf(stderr, "%s: `-s' requires an argument\n", pname);
return 1;
}
add_sync (readnum (v, &rn_error), 0L);
if (rn_error) {
fprintf(stderr, "%s: `-s' requires a numeric argument\n",
pname);
return 1;
}
p = ""; /* force to next argument */
break;
case 'e': /* skip a header */
v = p[1] ? p+1 : --argc ? *++argv : NULL;
if (!v) {
fprintf(stderr, "%s: `-e' requires an argument\n", pname);
return 1;
}
initskip = readnum (v, &rn_error);
if (rn_error) {
fprintf(stderr, "%s: `-e' requires a numeric argument\n",
pname);
return 1;
}
p = ""; /* force to next argument */
break;
case 'k': /* skip a region */
v = p[1] ? p+1 : --argc ? *++argv : NULL;
if (!v) {
fprintf(stderr, "%s: `-k' requires an argument\n", pname);
return 1;
}
vv = strchr(v, ',');
if (!vv) {
fprintf(stderr, "%s: `-k' requires two numbers separated"
" by a comma\n", pname);
return 1;
}
*vv++ = '\0';
nextsync = readnum (v, &rn_error);
if (rn_error) {
fprintf(stderr, "%s: `-k' requires numeric arguments\n",
pname);
return 1;
}
synclen = readnum (vv, &rn_error);
if (rn_error) {
fprintf(stderr, "%s: `-k' requires numeric arguments\n",
pname);
return 1;
}
add_sync (nextsync, synclen);
p = ""; /* force to next argument */
break;
case 'p': /* preferred vendor */
v = p[1] ? p+1 : --argc ? *++argv : NULL;
if (!v) {
fprintf(stderr, "%s: `-p' requires an argument\n", pname);
return 1;
}
if ( !strcmp(v, "intel") ) {
prefer = 0; /* Default */
} else if ( !strcmp(v, "amd") ) {
prefer = IF_AMD|IF_3DNOW;
} else if ( !strcmp(v, "cyrix") ) {
prefer = IF_CYRIX|IF_3DNOW;
} else if ( !strcmp(v, "idt") || !strcmp(v, "centaur") ||
!strcmp(v, "winchip") ) {
prefer = IF_3DNOW;
} else {
fprintf(stderr, "%s: unknown vendor `%s' specified with `-p'\n", pname, v);
return 1;
}
p = ""; /* force to next argument */
break;
default: /*bf*/
fprintf(stderr, "%s: unrecognised option `-%c'\n",
pname, *p);
return 1;
}
} else if (!filename) {
filename = p;
} else {
fprintf(stderr, "%s: more than one filename specified\n", pname);
return 1;
}
}
if (!filename) {
fprintf(stderr, help, pname);
return 0;
}
if (strcmp(filename, "-")) {
fp = fopen(filename, "rb");
if (!fp) {
fprintf(stderr, "%s: unable to open `%s': %s\n",
pname, filename, strerror(errno));
return 1;
}
} else
fp = stdin;
if (initskip > 0)
skip (initskip, fp);
/*
* This main loop is really horrible, and wants rewriting with
* an axe. It'll stay the way it is for a while though, until I
* find the energy...
*/
p = q = buffer;
nextsync = next_sync (offset, &synclen);
do {
unsigned long to_read = buffer+sizeof(buffer)-p;
if (to_read > nextsync-offset-(p-q))
to_read = nextsync-offset-(p-q);
if (to_read) {
lenread = fread (p, 1, to_read, fp);
if (lenread == 0)
eof = TRUE; /* help along systems with bad feof */
} else
lenread = 0;
p += lenread;
if ((unsigned long)offset == nextsync) {
if (synclen) {
fprintf(stdout, "%08lX skipping 0x%lX bytes\n", offset, synclen);
offset += synclen;
skip (synclen, fp);
}
p = q = buffer;
nextsync = next_sync (offset, &synclen);
}
while (p > q && (p - q >= INSN_MAX || lenread == 0)) {
lendis = disasm (q, outbuf, bits, offset, autosync, prefer);
if (!lendis || lendis > (p - q) ||
(unsigned long)lendis > nextsync-offset)
lendis = eatbyte (q, outbuf);
output_ins (offset, q, lendis, outbuf);
q += lendis;
offset += lendis;
}
if (q >= buffer+INSN_MAX) {
unsigned char *r = buffer, *s = q;
int count = p - q;
while (count--)
*r++ = *s++;
p -= (q - buffer);
q = buffer;
}
} while (lenread > 0 || !(eof || feof(fp)));
if (fp != stdin)
fclose (fp);
return 0;
}
static void output_ins (unsigned long offset, unsigned char *data,
int datalen, char *insn)
{
int bytes;
fprintf(stdout, "%08lX ", offset);
bytes = 0;
while (datalen > 0 && bytes < BPL) {
fprintf(stdout, "%02X", *data++);
bytes++;
datalen--;
}
fprintf(stdout, "%*s%s\n", (BPL+1-bytes)*2, "", insn);
while (datalen > 0) {
fprintf(stdout, " -");
bytes = 0;
while (datalen > 0 && bytes < BPL) {
fprintf(stdout, "%02X", *data++);
bytes++;
datalen--;
}
fprintf(stdout, "\n");
}
}
/*
* Skip a certain amount of data in a file, either by seeking if
* possible, or if that fails then by reading and discarding.
*/
static void skip (unsigned long dist, FILE *fp)
{
char buffer[256]; /* should fit on most stacks :-) */
/*
* Got to be careful with fseek: at least one fseek I've tried
* doesn't approve of SEEK_CUR. So I'll use SEEK_SET and
* ftell... horrible but apparently necessary.
*/
if (fseek (fp, dist+ftell(fp), SEEK_SET)) {
while (dist > 0) {
unsigned long len = (dist < sizeof(buffer) ?
dist : sizeof(buffer));
if (fread (buffer, 1, len, fp) < len) {
perror("fread");
exit(1);
}
dist -= len;
}
}
}

View file

@ -0,0 +1,11 @@
/* automatically generated from ./regs.dat - do not edit */
static const int creg [] = {R_CR0,R_CR1,R_CR2,R_CR3,R_CR4,R_CR5,R_CR6,R_CR7};
static const int dreg [] = {R_DR0,R_DR1,R_DR2,R_DR3,R_DR4,R_DR5,R_DR6,R_DR7};
static const int fpureg [] = {R_ST0,R_ST1,R_ST2,R_ST3,R_ST4,R_ST5,R_ST6,R_ST7};
static const int mmxreg [] = {R_MM0,R_MM1,R_MM2,R_MM3,R_MM4,R_MM5,R_MM6,R_MM7};
static const int reg16 [] = {R_AX,R_CX,R_DX,R_BX,R_SP,R_BP,R_SI,R_DI};
static const int reg32 [] = {R_EAX,R_ECX,R_EDX,R_EBX,R_ESP,R_EBP,R_ESI,R_EDI};
static const int reg8 [] = {R_AL,R_CL,R_DL,R_BL,R_AH,R_CH,R_DH,R_BH};
static const int sreg [] = {R_ES,R_CS,R_SS,R_DS,R_FS,R_GS,R_SEGR6,R_SEGR7};
static const int treg [] = {R_TR0,R_TR1,R_TR2,R_TR3,R_TR4,R_TR5,R_TR6,R_TR7};
static const int xmmreg [] = {R_XMM0,R_XMM1,R_XMM2,R_XMM3,R_XMM4,R_XMM5,R_XMM6,R_XMM7};

View file

@ -0,0 +1,83 @@
/* automatically generated from ./regs.dat - do not edit */
static const char *reg_names[] = {
"ah",
"al",
"ax",
"bh",
"bl",
"bp",
"bx",
"ch",
"cl",
"cr0",
"cr1",
"cr2",
"cr3",
"cr4",
"cr5",
"cr6",
"cr7",
"cs",
"cx",
"dh",
"di",
"dl",
"dr0",
"dr1",
"dr2",
"dr3",
"dr4",
"dr5",
"dr6",
"dr7",
"ds",
"dx",
"eax",
"ebp",
"ebx",
"ecx",
"edi",
"edx",
"es",
"esi",
"esp",
"fs",
"gs",
"mm0",
"mm1",
"mm2",
"mm3",
"mm4",
"mm5",
"mm6",
"mm7",
"segr6",
"segr7",
"si",
"sp",
"ss",
"st0",
"st1",
"st2",
"st3",
"st4",
"st5",
"st6",
"st7",
"tr0",
"tr1",
"tr2",
"tr3",
"tr4",
"tr5",
"tr6",
"tr7",
"xmm0",
"xmm1",
"xmm2",
"xmm3",
"xmm4",
"xmm5",
"xmm6",
"xmm7"
};

View file

@ -0,0 +1,84 @@
/* automatically generated from ./regs.dat - do not edit */
enum reg_enum {
R_AH = EXPR_REG_START,
R_AL,
R_AX,
R_BH,
R_BL,
R_BP,
R_BX,
R_CH,
R_CL,
R_CR0,
R_CR1,
R_CR2,
R_CR3,
R_CR4,
R_CR5,
R_CR6,
R_CR7,
R_CS,
R_CX,
R_DH,
R_DI,
R_DL,
R_DR0,
R_DR1,
R_DR2,
R_DR3,
R_DR4,
R_DR5,
R_DR6,
R_DR7,
R_DS,
R_DX,
R_EAX,
R_EBP,
R_EBX,
R_ECX,
R_EDI,
R_EDX,
R_ES,
R_ESI,
R_ESP,
R_FS,
R_GS,
R_MM0,
R_MM1,
R_MM2,
R_MM3,
R_MM4,
R_MM5,
R_MM6,
R_MM7,
R_SEGR6,
R_SEGR7,
R_SI,
R_SP,
R_SS,
R_ST0,
R_ST1,
R_ST2,
R_ST3,
R_ST4,
R_ST5,
R_ST6,
R_ST7,
R_TR0,
R_TR1,
R_TR2,
R_TR3,
R_TR4,
R_TR5,
R_TR6,
R_TR7,
R_XMM0,
R_XMM1,
R_XMM2,
R_XMM3,
R_XMM4,
R_XMM5,
R_XMM6,
R_XMM7,
REG_ENUM_LIMIT
};

View file

@ -0,0 +1,112 @@
/* sync.c the Netwide Disassembler synchronisation processing module
*
* The Netwide Assembler is copyright (C) 1996 Simon Tatham and
* Julian Hall. All rights reserved. The software is
* redistributable under the licence given in the file "Licence"
* distributed in the NASM archive.
*/
#include <stdio.h>
#include <stdlib.h>
#include <limits.h>
#include "sync.h"
#define SYNC_MAX 4096 /* max # of sync points */
/*
* This lot manages the current set of sync points by means of a
* heap (priority queue) structure.
*/
static struct Sync {
unsigned long pos;
unsigned long length;
} *synx;
static int nsynx;
void init_sync(void)
{
/*
* I'd like to allocate an array of size SYNC_MAX, then write
* `synx--' which would allow numbering the array from one
* instead of zero without wasting memory. Sadly I don't trust
* this to work in 16-bit Large model, so it's staying the way
* it is. Btw, we don't care about freeing this array, since it
* has to last for the duration of the program and will then be
* auto-freed on exit. And I'm lazy ;-)
*
* Speaking of 16-bit Large model, that's also the reason I'm
* not declaring this array statically - by doing it
* dynamically I avoid problems with the total size of DGROUP
* in Borland C.
*/
synx = malloc((SYNC_MAX+1) * sizeof(*synx));
if (!synx) {
fprintf(stderr, "ndisasm: not enough memory for sync array\n");
exit(1);
}
nsynx = 0;
}
void add_sync(unsigned long pos, unsigned long length)
{
int i;
if (nsynx == SYNC_MAX)
return; /* can't do anything - overflow */
nsynx++;
synx[nsynx].pos = pos;
synx[nsynx].length = length;
for (i = nsynx; i > 1; i /= 2) {
if (synx[i/2].pos > synx[i].pos) {
struct Sync t;
t = synx[i/2]; /* structure copy */
synx[i/2] = synx[i]; /* structure copy again */
synx[i] = t; /* another structure copy */
}
}
}
unsigned long next_sync(unsigned long position, unsigned long *length)
{
while (nsynx > 0 && synx[1].pos + synx[1].length <= position) {
int i, j;
struct Sync t;
t = synx[nsynx]; /* structure copy */
synx[nsynx] = synx[1]; /* structure copy */
synx[1] = t; /* ditto */
nsynx--;
i = 1;
while (i*2 <= nsynx) {
j = i*2;
if (synx[j].pos < synx[i].pos &&
(j+1 > nsynx || synx[j+1].pos > synx[j].pos)) {
t = synx[j]; /* structure copy */
synx[j] = synx[i]; /* lots of these... */
synx[i] = t; /* ...aren't there? */
i = j;
} else if (j+1 <= nsynx && synx[j+1].pos < synx[i].pos) {
t = synx[j+1]; /* structure copy */
synx[j+1] = synx[i]; /* structure <yawn> copy */
synx[i] = t; /* structure copy <zzzz....> */
i = j+1;
} else
break;
}
}
if (nsynx > 0) {
if (length)
*length = synx[1].length;
return synx[1].pos;
} else {
if (length)
*length = 0L;
return ULONG_MAX;
}
}

View file

@ -0,0 +1,16 @@
/* sync.h header file for sync.c
*
* The Netwide Assembler is copyright (C) 1996 Simon Tatham and
* Julian Hall. All rights reserved. The software is
* redistributable under the licence given in the file "Licence"
* distributed in the NASM archive.
*/
#ifndef NASM_SYNC_H
#define NASM_SYNC_H
void init_sync(void);
void add_sync(unsigned long position, unsigned long length);
unsigned long next_sync(unsigned long position, unsigned long *length);
#endif

View file

@ -0,0 +1 @@
0.98.38

View file

@ -0,0 +1,9 @@
#ifndef NASM_VERSION_H
#define NASM_VERSION_H
#define NASM_MAJOR_VER 0
#define NASM_MINOR_VER 98
#define NASM_SUBMINOR_VER 38
#define NASM_PATCHLEVEL_VER 0
#define NASM_VERSION_ID 0x00622600
#define NASM_VER "0.98.38"
#endif /* NASM_VERSION_H */

View file

@ -0,0 +1,16 @@
#ifndef _plugin_ndisasm_ndisasm_h_
#define _plugin_ndisasm_ndisasm_h_
NAMESPACE_UPP
static const int NDISASM_INSN_MAX = 32; // one instruction can't be longer than this
static const int NDISASM_OUTBUF_SIZE = 256; // maximum length of disassembly output
#ifdef CPU_32
int NDisassemble(char *output, const byte *data, long offset); // returns instruction length
#else
int NDisassemble(char *output, const byte *data, int64 offset); // returns instruction length
#endif
END_UPP_NAMESPACE
#endif

View file

@ -0,0 +1,25 @@
description "Disassembler (GPL license - used in TheIDE)";
uses
Core;
file
ndisasm.h,
ndisupp.cpp,
lib/ndisasm readonly separator,
lib\disasm.c tabsize 8,
lib\disasm.h,
lib\insns.h,
lib\insnsd.c tabsize 8,
lib\insnsi.h,
lib\nasm.h,
lib\nasmlib.c tabsize 8,
lib\nasmlib.h,
lib\regs.c tabsize 8,
lib\regs.h,
lib\sync.c tabsize 8,
lib\sync.h,
lib\version.h,
lib\AUTHORS,
lib\COPYING;

View file

@ -0,0 +1,37 @@
#include <Core/Core.h>
#include "ndisasm.h"
extern "C" {
#include "lib/disasm.h"
}
NAMESPACE_UPP
#ifdef CPU_32
int NDisassemble(char *output, const byte *data, long offset)// returns instruction length
#else
int NDisassemble(char *output, const byte *data, int64 offset)// returns instruction length
#endif
{
unsigned preferences = 0; // see lib/insns.h(84)
long len = (long)disasm(const_cast<unsigned char *>(data), output, 32, offset, false, preferences);
if(len <= 0) {
eatbyte(const_cast<unsigned char *>(data), output);
len = 1;
}
return (int)len;
}
#ifdef flagMAIN
CONSOLE_APP_MAIN
{
long start = 0x4012f8, end = start + 256;
while(start < end) {
char line[NDISASM_OUTBUF_SIZE];
start += NDisassemble(line, (const byte *)start, start);
puts(line);
}
}
#endif
END_UPP_NAMESPACE