Compare commits

..

463 commits

Author SHA1 Message Date
H. Peter Anvin (Intel)
fbdc88565c AUTHORS: update maintainer for 2+, no longer with Intel
Some checks failed
NASM CI/CD / Build and test (push) Failing after 4s
NASM CI/CD / Build with MSVC (Windows) (push) Has been cancelled
Even though NASM is now using 3.xx version numbers, I'm still the main
maintainer :)

2026-08-15 was my last day employed by Intel Corporation, so anything
since are not their copyright.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
2026-08-19 16:45:00 -07:00
H. Peter Anvin (Intel)
b2734a91bd output/outobj.c: free the section name on cleanup
It is a completely unimportant memory leak as the process is about to
exit, but it is easy to clean up.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-07-07 15:43:40 -07:00
H. Peter Anvin (Intel)
9248a85f97 asm/error.c: handle -w* during command line parsing
During command line parsing, warning_state_init is NULL as the warning
stack is naturally not set up yet. Furthermore, -w* would mean return
to command-line default, which isn't even defined yet.

Rather than ignoring it or returning an error, do something useful by
allowing -w* to reset to the *compile time* default when specified on
the command line.

Reported-by: <momo-trip@github.com>
Fixes: https://github.com/netwide-assembler/nasm/issues/155
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-07-07 15:43:40 -07:00
H. Peter Anvin (Intel)
63abf28933 doc/source.src: remove note about "make warnings"
The idea of embedded warning documentation text in the source code was
a cute idea, but the resulting build dependency mess really made it
more painful than it was worth.

The warning declarations were moved to asm/warnings.dat quite a while
ago; remove stray note in the documentation.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-07-07 15:43:40 -07:00
H. Peter Anvin (Intel)
6393f99455 doc/pspdf.pl: fix Ghostscript executable path construction on Windows
win32_gs_help() looks up Ghostscript's install directory (GS_LIB) from
the registry and then tries to locate gswin64c.exe/gswin32c.exe/gs.exe
in it, but used File::Spec->catpath($p, $exe) to build the candidate
path. catpath() takes three arguments (volume, directory, file); called
with only two, $exe is interpreted as the directory and the file
component is left undef, so the result is just $exe on its own --
never a path that actually exists -- meaning the registry-based lookup
silently always failed and pspdf.pl fell back to a bare 'gs' on PATH
(which choco's ghostscript package does not add). Use catfile($p, $exe)
instead, which is the correct call for joining a directory and a
filename. Confirmed via real MSVC CI that Ghostscript is now found
purely from the registry, matching doc/source.src's documented
requirement that Ghostscript need not be on PATH.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-07 15:26:53 -07:00
H. Peter Anvin (Intel)
8317d7ae2f Mkfiles/msvc.mak: make the docs: target actually work under real nmake
The docs: target fed doc/Makefile.in directly to nmake, but that file
relies on several GNU make-only constructs nmake cannot parse at all:
the $^ automatic variable (not valid nmake macro syntax -- fatal
parse error), $< used outside of an inference rule (silently
unsupported, since nmake only defines $< within .SUFFIXES-style
rules), and the GNU-only "-include *.dep" optional wildcard include
directive (nmake only understands the unrelated "!include"
directive). Add tools/mkmsvcdocmak.pl, which rewrites just those
constructs to their explicit nmake-safe equivalents in a generated
copy (doc/Makefile.msvc), leaving doc/Makefile.in itself untouched for
the Unix/GNU make build. Verified by rewriting doc/Makefile.in this
way and building nasmdoc.pdf through it with GNU make standing in for
nmake.

Also, doc/Makefile.in expects doc/warnings.src, doc/perlbreq.src and
doc/pptok.src to have already been generated -- the Unix "doc" target
does this via the top-level Makefile.in before recursing into doc/,
but msvc.mak's docs: target had no equivalent step. warnings.src and
pptok.src already had msvc.mak rules (just not wired up as
prerequisites of docs:); perlbreq.src had no rule at all, since the
top-level Makefile.in generates it with a POSIX find/sed pipeline that
doesn't translate to Windows. Add tools/genperlbreq.pl, a portable
pure-Perl equivalent (using File::Find), and a doc\perlbreq.src rule
in msvc.mak that uses it; verified it produces output byte-identical
to the existing POSIX pipeline.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-07 15:26:53 -07:00
H. Peter Anvin (Intel)
5d727e1253 Mkfiles/msvc.mak: document docs rule's tool requirements
Note that building the documentation via the "docs" nmake target
requires Ghostscript and the Roboto/Roboto Mono fonts, per
doc/source.src. This target previously also had to work around
doc/Makefile.in containing a bare, unexpanded "@SET_MAKE@" line
(fixed in the preceding commit), which made it a hard nmake parse
error; that workaround is no longer needed.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-07 15:26:53 -07:00
H. Peter Anvin (Intel)
56200857e2 build: only use @SET_MAKE@ in the top-level Makefile.in
@SET_MAKE@ (AC_PROG_MAKE_SET) is a legacy autoconf substitution needed
only for very old Unix make implementations that don't automatically
propagate $(MAKE) to recursively invoked sub-makes. Every Makefile.in
in the tree carried its own copy, but that's unnecessary: exporting
MAKE once, from the top-level Makefile.in, is sufficient for it to
reach any sub-make invoked (directly or transitively) from there.

Replace the top-level @SET_MAKE@ with the pair "@SET_MAKE@" followed
by "export MAKE", and drop the now-redundant @SET_MAKE@ line from
doc/Makefile.in, misc/Makefile.in and test/Makefile.in.

This incidentally fixes doc/Makefile.in being usable when fed directly
to nmake (as Mkfiles/msvc.mak's "docs" rule does, since it predates
running ./configure): a bare "@SET_MAKE@" line, left unexpanded, is
not a valid nmake assignment or rule and previously caused a hard
parse error (U1035, "expected ':' or '=' separator").

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-07 15:26:53 -07:00
H. Peter Anvin (Intel)
186be201d5 ci: build the Windows NSIS installer in the MSVC job
Install NSIS via choco (not preinstalled on windows-latest), Ghostscript
via choco, and the Roboto/Roboto Mono fonts (matching the exact
versions Fedora's google-roboto-fonts and google-roboto-mono-fonts
packages ship, dropped straight into %windir%\Fonts, which
doc/findfont.ph's directory-scan fallback picks up without needing
font registration). Then run 'nmake docs' (builds nasmdoc.pdf via
NASM's own Perl-based doc toolchain, which needs exactly those tools --
see doc/source.src) followed by 'nmake nsis' to produce the installer
via nsis/nasm.nsi, and upload it as a workflow artifact.

Ghostscript is located by doc/pspdf.pl via the Windows registry keys
the official installer creates, not via PATH, so no PATH setup is
needed for it.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-07 15:26:53 -07:00
H. Peter Anvin (Intel)
c68bf5ef57 ci: add a real-MSVC (cl.exe/nmake) build job
Add a build-msvc job on windows-latest that uses
step-security/msvc-dev-cmd to set up the MSVC developer environment,
builds NASM with 'nmake /f Mkfiles/msvc.mak', and smoke-tests the
resulting nasm.exe/ndisasm.exe by assembling and disassembling a tiny
program and building a win64 object file.

step-security/msvc-dev-cmd is a StepSecurity-maintained, drop-in
replacement for the more widely known ilammy/msvc-dev-cmd@v1 action;
the latter's newest release (v1.13.0, Jan 2024) still targets the
now-deprecated Node.js 20 runtime with no newer release in sight,
while step-security's fork tracks Node.js 24.

This is the first CI coverage of the MSVC build path (Mkfiles/msvc.mak
+ config/msvc.h), which previously had no automated verification.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-07 13:22:36 -07:00
H. Peter Anvin (Intel)
ace0078261 file.c: include <windows.h> before <stringapiset.h>
nasmlib/file.c included <stringapiset.h> directly (for
MultiByteToWideChar()/CompareStringOrdinal()) without first including
<windows.h>. Windows SDK headers like <stringapiset.h> are only
guaranteed to work when pulled in through the normal <windows.h>
pipeline, which sets up SDK-internal architecture macros (_X86_,
_AMD64_, ...) derived from the compiler's own _M_IX86/_M_X64/etc.
Including them directly skips that setup and can fail with a
'No Target Architecture' #error from <winnt.h> -- which is exactly
what happened building with a real cl.exe/nmake in CI.

<windows.h> is deliberately *not* pulled in globally from compiler.h:
it #defines NEAR and FAR as legacy no-op calling-convention keywords,
which clash with NASM's own NEAR/FAR opflags bits (include/opflags.h).
Keep the inclusion local to file.c, the only file that currently needs
Windows API declarations, guarded by WIN32_LEAN_AND_MEAN to keep the
exposed surface minimal.

Confirmed fixed with a real MSVC (cl.exe/nmake) build in CI.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-07 13:12:06 -07:00
H. Peter Anvin (Intel)
e2f38a8aed config/msvc.h: fill in gaps versus configure.ac/config.h.in
Cross-referenced configure.ac's AC_CHECK_HEADERS/AC_CHECK_FUNCS/PA_*
tests (as materialized into config/config.h.in) against config/msvc.h
and added definitions for macros MSVC actually supports:

- HAVE_STDARG_H, HAVE_STDIO_H, HAVE_WCHAR_H: always present.
- HAVE_STDINT_H: available starting with Visual Studio 2010
  (_MSC_VER >= 1600).
- HAVE_INTRIN_H plus an #include <intrin.h>, gated on Visual Studio
  2005 (_MSC_VER >= 1400) when the header was introduced.
- HAVE_ISCNTRL: always present.
- HAVE_ISASCII plus '#define isascii __isascii', since MSVC only
  provides the underscore-prefixed spelling.
- HAVE__BYTESWAP_USHORT/_ULONG/_UINT64: always present, declared in
  <stdlib.h>, matching the names PA_FIND_FUNC probes for in
  autoconf/m4/pa_endian.m4.
- HAVE__BITSCANREVERSE (>=1400) and HAVE__BITSCANREVERSE64 (>=1400 and
  only on _M_X64/_M_ARM64, since the 64-bit intrinsic does not exist
  on 32-bit x86).
- HAVE_UNSIGNED_LONG_LONG_INT: always present.
- HAVE_UINTMAX_T, gated on '#ifdef HAVE_STDINT_H' rather than a
  separate version check, with a textual 'unsigned long long'
  fallback for uintmax_t otherwise; gating strictly on HAVE_STDINT_H
  avoids the fallback macro clobbering <stdint.h>'s own uintmax_t
  typedef when both would otherwise be available.

Deliberately left out anything that is POSIX/GNU/BSD-only or does not
exist verbatim on MSVC (strcasecmp/strsep/strlcpy/mempcpy, getuid/
getrlimit/realpath, GCC __builtin_*/attribute probes, byteswap.h/
endian.h family, C23 stdbit.h, etc.), since compiler.h and the
relevant call sites already handle those cases separately for MSVC.

Verified with x86_64-w64-mingw32-gcc -fsyntax-only using manually
defined _MSC_VER/_M_X64/_M_ARM64 across Visual Studio versions
1310/1400/1600/1800/1929 (mingw-w64 declares the same intrinsics in
the expected headers), then confirmed end-to-end with a real MSVC
(cl.exe/nmake) build in CI.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-07 12:57:50 -07:00
H. Peter Anvin (Intel)
18c778c590 files: formalize storing "mapped" file names in the filenames system
Formalize the mechanism for storing mapped (non-filesystem) filenames
in the filenames array. These are not compared against input or output
files for overwrite checks.

Add the infrastructure for comparing more than one input filename
(future proofing.)

Move the Makefile dependency target name to the filenames system.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-07-06 17:08:01 -07:00
H. Peter Anvin (Intel)
339ee194fc files: use nasm_compare_paths()
Instead of doing a simple string comparison, call nasm_compare_paths()
to compare infile and outfile paths.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-07-06 17:06:49 -07:00
H. Peter Anvin (Intel)
1c3d3dc554 nasmlib: add path name comparison function
Add nasm_compare_paths(). At this point, the only effect is wide
character/case insensitivity canonicalization on Windows, but in the
future it might be doing things like comparing st_dev:st_inode pairs
on Unix or compare nasm_realpath().

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-07-06 16:57:38 -07:00
H. Peter Anvin (Intel)
86c6b34bd3 Rename travis.mk[.in] -> travis.mak[.in]
Rename travis.mk to .mak to match the convention for all other
Makefiles in the tree (that aren't simply named "Makefile".)

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-07-06 14:09:02 -07:00
H. Peter Anvin (Intel)
75024b8109 test: remove test/performtest.pl and redirect {test,golden} targets
Remove the long-since-unmaintained test/performtest.pl script and
redirect the "test" and "golden" Makefile targets to their respective
travis targets.

The test/ directory still has two important functions:

1. Running ad hoc tests manually. The test/ directory has
   infrastructure for running a quick test manually in a large number
   of configurations. This is highly useful during development.

2. It contains the infrastructure for running regression tests on
   external applications, far too big to include into NASM itself.

Reported-by: Ross Burton <ross@burtonini.com>
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-07-06 13:58:35 -07:00
H. Peter Anvin (Intel)
c0b64a692b Mkfiles/: sync with Makefile.in
Sync the standalone Makefiles with Makefile.in (adding
x86/insns-cc.ph.)

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-07-06 13:54:38 -07:00
H. Peter Anvin (Intel)
87968c3596 editors/nasmtok.pl: break nasmtok.json into lines
Instead of generating one single huge line of text, add newlines after
suitable commas to make it at least a manageable text file.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-07-04 19:58:07 -07:00
H. Peter Anvin (Intel)
620dd315ee editors/builtin.mac: sync with executable (pick up the list options macros)
Regenerate editors/buildin.mac to pick up the new list options macros.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-07-04 19:52:16 -07:00
Joshua Watt
851460a10b Add --debug-prefix-map option
Adds an option to remap file prefixes in output object files. This is
analogous to the "-fdebug-prefix-map" option in GCC, and allows files to
be built in a reproducible manner regardless of the build directory.

[ hpa: this still needs to be documented in doc/running.src. ]

Signed-off-by: Joshua Watt <JPEWhacker@gmail.com>
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-07-04 19:22:48 -07:00
H. Peter Anvin (Intel)
c577f357d1 travis: disable the cv8struc test
The cv8struc test ends up with embedded absolute pathnames. This is a
known problem with the reproducibility of this test (see
https://github.com/netwide-assembler/nasm/pull/8) and so disable it
for now, as it generates false positive failures.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-07-04 19:12:12 -07:00
H. Peter Anvin (Intel)
87e9a45891 github: save travis.log from CI/CD tests
It is more or less impossible to debug CI/CD test failures without
this file, so make github keep a copy of it.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-07-04 19:05:08 -07:00
H. Peter Anvin (Intel)
c138d532fb github: update test.yml to be compatible with newer requirements
The test.yml file uses actions/checkout@v4, which apparently is being
deprecated; bump to @v6 (using Node.js 24) instead.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-07-04 18:52:44 -07:00
H. Peter Anvin (Intel)
081a097909 testgen: document %ifdef ERROR error-case coverage
Adds a "Error-case (%ifdef ERROR) coverage" section describing the
needs64/avoid64 dual-source design and the nasm-t.py json convention
reused from travis/ret/ret.json, notes on the two branch-operand bugs
discovered and fixed along the way, and updates the "Known
limitations" and "Validation" sections with the final 2612/10
mnemonic counts and 1976/2612 error-coverage numbers.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-04 13:43:20 -07:00
H. Peter Anvin (Intel)
eee1384bf5 testgen: add %ifdef ERROR error-case coverage, fix branch-operand bugs
Add error-case ("negative test") coverage per the user's preferred
convention: rather than a separate source file, error-triggering
instruction lines are appended to the existing per-mnemonic .asm file
under a %ifdef ERROR guard, and the harness assembles the same file
twice -- once without -DERROR (existing positive-path coverage,
unaffected) and once with -DERROR (expected to fail, per nasm-t.py's
"error": "expected" json convention, matching the pre-existing
travis/ret/ret.json pattern).

The error material comes for free from lines the generator already
knows are bit-width-incompatible:

- Lines needing 64-bit encodings (reg64/imm64 operands, hireg r8-r15,
  apxreg r16-r31, etc. -- %needs64_token / build_variant_line) are, by
  construction, exactly the lines already excluded from the 16/32-bit
  "narrow" body. They're appended to the narrow file under %ifdef
  ERROR and probed at --bits 16/32 with -DERROR; only widths where the
  block actually fails become json entries.

- Symmetrically, CALL/JMP near-indirect targets via rm16/rm32 (only
  rm64 is valid in 64-bit mode -- confirmed empirically, matches the
  NOLONG flag on those insns.xda templates) are appended to the full
  (64-bit) body under %ifdef ERROR and probed at --bits 64 with
  -DERROR.

Each candidate block is probed before being turned into a json entry,
so a line that unexpectedly *does* assemble at some width (this
generator doesn't model every mode restriction) doesn't turn into a
bogus "expected error" test; a mnemonic whose *only* surviving
coverage would be error entries is also rejected (see below), since
"this never assembles" isn't meaningful regression coverage on its
own.

While wiring this up, discovered and fixed two related bugs in the
existing branch-mnemonic handling (gen_operand()'s is_branch
substitution):

1. is_branch replaced *every* operand of a branch mnemonic with the
   ".L1" local-label text, not just genuine relative/near/short/abs
   branch-displacement operands. This produced nonsensical lines like
   "loop .L1, .L1" (LOOP's address-size-override form takes a fixed
   "cx"/"ecx"/"rcx" second operand, not a branch target) and "call
   .L1" for JMP/CALL's indirect (rm16/32/64) and far-pointer
   (imm16:imm16) forms instead of an actual register/memory operand.
   These bogus lines silently poisoned assembly for the whole
   mnemonic, and LOOP/LOOPE/LOOPNE/LOOPNZ/LOOPZ/JCXZ were silently
   dropped entirely as a result (present in the "16 dropped" list).
   Restricting the substitution to base tokens matching
   /^imm(?:8|16|32|64)$/ fixes both LOOP's operand and JMP/CALL's
   indirect/far forms, and recovers all six previously-dropped
   mnemonics with correct coverage.

2. Once (1) exposed genuine rm16/rm32 operand generation for CALL/JMP,
   a new bit-width interaction appeared: rm16/rm32 near-indirect
   targets are only valid in 16/32-bit mode (unlike ordinary reg16/32
   operands elsewhere, which work at any bit width), so a line built
   from one now broke 64-bit assembly for the whole mnemonic the same
   way a needs64 line breaks 16/32-bit assembly. Added
   branch_narrow_only() and a parallel avoid64 line flag (mirroring
   needs64) to exclude these lines from the 64-bit "full" body -- this
   is also what feeds the new symmetric 64-bit error-case coverage
   described above.

Also added a safety-net to the existing "couldn't assemble in any
mode, drop the directory" check: a directory is now only kept if it
has at least one *non*-error json entry, preventing a future bug
symmetric to (1) from silently producing a directory whose only
content is error-case entries.

Verified via full scratch regeneration (2612 mnemonics generated / 10
dropped, up from 2606/16 thanks to the LOOP-family/JCXZ fix) +
nasm-t.py run (10918/10918 PASS, 0 FAIL) + per-mnemonic non-error
.json entry-count diff against the prior committed tree (identical
except the 6 newly-recovered mnemonics, confirming no regressions).
1976/2612 mnemonics gained at least one error-case entry (3951 error
json entries total). Regenerated travis/insns/ and validated via
'make -j32 travis' (all PASS, ~27s).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-04 13:41:59 -07:00
H. Peter Anvin (Intel)
6de2898d8d testgen: document implicitly-sized memory operand coverage
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-04 12:39:10 -07:00
H. Peter Anvin (Intel)
5422294119 testgen: add implicitly-sized memory operand coverage
For instruction operand tokens that carry an explicit size in their own
name (mem8/16/32/64/..., rm8/16/32/64, xmmrm.../ymmrm256/zmmrm512,
mmxrm/mmxrm64), the generator previously always emitted an explicit size
keyword (e.g. "dword", "oword") for the memory operand. This never
exercised NASM's SM-flag-driven implicit-size-inference path, where the
size of an ambiguous memory operand is inferred from a paired
already-sized operand (typically a same-width register) in the same
instruction template (e.g. ADD reg32,rm32 or MOVBE reg32,mem32 don't
need an explicit size keyword).

Add build_implicitsize_line(), which replaces the first memory-capable
operand whose base token has a nonzero %mem_sizebits entry with a bare
(size-keyword-free) memory operand, leaving all other operands as
normally generated. As with the other coverage buckets (hireg, apxreg,
mask/maskz/broadcast/saeer, disp8/32 boundary), the candidate line is
routed through the shared cumulative staged probe and only kept if it
actually assembles for that instruction -- this avoids needing to parse
and replicate NASM's own SM/AR flag-driven operand-size-disambiguation
logic.

Note: for tokens with no size in their own name (plain "mem"), the
existing mem_operand($rng, 0) generator path already omits the size
keyword unconditionally, so that half of implicit-size coverage was
already exercised prior to this change; only explicitly-sized tokens
needed the new candidate.

Verified via full scratch regeneration (2606 mnemonics / 16 dropped,
unchanged) + nasm-t.py run (6955/6955 PASS, 0 FAIL) + per-mnemonic
.json entry-count diff against the prior committed tree (zero
differences, confirming no bit-width regressions). 1922/2606
mnemonics gained new implicit-size coverage lines. Regenerated
travis/insns/ and validated via 'make -j32 travis' (all PASS, ~26s).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-04 12:38:36 -07:00
H. Peter Anvin (Intel)
5d8ec1742c tools/testgen: document disp8/disp32 boundary coverage in README
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-04 12:22:30 -07:00
H. Peter Anvin (Intel)
941aa2ba16 testgen: add modrm-memory disp8/disp32 boundary coverage
Extend gen-insn-tests.pl to synthesize, for every distinct template
across a mnemonic's entire template set that has a modrm-memory-
capable operand (mem*, rm*, xmmrm*/ymmrm256/zmmrm512, mmxrm*), two
additional candidate lines using [eax+1] and [eax+64] addressing in
place of that operand's usual bare-displacement or register form.

Whether an instruction has a disp8-encodable form (or, for EVEX, what
its compressed-displacement scale factor is) is instruction-specific,
so rather than computing the exact boundary per instruction these two
fixed offsets are used as a baseline: +1 is unambiguously disp8-
encodable everywhere, and +64 lands past the disp8 boundary for
byte-granular encodings while still being a clean multiple of the
larger EVEX compressed-displacement scales.

[eax+N] (rather than a bare displacement, or a bit-width-specific base
register) is used because it's valid addressing syntax at every
--bits width via the 0x67 address-size prefix, confirmed empirically.
Candidates are routed through the same staged, cumulative probe as the
hireg/apxreg/EVEX-decorator buckets, so one bad candidate (e.g. an
instruction with memory-operand restrictions this generator doesn't
model) can't cost a mnemonic its pre-existing coverage.

Regenerated travis/insns/ (2606 mnemonics, 16 dropped, unchanged from
before; 1987 mnemonics gained at least one disp-boundary line).
Validated: nasm-t.py run against a scratch regeneration is 6955/6955
PASS/0 FAIL with per-mnemonic bit-width success counts identical to
the previous committed baseline, and make -j32 travis passes in ~26s.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-04 12:21:31 -07:00
H. Peter Anvin (Intel)
fe6bb359e4 tools/testgen: document EVEX decorator coverage in README
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-04 12:07:02 -07:00
H. Peter Anvin (Intel)
1ac35569b1 testgen: add EVEX decorator coverage (mask/{z}/broadcast/sae/er)
Extend gen-insn-tests.pl to recognize the four independent EVEX
decorator families encoded in insns.xda operand tokens (|mask, |z,
|b16|b32|b64, |sae|er) and synthesize additional candidate lines
exercising each:

  - mask:      {k1}-{k7} appended to the marked register/memory operand
  - maskz:     mask + trailing {z} (zeroing), only where |z co-occurs
  - broadcast: {1toN} on a memory operand, N derived from the token's
               vector width (xmm/ymm/zmm or explicit mem/rm size) and
               the b16/b32/b64 element-width marker
  - sae/er:    a separate trailing {sae} or {rn|rd|ru|rz-sae} pseudo-
               operand, only legal when the marked operand resolves to
               a register sized per the token's own declared width
               (e.g. rm64|er needs a 64-bit register, not rm32)

Candidate lines are generated once per *distinct* template across each
mnemonic's entire template set, not just the capped per-mnemonic
sample -- EVEX/AVX512 forms are frequently appended well after a
mnemonic's plain SSE/AVX forms in insns.xda (e.g. VMOVAPD's mask-on-
memory-destination forms), so relying on the sample alone would
silently skip them for many mnemonics.

Generalized the item-2 hireg/apxreg staged-fallback probe into a
per-category, cumulative probing loop over all six extra-line buckets
(hireg, apxreg, mask, maskz, broadcast, saeer): each candidate bucket
is tentatively merged into the accepted line set and kept only if the
result still assembles, avoiding the combinatorial blowup of trying
every subset as the number of independent categories grows.

Regenerated travis/insns/ (2606 mnemonics, 16 dropped, unchanged from
before). Validated: nasm-t.py run against a scratch regeneration is
6955/6955 PASS/0 FAIL (identical per-mnemonic bit-width success counts
to the committed baseline), and make -j32 travis passes in ~26s.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-04 12:05:56 -07:00
H. Peter Anvin (Intel)
6ca6b03467 tools/testgen: document high-register-number coverage in README
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-04 11:40:34 -07:00
H. Peter Anvin (Intel)
629cf75c3d tools/testgen: cover high register numbers (r8-r15, r16-r31)
Add register-number-focused coverage for every operand-class token that
has a hireg (r8-r15 / xmm-zmm8-15) or apxreg (r16-r31 / xmm-zmm16-31)
tier: registers 8+ only exist in 64-bit mode (they need a REX prefix,
or REX2/EVEX register-extension bits for 16-31), so this coverage is
64-bit-only regardless of the base token's own size.

Per template with at least one such token, generate one extra all-hireg
and one extra all-apxreg instruction line (once per template, not once
per --variants instance). Since NASM's own template-matching engine
transparently selects an alternate (e.g. APX/EVEX-encoded) pattern when
the operand syntax calls for it, the generator doesn't need to special-
case APX/EVEX iflags to decide whether extended registers are legal for
a given mnemonic -- it can simply try assembling and keep whichever
combination works. A staged-fallback probe (try hireg+apxreg, then
hireg alone, then apxreg alone, then neither) avoids letting one
genuinely-incompatible extra line (e.g. NOAPX/NOLONG-only mnemonics)
cost the whole mnemonic its pre-existing 64-bit coverage; the probe
checks --bits 16/32 too whenever a mnemonic's *only* templates need
64-bit registers regardless of number (e.g. URDMSR/UWRMSR), since in
that case the generated 'full' file is reused for every bit width.

Also fixes a latent bug: xmmreg/ymmreg/zmmreg previously drew uniformly
from registers 0-15, but 8-15 needs 64-bit mode just like the GPR
case -- so a template could non-deterministically lose its 16/32-bit
coverage whenever the RNG happened to land on 8-15 (e.g. ADDPD was
missing bin16/bin32 goldens before this fix). Register pools are now
split into explicit low (0-7)/hireg (8-15)/apxreg (16-31) tiers per
register class, threaded through gen_operand() via a new
parameter (defaulting to the existing 'low' behavior at all pre-
existing call sites).

Regenerated travis/insns/ (2606 mnemonics, 16 dropped -- unchanged
counts). Full suite validated via make -j32 travis: all tests PASS in
~27s.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-04 11:38:35 -07:00
H. Peter Anvin (Intel)
1891551544 tools/testgen: document optional-operand coverage in README
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-04 11:05:11 -07:00
H. Peter Anvin (Intel)
70dae61029 tools/testgen: cover optional (*/?) operand omitted forms
x86/insns.xda marks operands with a trailing '*' (optional source,
duplicates the previous operand in the encoding when omitted --
insns.pl's relaxed_forms() implements the actual encoding semantics for
the C generators) or '?' (optional destination, entirely absent from
the encoding when omitted, e.g. APX NDD forms). Previously the
generator always emitted every operand in a template, so the
omitted-operand parsing/encoding path was never exercised, and
reg8?/reg16?/reg32?-marked templates fell back to the generic '?'-
unaware base_token() lookup and were silently dropped as unsupported
(only the reg64? case happened to have an explicit, redundant table
entry).

base_token() now strips a trailing '?' the same way it already stripped
'*', so all four reg#?  variants resolve to their plain register
generator (the redundant explicit reg8?/16?/32?/64? %gen entries are
removed as now-dead code). A new optional_operand_index() locates the
(at most one, per insns.xda) marked operand in a template, and the
per-mnemonic driver emits one additional reduced-arity instruction line
per template (dropping that operand) alongside the existing full-arity
line, so both forms get captured as goldens.

Regenerated travis/insns/ (2606 mnemonics, 16 dropped -- unchanged counts,
since this only adds coverage lines to existing mnemonic asm files, not
new mnemonics). Full suite validated via make -j32 travis: all tests
PASS in ~26s.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-04 11:04:49 -07:00
H. Peter Anvin (Intel)
35016d4880 x86/insns.pl, tools/testgen: share cc/scc condition-code tables
Extract the condition-code suffix table (%conds, @conds, and the
c_ccmask/c_nd/c_cc/c_scc bitmasks) out of x86/insns.pl's
conditional_forms() into a new shared x86/insns-cc.ph module, adding
cc_suffix_list($is_scc) to return the suffix list applicable to a
'...cc'-family (Jcc, SETcc, CMOVcc, CFCMOVcc) or '...scc'-family
(CCMPscc, CTESTscc, CMPccXADD, SETccZU) placeholder mnemonic. insns.pl
is refactored to use it (behavior-preserving: verified byte-identical
x86/insnsa.c, insnsb.c, insnsd.c, insnsi.h, insnsn.c, iflag.c,
iflaggen.h, asm/tokhash.c, asm/tokens.h before/after).

tools/testgen/gen-insn-tests.pl now requires the same module instead
of hand-rolling a 16-suffix 'cc'-only expansion table, closing the gap
where the APX 'scc'-suffix families (CCMPscc/CTESTscc/CMPccXADD/
SETccZU) were dropped as unsupported. The generator now detects and
expands any '...cc'/'...scc' placeholder mnemonic the same way
insns.pl's conditional_forms() does (case-sensitive /s?cc/ match and
substitution), so future new cc/scc families need no generator
changes. Mnemonics with generated tests: 2432 -> 2606 (+174, one per
newly-expanded scc-family condition); dropped: 20 -> 16.

Regenerated travis/insns/ (174 new mnemonic dirs for the APX scc
families; existing 2432 regenerated byte-identically, confirming
determinism). Full suite validated both via
tools/travis/nasm-t.py --directory=./travis run (4427 total, 4426
PASS, 1 pre-existing SKIP, 0 FAIL) and via make -j32 travis (all
tests PASS, ~28s).

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-02 00:05:47 -07:00
H. Peter Anvin (Intel)
c95b04bc7d tools/testgen: add README documenting design, usage, and limitations
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-01 23:44:51 -07:00
H. Peter Anvin (Intel)
28bf46e532 tools/testgen: pseudorandom instruction test generator
Add gen-insn-tests.pl, a prototype tool that generates one travis test
directory per non-pseudo instruction mnemonic (asm + json + golden
output), by parsing x86/insns.xda (the already-generated, macro-
expanded, one-template-per-line intermediate NASM produces from
insns.dat) rather than insnsa.c/insnsb.c or hooking insns.pl.

Rationale: insnsa.c/insnsb.c encode operands as opaque bitmask
constants and index into an explicitly-unstable, shared bytecode array
(x86/bytecode.txt: byte codes can be moved and recycled at any time),
making them fragile/high-effort to parse from outside insns.pl.
insns.xda already provides exactly the needed semantic info (mnemonic,
comma-separated operand-type tokens, flags) in a small stable text
grammar, with zero changes to insns.pl or the build. We only need
valid operand *syntax* per operand-type token -- NASM picks the
encoding itself from mnemonic + operand syntax -- so the generated
tests are regression tests against a golden captured from a known-good
nasm build, consistent with the rest of travis/.

Includes UNDOC/OBSOLETE/NEVER-flagged instructions (only PSEUDO
pseudo-ops are excluded): where these emit an expected warning (e.g.
-w+obsolete-removed), the generator declares a stderr target so the
warning text itself becomes part of the golden, verifying the warning
fires rather than skipping the coverage.

Delegates golden capture to tools/travis/nasm-t.py update instead of
re-implementing it, so goldens get the harness's existing correctness
properties (reproducible-build NASMENV, path-embedding conventions,
etc.) for free.

Generated travis/insns/<mnemonic>/ for all 2432 assemblable mnemonics
(16/32/64-bit variants as applicable). Full suite validated via
tools/travis/nasm-t.py: 4225 total, 4224 PASS, 1 pre-existing SKIP,
0 FAIL.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-07-01 23:42:14 -07:00
H. Peter Anvin (Intel)
73abe9374b travis: run from a Makefile to parallelize testing
The travis tool itself runs all tests it is given in series. Use make
to parallelize running the tests, leaving a log in each subdirectory
in addition to the global log.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-30 23:12:52 -07:00
H. Peter Anvin (Intel)
7f69cf689c travis: reorganize directories, add tests from the test/ directory
This is a mostly automated, partially AI-assisted migration of tests
from the test/ directory into the travis framework.

Running tests manually in the test/ directory is still supported, but
move common include files into travis/test and add a default -I option
to Makefile.in in the test/ directory.

The incbin test fails for pre-existing reasons; for now it contains an
stderr file with the errors. The problem is that INCBIN is both a
macro and a special instruction (not even a directive...), but there
currently is no way to handle prefixes, *especially* TIMES, in
multi-line macros. This is a separate problem and needs to be dealt
with as such.

Reorganize the travis directory so that each test or collection of
tests are in a separate subdirectory of travis/, and travis itself
lives in tools/travis to avoid creating deeper paths.

Add support for recording compression options in the travis .json
files, so that compressed files can be recreated with the same
options: because of the generally repetitive nature of the binary
output test files, the parameters used for xz compression can matter
enormously.

These are combined into a single huge commit to avoid adding large
binary files into the repository that then would immediately be
obsoleted, but still retained in git.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-30 20:54:46 -07:00
H. Peter Anvin (Intel)
3cc3654e08 travis: replace riprel.stderr reference file xz file
Compress this quite large file with xz now when travis supports
xz-compressed reference files.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-30 19:19:58 -07:00
H. Peter Anvin (Intel)
c460d1112f travis: support .xz compressed golden reference files
Some tests may by necessity generate very large output files. Allow
.xz compression of the reference files to avoid bloating the git
repository too much. The committer of very large files will need to
carefully consider the xz options used to maximize compressibility
especially of highly regular files.

This commit was AI-assisted (Copilot/Claude Sonnet 5).

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-30 19:16:59 -07:00
H. Peter Anvin (Intel)
386f5d44f7 test/amx: suppress obsolete-removed warning for TMMULTF32PS
TMMULTF32PS was retagged never, suppress the warning to avoid a travis
failure.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-30 17:22:13 -07:00
H. Peter Anvin (Intel)
844f409f8d x86/insns.dat: make TMMULTF32PS as NEVER
The TMMULTF32PS instruction will not be implemented, mark it as NEVER.

Reported-by: Christian Ludloff <ludloff@github.com>
Fixes: https://github.com/netwide-assembler/nasm/issues/259
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-30 14:07:21 -07:00
Nick Clifton
8890d723d0 outobj: fix buffer overflow when too many segments in a group
The number of entries in a group was hard-coded, but not enforced.

Reported-by: <BreakingBad6@github.com>
Fixes: https://github.com/netwide-assembler/nasm/issues/203
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-29 18:22:44 -07:00
H. Peter Anvin (Intel)
dad1d8ca42 outbin: register the mapfile; check for input clobber; remove on fail
- Register the map file with the filename system.
- Check to see if the mapfile is clobbering the input.
- Remove the map file if the output file is also removed.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-29 18:22:39 -07:00
H. Peter Anvin (Intel)
720a32672c Refactor the handling of primary input/output files
Replace the direct setting of variables for input and output variables
with accessors. This allows for properly tracking the lifetimes of the
data and allows for things like checking of the overwrite of the
primary input file to be centralized.

It isn't possible *in the general case* to check for overwrite of
*any* of the input files, although in the particularly important case
of the assembler proper it ought to be possible to do a bit better:

it should be able to guard for overwrites of non-primary input files
except for the error file or the list file if and only if -Lp is used.

That is, however, a latter project.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-29 18:22:26 -07:00
H. Peter Anvin (Intel)
9d94cac7ae nasmlib/file: add nasm_remove()
Add nasm_remove() to mangle a filename if necessary before calling
an OS-specific remove() function. This allows calling _wremove() on
Windows.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-29 13:30:03 -07:00
H. Peter Anvin (Intel)
9000d56aec doc: fix the example for saving and restoring list options
The example used %define but it really needs to use %xdefine in order
to snapshot the value of __?LIST_OPTIONS?__.

Tidy it up a little as well.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-29 07:10:26 -07:00
H. Peter Anvin (Intel)
4a56d66ed9 NASM 3.02 2026-06-28 20:37:13 -07:00
H. Peter Anvin (Intel)
47f1cd8ede test: add test for %pragma list options and __?LIST_OPTIONS*?__
A simple test for tweaking the list options from the source code.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-28 20:35:56 -07:00
H. Peter Anvin (Intel)
27500eee7f preproc.c: check do_delete_Token() actually has a token
It seems pretty clear from the API that [do_]delete_Token() always was
intended to allow for a NULL option; the test for "if (tp)" is
somewhat pointless when invoking the delete_Token() macro which does a
do_delete_Token(&(t)).

Add in the null check to *tp as well.

Fixes: https://github.com/netwide-assembler/nasm/issues/176
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-28 20:18:43 -07:00
H. Peter Anvin (Intel)
9969b34454 listing: add __?LIST_OPTIONS?__ and __?LIST_OPTIONS_DEFAULT?__ macros
Add macros to query the current state of the listing options, add
appropriate documentation.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-28 20:13:30 -07:00
H. Peter Anvin (Intel)
06f9a1855e listing.[ch]: allow ! to be used in %pragma and * to reset to cmdline
Do allow the ! as a wildcard for all options to be used in %pragma as
well as on the command line.

Keep track of the command-line default to allow the * modifier (like
warnings) to reset to the command-line default.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-28 20:04:25 -07:00
H. Peter Anvin (Intel)
8fe7600cde NASM 3.02rc13 2026-06-28 19:04:16 -07:00
H. Peter Anvin (Intel)
640c7e0f5b preproc: fix memory leak: long tokens never freed
When tokens exceeded INLINE_TEXT, free_Token() had managed to miss
freeing the allocated token buffer.

This is different from the pull request merely in forward-porting the
change to the current code base.

Reported-by: <sorokin@github.com>
Fixes: https://github.com/netwide-assembler/nasm/pull/70
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-28 18:55:25 -07:00
H. Peter Anvin (Intel)
096c82e141 fpu.asm: test a few more syntax combinations
This also underscores the missing "to" forms of some instructions, but
that is not a regression of any kind; in fact seems to have been there
since the very beginning.

It is probably so that we should use the 2-operand forms as the
preferred disassembly forms, but that's a totally different task.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-28 18:41:20 -07:00
H. Peter Anvin (Intel)
4d18bdd318 listing: allow the user to suppress abbreviation of TIMES and INCBIN
Allow the user to suppress the abbreviation of the output from TIMES
(and therefore ALIGN) and INCBIN.

Sync the documentation with the help text, too.

Fixes: https://github.com/netwide-assembler/nasm/issues/211
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-28 18:11:40 -07:00
H. Peter Anvin (Intel)
5b9dce55cb outas86.c: fix memory leak during initialization
It is just an O(1) memory leak but might as well fix it.
filename_set_extension() returns a newly allocated string,
as86_add_string() does not consume a string reference, so the string
is left danging at the end; add nasm_free() to free it.

Reported-by: <for-just-we@github.com>
Fixes: https://github.com/netwide-assembler/nasm/issues/255
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-28 16:40:17 -07:00
H. Peter Anvin (Intel)
6051380c34 nasm.c: in preprocessor mode (-E) free the line data after printing
pp_getline() returns a string in heap storage, it needs to be freed.
This is done correctly in the other modes, but in preprocessor mode,
the freeing was missed.

This also replaces nasm_free() ... assignment with the nasm_strto()
idiom.

Reported-by: <for-just-we@github.com>
Fixes: https://github.com/netwide-assembler/nasm/issues/254
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-28 16:35:31 -07:00
H. Peter Anvin (Intel)
cdfe73e4b9 NASM 3.02rc12 2026-06-26 17:49:01 -07:00
H. Peter Anvin (Intel)
7bc82e7daf asm/nasm.c: fix use-after-free for -M* options in -@ files
-M* options in response files would hold on to a pointer to the new
value, but in response files that is not a persistent buffer. Make
sure to make a copy instead.

This uses the new nasm_str[dup]to() helpers.

(Note that calling nasm_free() on a NULL pointer is guaranteed safe.)

Reported-by: <BreakingBad6@github.com>
Fixes: https://github.com/netwide-assembler/nasm/issues/222
Fixes: CVE-2026-6068
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-26 17:35:33 -07:00
H. Peter Anvin (Intel)
44245e4684 Add nasm_strdupto() and nasm_strto(), to replace a string variable
It is common enough that one wants to set a string pointer to a newly
allocated string, freeing the old one if it is not NULL.

Add specific helper functions for this.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-26 17:25:23 -07:00
H. Peter Anvin (Intel)
7b4e77dae2 Drop const from the output of filename_set_extension()
filename_set_extension() always returns a newly allocated string
buffer, drop the "const" from the return type.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-26 17:24:17 -07:00
H. Peter Anvin (Intel)
e47a62ed4d nasmlib.h: modify nasm_assert_pointer() to work with void pointers
nasm_assert_pointer() would fail with newer gcc when passed a void *,
because the construct sizeof(*(p)) is invalid for void pointers, as is
sizeof(&*(p)).

Instead, make use of the fact that the ternary operator ? : requires
type compatibility between the two sides, and const volatile void * is
type-compatible with any pointer.

Since some compilers are known to elide this check when one side is
NULL, make it a explicit pointer to an arbitrary
object cast to (const volatile void *). zero_buffer[] seems a logical
choice.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-26 16:59:12 -07:00
H. Peter Anvin (Intel)
20cf91df63 NASM 3.02rc11 2026-06-26 14:40:20 -07:00
H. Peter Anvin (Intel)
24263bc4c1 doc/changes.src: document defanging of "%[i]rmacro"
Formally document in the change notes that %[i]rmacro falls back to
%[i]macro with a warning.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-26 14:39:12 -07:00
H. Peter Anvin (Intel)
139986238a editors/dumpbuiltin.sh: make a little more user-friendly
If no $NASM is defined and no nasm path has been given on the command
line, default to "../nasm".

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-26 14:35:07 -07:00
H. Peter Anvin (Intel)
3f269f2dc8 x86/insns.dat: add "UDW" as a (likely temporary) mnemonic for FF FF
sandpile.org are referring to FF FF as "UDW" for the FF FF subcase of
FF /7. Accept that mnemonic; allow it in disassembly as well until
such time as an official mnemonic exists for this pseudo-instruction
(or the opcode ends up being actually used, which would almost
certainly be a very bad thing.)

Fixes: https://github.com/netwide-assembler/nasm/issues/249
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-26 14:29:00 -07:00
H. Peter Anvin (Intel)
a55b5930b3 changes.src: document fixing $-escaped symbols in directives
Document the fix of $-escaped symbols in directives. Tidy up the
source formatting (no output change) of one of the bullet points.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-26 14:20:31 -07:00
H. Peter Anvin (Intel)
414ea824d9 directiv.c: correct the parsing of $-symbols in directives, again
1fc631a173 [directiv.c: $-hex requires nasm_isnumstart, not just nasm_isnumchar]

... was accidentally a commit of a wrong, broken version of the fix
(SIGMY: My fault (core dumped)).

Both the nasm_isidchar() and !nasm_isnumstart() checks need to be
applied to the *same* character, the one immediately after '$'.

Huge special thanks to ecm-pushbx for the quick testing and timely bug
report!

Reported-by: <ecm-pushbx@github.com>
Fixes: https://github.com/netwide-assembler/nasm/issues/252
Fixes: 1fc631a173
Fixes: 178a1b7443
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-26 14:11:19 -07:00
H. Peter Anvin (Intel)
6950581b35 NASM 3.02rc10 2026-06-25 15:16:19 -07:00
alexvoste
cfcfe9e701 asm/labels: fix memory leak in local label structures
Travis CI testing with AddressSanitizer (ASan) triggered a severe memory
leak in the assembler label tracking. Local label structures were not
properly freed during cleanup stages. This fix adds proper verification
and destruction of tracking labels, resolving the ASan memory leak.

Signed-off-by: alexvoste <alexvostedev@proton.me>
[ hpa: fixed indentation style and removed unnecessary { } ]
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-25 15:13:47 -07:00
alexvoste
3a33d83610 parser: fix invalid segment override on EQU FAR pointers
The parser incorrectly treated colons as memory segment overrides inside
EQU directives because of an inverted far_jmp_ok check. This regression
was introduced in commit 8981724. Removing the incorrect negation
restores proper parsing of FAR pointer constants.

Fixes #242

Signed-off-by: alexvoste <alexvostedev@proton.me>
2026-06-25 15:11:05 -07:00
H. Peter Anvin (Intel)
90ba5bbc23 doc: fix spelling of "syntactically"
Fix spelling error.

Fixes: https://github.com/netwide-assembler/nasm/issues/251
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-25 15:02:58 -07:00
H. Peter Anvin (Intel)
2b37c0ad75 directiv.c: include leading $ in a token if missing an identifier
When complaining about a valid token where an identifier was expected,
do include the leading $ if at all applicable to avoid confusing the
user.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-25 14:59:33 -07:00
H. Peter Anvin (Intel)
1fc631a173 directiv.c: $-hex requires nasm_isnumstart, not just nasm_isnumchar
For identifier-escapes beginning with $a-f to work, the $ hexadecimal
prefix cannot be used, nor could it ever be used, with A-F immediately
after the $. This is the main reason the $-hex has been deprecated.

When adding the non-dollarhex mode, this got accidentally promoted to
nasm_isnumchar() instead of nasm_isnumstart(), which broke using
$-escaped identifiers in directives.

To fix this properly, it would be a good thing to add a central
identifier-skipping function.

Fixes: https://github.com/netwide-assembler/nasm/issues/223
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-25 14:58:22 -07:00
H. Peter Anvin (Intel)
19125b6d46 builtin.mac: synchronize with the NASM binary
Update builtin.mac to match the current set of built-in NASM macros.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-24 15:56:50 -07:00
H. Peter Anvin (Intel)
08a369628e Rename emacstok.pl back to nasmtok.pl
This script can output more than just Emacs format these days; it is
already used to produce both Emacs and JSON output, and it seems
unlikely that we would want to create another script to output any
additional file formats.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-21 14:34:09 -07:00
H. Peter Anvin (Intel)
f0c3b0e6c7 NASM 3.02rc9
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-11 15:26:28 -07:00
H. Peter Anvin (Intel)
5e6a181fec insns.pl: fix unnecessary build reproducibility failure
Instead of sorting the list of flags by number, it sorted it by hash.

Reported-by: <bbhtt@bbhtt.in>
Fixes: https://github.com/netwide-assembler/nasm/issues/220
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-11 15:20:12 -07:00
H. Peter Anvin (Intel)
6f830c1c74 labels: handle the sequence EXTERN, GLOBAL, defined
The sequence EXTERN, GLOBAL, definition would fail, because the EXTERN
would create a pseudo-segment and consider it a definition, whereas
GLOBAL would set change it to a global definition, but leaving the
definition existing, which is not the normal case for a GLOBAL symbol
(define_label would not be called.)

Therefore, explicitly "undefine" the symbol by setting defn.defined to
0, as it would be after a GLOBAL statement, as as it is when an EXTERN
statement is followed by a definition (causing it to be implicitly
promoted to GLOBAL.)

Reported-by: E. C. Masloch <ecm-pushbx@github.com>
Reported-by: <roel-z@github.com>
Fixes: https://github.com/netwide-assembler/nasm/issues/224
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-11 15:08:27 -07:00
H. Peter Anvin (Intel)
022586090d changes.src: document %clear directive fix
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-11 14:42:55 -07:00
H. Peter Anvin (Intel)
0c9baa8f3a preproc: ensure forward process in %clear loop
The %clear loop was missing advancing to the next token. Also allow
the list to be comma-separated, like most other cases in NASM.
Reported-by: <magicelk235@gmail.com>
Fixes: https://github.com/netwide-assembler/nasm/issues/227
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-11 14:40:01 -07:00
H. Peter Anvin (Intel)
9052efaa63 preproc: warn if the user tries to use %rmacro
Unfortunately, the %rmacro and %irmacro directives were not disabled
when recursive macros were removed due to the implementation did not
work. Make them issue a warning and document that they might change in
the future.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-11 14:29:41 -07:00
Jiri Malak
8d1f35b78f open-watcom: fix Open Watcom build make file
Resolves Conflicts:
	Mkfiles/openwcom.mak
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-11 14:05:52 -07:00
H. Peter Anvin (Intel)
7b267445b6 preproc.src: document the limitations of case insensitivity
For the longest time, NASM has allowed non-ASCII characters is macros
and identifiers, but they have always been treated as opaque
bytes.

NASM has never done case insensitive matching of identifiers, only
keywords and macros. Keywords are compile-time-defined and are always
ASCII, but macros can be user-defined, so document the limitations.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-11 13:57:29 -07:00
H. Peter Anvin (Intel)
018406b870 SubmittingPatches: more up to date information about the patch format
It has not been considered valid to omit the long patch description
for a long time. Try to explain in more detail what the long patch
description is actually expected to contain.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-11 12:47:32 -07:00
H. Peter Anvin (Intel)
6015afc6d7 omfdump.c: add updates from Bernd Böckmann
Bernd Böcknann has been maintaining a fork of this tool on github:

      https://github.com/boeckmann/omfdump

Sync with his latest version. In the future it might be possible to
drop this tool from the NASM distribution entirely.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-07 21:00:04 -07:00
H. Peter Anvin (Intel)
ed8864e342 NASM 3.02rc8
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-07 20:56:10 -07:00
H. Peter Anvin (Intel)
d832776ccb Revert "parser: fix invalid segment override on EQU FAR pointers"
This reverts commit 35ffac3ea0.

This commit caused a regression, causing segment overrides to get
lost. Multiple travis tests failed as a result.

Revert this until a proper solution exists.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-07 20:54:47 -07:00
Joe Konno
6d8ea837c6 x86: fix {er} decorator placement for integer-source VCVT* instructions
For `VCVTUSI2SD`, `VCVTUSI2SS`, and `VCVTUSI2SH`, the `|er` flag in
`insns.dat` was attached to the XMM pass-through source (operand 2, the
vvvv field) rather than the integer source (operand 3, the rm field).
This caused NASM to require the embedded-rounding decorator before the
integer register rather than after it, which is wrong; the correct
syntax is `vcvtusi2ss xmm0,xmm1,eax,{rn-sae}`, not `vcvtusi2ss
xmm0,xmm1,{rn-sae},eax`.

Move `|er` to the integer source operand for all six affected entries,
and change the XMM source from `xmmreg|er` to `xmmreg*` (optional
duplicate of the destination, consistent with every other scalar
integer-to-float convert in the file).

Also fix a copy-paste error in `insns.dat` where the second `VCVTUSI2SH`
entry (W=1, rm64) was mis-labeled as `VCVTUSI2SS`.

Update `travis/test/avx512f.asm` to use the correct decorator syntax
(`reg,{rN-sae}` instead of `{rN-sae},reg`) for the ER forms of
`VCVTSI2SD`, `VCVTSI2SS`, `VCVTUSI2SD`, and `VCVTUSI2SS`; regenerate the
golden `avx512f.bin.t`. The encoded bytes are unchanged.

`travis/test/avx512f.json` had a trailing comma after the last field of
the JSON object, making it invalid JSON. Remove the trailing comma.

Signed-off-by: Joe Konno <joe.konno@intel.com>
Fixes: https://github.com/netwide-assembler/nasm/pull/229
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-07 20:23:45 -07:00
xmoezzz
d2541cb884 nasm.c: response file (-@) option parsing UAF affecting debug format selection (-F / -g)
Fixes: https://github.com/netwide-assembler/nasm/pull/189
[ hpa: added necessary cast to nasm_free() ]
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-07 20:21:09 -07:00
SEt
dee2d13f2c Proper handling of several code sections in Codeview debug information
Current Codeview implementation assumes there is only one actual code
section and all line number information is pulled there. With support
of comdat that assumption becomes incorrect, so proper generation of
line number information table per code section is required.

Also solved an issue with incorrect relocation for symbol with the
same name as some section.

New code assumes that coff_nsects doesn't change during generation of
debug information.

Fixes: https://github.com/netwide-assembler/nasm/pull/183
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-07 20:17:36 -07:00
Kacper Michajłow
1c9e16a03f output/codeview: don't panic when there is not code section
Simply skip the tables that require code section and source information.

Fixes: https://github.com/netwide-assembler/nasm/issues/216
Fixes: https://github.com/netwide-assembler/nasm/pull/178#issuecomment-4156226648
Signed-off-by: Kacper Michajłow <kasper93@gmail.com>
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-07 20:13:27 -07:00
knut st. osmundsen
05ad1e46b2 doc/outfmt.src: Documented 'function' win32/64 symbol type.
Documented the 'function' win32/64 extension to the global, extern
and static directives.

Resolved Conflicts:
	doc/outfmt.src

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-07 20:10:15 -07:00
knut st. osmundsen
c8be7b7a3f outcoff.c: Added support for 'function' type on global symbols.
Setting the symbol type is necessary for the control flow guard (CFG)
stuff on windows.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-07 20:08:03 -07:00
knut st. osmundsen
3ad8e6c533 outcoff.c: Prevent elimination of extern safeseh symbol.
Do a lookup of the symbol given to safeseh to prevent out_symdef() from
thinking it is unused.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-07 20:06:49 -07:00
knut st. osmundsen
251b9c6825 test/wrtsymtab.asm: reproducible
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-07 20:05:20 -07:00
knut st. osmundsen
06d2606b06 outcoff.c: fix warnings
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-07 20:05:20 -07:00
knut st. osmundsen
f1e4e6fe16 outcoff.c: dd symbol wrt ..symtab
Added a special symbol ..symtab for emitting the COFF symbol table
index of a symbol rather than some kind of address.  For use with ehcont
metadata and possible other stuff.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-07 20:05:20 -07:00
H. Peter Anvin (Intel)
f216d5b65d editors: rename nasmtok.pl to emacstok.pl
Rename this script to reflect its function within the NASM tree. The
output file is still called nasmtok.el, however, as it reflects its
function within an Emacs environment.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-07 20:04:50 -07:00
H. Peter Anvin (Intel)
5b4d5cf2a7 editors/nasmtok.pl: don't overquote nasm-token-lists
The definition of nasm-token-lists was double quoted: both the list
itself and the tokens inside were quoted, which is not the right
thing.

Remove the unnecessary inner quoting.

Reported-by: 8dcc <8dcc@github.com>
Fixes: https://github.com/netwide-assembler/nasm/issues/231
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-07 19:56:20 -07:00
H. Peter Anvin (Intel)
dc68633fa3 Fix tuple type for V{MOV,ADD,SUB,MUL,DIV}SH to t1s16
These use a 16-bit tuple type, not one derived from EVEX.W. All of
this is really messy... it would be better to have a much more
explicit handling of the displacement type than relying on "tuples".

Reported by: MSander-OptiCode <msander-opticode@gmail.com>
Fixes: https://github.com/netwide-assembler/nasm/issues/245
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-07 19:51:54 -07:00
H. Peter Anvin (Intel)
93bb528742 Remove nroff from configure.ac and Makefile.in
Converting nroff man pages to other formats was obsoleted with the use
of asciidoc. No need to check for them.

Reported-by: Ross Burton <rossburton@github.com>
Fixes: https://github.com/netwide-assembler/nasm/issues/236
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-07 18:27:49 -07:00
H. Peter Anvin (Intel)
471073c0d0 changes.src: update release notes
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-07 18:25:57 -07:00
alexvoste
6e8cdf8d59 x86: Fix VCVTPD2PH and add missing VMINPH/VMAXPH AVX512-FP16 instructions
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-07 18:21:52 -07:00
alexvoste
35ffac3ea0 parser: fix invalid segment override on EQU FAR pointers
The parser incorrectly treated colons as memory segment overrides inside
EQU directives because of an inverted far_jmp_ok check. This regression
was introduced in commit 8981724. Removing the incorrect negation restores
proper parsing of FAR pointer constants.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-07 18:21:39 -07:00
H. Peter Anvin (Intel)
de7a94e884 asm/preproc.c: remove unused variable bad_bracket
This variable was assigned but never used.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-04 10:52:15 -07:00
H. Peter Anvin (Intel)
0114c92101 asm/assemble.c: remove unused variable this_good
This variable was assigned but never used.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-04 10:51:49 -07:00
H. Peter Anvin (Intel)
ea675d0af7 autoconf: sync with upstream pa_option_lto.m4
This change has no effect on NASM, but syncs with the upstream
collection. RANLIB should be defaulting to : if not present.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-04 10:50:54 -07:00
H. Peter Anvin (Intel)
3ee140842f autoconf: separate -g3 and -ggdb
The -g3 and -ggdb options are really separate, treat them as
such. Trying -ggdb3 -g3 is not only inefficient, it is wrong when the
compiler supports only -ggdb.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-04 10:42:01 -07:00
H. Peter Anvin (Intel)
ccb73b72b2 autoconf: fix up search for "gcc-ar" and "gcc-ranlib"
The detection for "gcc-ar" and "gcc-ranlib" when building with LTO for
gcc was broken, fix it.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-04 10:40:50 -07:00
H. Peter Anvin (Intel)
113191195b configure.ac: if "strip" isn't found, dummy it out
There is no reason to error out if "strip" is missing.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-06-04 10:40:06 -07:00
H. Peter Anvin (Intel)
aa12d3381a NASM 3.02rc7 2026-04-22 09:10:32 -07:00
Yongjie2017
498afdba1b output/outelf.c: fix address sanitizer findings in elf output format
In elf_init, cur_path is a malloced one, and should be freed.

This patch adds a free operation by the end of the elf_init.

Signed-off-by: Yongjie Sheng (Intel) <sheng.yongjie@outlook.com>
2026-04-17 06:38:10 +08:00
Yongjie2017
b5235c49f0 asm/preproc.c: fix https://nvd.nist.gov/vuln/detail/CVE-2025-8842
When there is an ill formed assembly (e.g. a macro without a correct
ending), the assembly processing will end with a defining->refcnt
in non-zero value that further causes a nasm_assert in free_mmacro,
the nasm_assert causes a panic.

Force the defining->refcnt to zero in pp_clean_pass as a bailout.

Signed-off-by: Yongjie Sheng (Intel) <sheng.yongjie@outlook.com>
2026-04-17 06:35:57 +08:00
Yongjie2017
8c3f3fbe36 asm/preproc.c: fix https://nvd.nist.gov/vuln/detail/CVE-2025-8844
When there is an invalid radix specifier, the parse_smacro_template
set the current char pointer (cp) to NULL, but the tailing processing
of the for loop increases the cp so its value is 0x1 that deceives
the for loop condition check.

Add a NULL pointer checking on the cp after the switch statement
to quit the for loop because of the invalid radix specifier.

Signed-off-by: Yongjie Sheng (Intel) <sheng.yongjie@outlook.com>
2026-04-17 06:33:06 +08:00
H. Peter Anvin (Intel)
3cb6231581 asm/preproc.c: remove git merge crap in comment
A comment accidentally was left with a merge resolution
annotation. This was of course harmless, being in a comment, but it
shouldn't be there.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-04-10 13:21:41 -07:00
H. Peter Anvin (Intel)
97db0b96c2 NASM 3.02rc6 2026-04-10 13:18:31 -07:00
H. Peter Anvin (Intel)
e1e03770f7 asm/preproc.c: remove dead code, improve comment
ppscan() had a break; statement followed immediately by a return
statement. The latter was left over from code restructuring and is
dead code.

Remove it.

Fix a nearby comment indicating that we should not need to strip a
const from a string pointer. Probably Token::t_charptr should be
const, but it might need additional work.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-04-10 13:10:16 -07:00
H. Peter Anvin (Intel)
c8ea2d906d asm/preproc.c: fix NULL pointer on %exitrep outside %rep
When %exitrep incorrectly occurs outside a %rep block, do_exit_macro()
returns NULL, but the %exitrep code would try to set m->in_progress =
1 anyway, causing a NULL pointer dereference and crashing NASM.

Add a NULL pointer guard around this assignment; an error has already
been issued.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-04-10 13:06:34 -07:00
H. Peter Anvin (Intel)
d7c7de072f asm/preproc.c: correct the parameter string size calculation
In list_smacro_def(), the number of characters required for the
parameter string description was off by one; fix.

Improve the comment to explain the exact calculation, and make it more
explicit by specifying the calculation as (5+3+1) instead of just 9.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-04-10 13:03:51 -07:00
H. Peter Anvin (Intel)
d1e9ce5ab0 asm/preproc.c: merge end-of-input code
Normally, end of included files or special inputs should be handled by
pp_tokline(), but under some conditions it might be handled by
pp_cleanup_pass(). The latter case would assume the input was from a
file, which would cause a crash if istk->fp is NULL.

Although this should never happen, this is a good reason to merge
these two pieces of code, which ought to be doing the same thing
anyway.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-04-10 12:55:55 -07:00
InstLatx64
4bcfe7a838 AVX512BMM instructions
- 3 new AVX512BMM instructions, supported in AMD Zen6
Source: https://sourceware.org/pipermail/binutils/2025-November/145449.html

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-04-09 18:28:59 -07:00
H. Peter Anvin (Intel)
31ae053886 travis: update travis golden copy for br3392528.stderr
The format of this message has changed, change the golden copy to
match.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-04-09 18:26:43 -07:00
bonsthie
207b3727c7 elf: add support for GNU indirect function symbol type (gnu_ifunc)
This feature enables emission of IFUNC symbols for global directive.

Example syntax:
```asm
    global  func_ifunc:function

    global  func:gnu_ifunc
    func    equ func_ifunc
```
2026-04-09 18:23:57 -07:00
Raphaël Deschênes
21904008f5 doc: fix documentation for booleanizing operators
Fix the or and improve the xor

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-04-09 18:19:06 -07:00
Yongjie Sheng
8058e5df17 Add project test for cryptography-primitives
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-04-09 18:13:38 -07:00
H. Peter Anvin (Intel)
00fe1077dc Add \^ escape sequences for Ctrl characters
It is fairly common to want to represent characters like
Ctrl-Z. Instead of having to use character codes, allow these to be
coded as `\^z` or `\^Z` instead.

`\^?` is DEL.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-04-09 18:08:21 -07:00
H. Peter Anvin (Intel)
fe5235ffc9 limits: allow querying limits, and reset limits for each pass
Allow limits to be queried via a %limit() preprocessor function and a
__?NASM_LIMITS?__ macro.

Reset limits at the top of each pass. Note that the pass number limits
are checked at the *end* of the pass, so a %pragma limit will be
properly honored anyway.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-04-09 17:00:49 -07:00
H. Peter Anvin (Intel)
444ef5a122 asm/preproc.c: remove (void) on variable which is actually used
stdmac_env() actually uses nparams, so don't (void) it.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-04-09 16:54:47 -07:00
H. Peter Anvin (Intel)
4afd70f404 assemble_file(): make stall_count static
This function is invoked separately for each pass; therefore the stall
count would never get incremented. Make it a static variable to make
sure it does get incremented correctly.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-04-09 16:51:52 -07:00
H. Peter Anvin (Intel)
a9e46d4572 doc: update changes to the limit option and pragmas
Add --limit-params and the default and maximum keywords.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-04-09 15:19:36 -07:00
H. Peter Anvin (Intel)
a8d44ce956 limits: revamp the limit processor, change params limit to dynamic
Revamp the limit processor to allow a limit to have an absolute
maximum other than LIMIT_MAX_VAL.

Use LIMIT_MAX as a final enum parameter == parameter count == final
actual value + 1, which is the more usual construct and doesn't need
manual updating.

Allow setting a limit to the default value by setting it to "0" or
"default".

Accept "max" or "maximum" instead of "unlimited", specifically to
better handle the case of a fixed maximum < LIMIT_MAX_VAL.

Change the mmacro limit parameter to a dynamic limit, in case someone
needs it.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-04-09 15:12:19 -07:00
H. Peter Anvin (Intel)
e856c2e1dd asm/preproc.c: limit the mmacro parameter count to 16383
There is no conceivable way that a *specified* mmacro parameter count
of anywhere near that much would make sense, and as such almost
certainly represents an error.

Note that the code will still support varadic macros with an excessive
number of parameters.

Use int64_t to make (reasonably) sure that we actually catch
overflows.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-04-09 14:48:46 -07:00
H. Peter Anvin (Intel)
ab0cb6afcb asm/preproc.c: set MAX_TEXT to INT_MAX >> 2
There are still places in the code where "int" are used as
length. Reduce MAX_TEXT to INT_MAX >> 2 so that even adding two
lengths together should make a valid "int".

A token shouldn't be 512GB anyway...

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-04-09 13:52:13 -07:00
H. Peter Anvin (Intel)
b41191e29d warnings.dat: fix a missing "is"
Another editorial change.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-04-08 02:21:20 -07:00
H. Peter Anvin (Intel)
6f8dc8116f warnings.dat: correct regative -> negative spelling
Correct a typo.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-04-08 02:17:50 -07:00
H. Peter Anvin (Intel)
55e064dccb preproc: %env() function
Add an %env() function for expanding environment variables as a more
flexible and robust alternative to %! (the variable name can be
computed without doing weird things like %tok(%strcat("%!",...)) and a
fallback value can be specified by the user.)

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-04-08 01:14:17 -07:00
H. Peter Anvin (Intel)
cf770c08e8 changes.src: document fix to generating binary constants in smacros
Document the fix to smacro argument evaluation that caused truncation
to 63 bits.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-04-07 23:55:34 -07:00
H. Peter Anvin (Intel)
2ac469c93e preproc: for a parameter of type =x/ub, the topmost bit was lost
The buffer size passed in did not account for the terminating zero,
even though space was allocated for it. Explicitly use the size of the
buffer minus two bytes for the radix prefix instead of 64 (which is
the maximum possible number of digits, not the length of the string
buffer.)

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-04-07 23:49:00 -07:00
H. Peter Anvin (Intel)
6251fc5908 nasmlib/numstr.c: check for buflen == 0
buflen == 0 is an error, but be paranoid about it; the code already
checks for a valid base so it is better to check for a valid buffer
size as well.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-04-07 23:09:21 -07:00
H. Peter Anvin (Intel)
93c8f343d9 output/outform.c: change "Legacy alias" -> "Alias" in help text
Aliases aren't necessarily "legacy".

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-04-06 18:16:10 -07:00
H. Peter Anvin (Intel)
6b0e02de3a outform.h: add "omf", "omf2" and "os2" as aliases for obj[2]
Add aliases for the OMF object code formats.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-04-06 18:14:56 -07:00
H. Peter Anvin (Intel)
447bb02e1d Changes: document arith AL,imm8 fix
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-04-06 18:09:48 -07:00
H. Peter Anvin (Intel)
b1ee0338a3 NASM 3.02rc5 2026-04-06 17:57:13 -07:00
H. Peter Anvin (Intel)
e63209628f nasmlib/file.c: on Win32, need <stringapiset.h>
MultiByteToWideChar() and its constants are defined in
<stringapiset.h>, which is *not* included in <windows.h>.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-04-06 17:55:29 -07:00
H. Peter Anvin (Intel)
c8ce9504ca x86/insns.pl: show the correct instruction flags in comments
Adding the pattern number broke show_iflags(). This only produced
incorrect code comments and so had no actual effect, but it definitely
is not good for debugging!

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-04-06 17:42:54 -07:00
H. Peter Anvin (Intel)
0894bdae30 x86/insns.dat: remove APX flag from MSR immediate instructions
These aren't APX instructions; the vex+ annotation automatically adds
the APX flag when appropriate.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-04-06 17:16:52 -07:00
H. Peter Anvin (Intel)
fcb49f5dd6 NASM 3.02rc4 2026-04-06 16:56:18 -07:00
H. Peter Anvin (Intel)
4b37759129 nasmlib/file.c: Win32: add missing filename argument to conversion
In os_mangle_filename() with _WIN32, MultiByteToWideChar() was being
called with five arguments instead of six, missing the actual
string to convert(!)

Fixes: 5dfcfc8cab
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-04-06 16:53:11 -07:00
H. Peter Anvin (Intel)
0dd578ce68 nasmlib/alloc.c: no reason to clear q in nasm_free()
q is passed in by reference and the value of q is never examined, so
there is absolutely no reason to set q = NULL in nasm_free().

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-04-06 16:48:18 -07:00
H. Peter Anvin (Intel)
8d4733962e saa: make saa_wleb128[us]() take appropriate types; recode
Make saa_wleb128[us]() take uint64_t and int64_t, respectively, rather
than int.

Notably, if saa_wleb128u() were to receive negative int, it would have
looped forever.

Recode these functions in a style more consistent with NASM code in
general, and possibly a bit simpler.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-04-06 16:43:51 -07:00
H. Peter Anvin (Intel)
9fdc7eab6e nasmlib/path.c: filename_set_extension() missing NUL termination
filename_set_extension() with extension "" would leave the string not
NUL-terminated, because elen == 0.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-04-06 15:49:23 -07:00
Iouri Kharon
8ccb56cb10 insns.dat: add missing reg_al,imm8 (04+ opcode) to the arithmetic macro
The "reg_al,imm8" (04+ opcodes) were missing from the $arith macro.
Check via: 04 11 => must be add al, 11

Fixes: f0dc7c220d
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-04-06 15:42:47 -07:00
H. Peter Anvin (Intel)
1e494b46c1 NASM 3.02rc3 2026-03-06 18:00:05 -08:00
H. Peter Anvin (Intel)
c8fa17205b Add support for C2y-style \o and braced escapes, and \d for decimal
C2y adds \o for octal byte escapes, and allows \x, \o, or \u escape
sequences to be enclosed in braces to indicate their termination.

Add a \d sequence as a NASM extension to allow decimal bytes to be
specified.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-03-06 17:59:28 -08:00
H. Peter Anvin (Intel)
b1909cf39b listing: move LIST_* enums to listing.h
The LIST_* enums belongs in listing.h, move them there and actually
use them in listing.c.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-03-04 14:14:02 -08:00
H. Peter Anvin (Intel)
89e1d6203a assemble: for -LX emit specific template number as well
When using -LX to debug template selection, emit the specific template
number (as per insnsa.c) as well as the xda line number.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-03-04 14:12:55 -08:00
H. Peter Anvin (Intel)
5606bdb335 listing: move the setting of options to one function
Disentangle the list option setting from the list option
checking. This makes the code simpler for the compiler to grok, and
centralizing code is usually a good idea.

The option setting is hardly performance critical anyway.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-03-03 15:26:56 -08:00
H. Peter Anvin (Intel)
fe9586f201 listing: separate "user" and "debug" flag, add matching debug option
Adding information about the NASM internal state to the list file can
be useful for debugging purposes. Separate the list of options that
are "user" options and those that are "debugging" options. The latter
are not implied by -L+ and are intended for NASM developer use.

Introduce -LX, which lists which instruction patterns are matched by
each instruction.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-03-03 14:12:48 -08:00
H. Peter Anvin (Intel)
a4c5b2829c changes.src: document JMP/CALL immediate size fix
- Document the fix to the JMP/CALL immediate size.
- Keep the convention to use capitals for keywords and instructions.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-03-03 13:23:26 -08:00
H. Peter Anvin (Intel)
7f92d306a9 NASM 3.02rc2 2026-03-03 13:17:56 -08:00
H. Peter Anvin (Intel)
5de64ecd20 changes.src: minor formatting fixes
- Minor format cleanups
- Correct the statement on PUSH.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-03-03 13:17:05 -08:00
Maciej Wieczor-Retman
e7aa83c68e doc: Update changelogs with bugfixes
Write up regression solving results for the upcoming 3.02.

Signed-off-by: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
2026-03-03 13:09:16 -08:00
H. Peter Anvin (Intel)
2aab21b3fb Fix the handling of the "rel" and "iwd" byte codes with oXX prefixes
The "rel" and "iwd" byte codes are supposed to be sensitive to the
operand size of the instruction, but inadvertently were only sensitive
to the CPU mode or an explicit size override for the operand.

"rel" affects direct near jumps, calls, and XBEGIN; "iwd" direct far
jumps and calls. No other instructions use these opcodes.

Fix this, so that e.g. "o32 jmp foo" is treated the same as "jmp dword
foo".

Correct the golden copies of the jmpxx travis tests (which were always
wrong.)

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-03-03 09:57:44 -08:00
H. Peter Anvin (Intel)
fbacd59cce struct itemplate: add insns.xda line number to the structure
Add the line number from insns.xda to struct itemplate. NASM itself
doesn't need this information, but it makes debugging matching *much*
easier; it is worth a few more bytes.

In theory it could be conditionalized on --enable-debug, but it is
probably not worth it.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-03-03 09:55:27 -08:00
H. Peter Anvin (Intel)
99898edfc1 test/crc32.asm: remove "bits BITS" hack
The --bits option makes this pointless.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-03-03 08:54:01 -08:00
H. Peter Anvin (Intel)
b4f74befce test/immsize2.asm: remove bits BITS
The --bits option makes this pointless.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-03-03 08:54:01 -08:00
H. Peter Anvin (Intel)
5bb69e6c8b test.inc: remove BITS hack
The --bits option makes the BITS hack unnecessary, and it somewhat
conflicts with the directive name itself.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-03-03 08:54:01 -08:00
Maciej Wieczor-Retman
320bc224b5 travis: Fix v4 tests
Update the test after fixing the typo in the mnemonic.

Signed-off-by: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
2026-03-03 08:53:44 -08:00
Maciej Wieczor-Retman
ddcf4d4f99 insns.dat: Fix issue #200 - push not allowing dword keyword
After macroization PUSH lost the NOLONG flags. That in turn caused
matching the 32-bit template when using the dword size specifier and
when in 64-bit mode. Giving the o32 entry the NOLONG flag seems to force
the o64 template instead which doesn't trigger warnings about 32-bit
sizes not being allowed.

Signed-off-by: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
2026-03-03 08:53:44 -08:00
Maciej Wieczor-Retman
f0dc7c220d preinsns: Fix issue #159 - incorrect byte encoding
Revert part of macroization that caused incorrect instruction template
matching. The behavior known at 2.16.03 changed due to the rm#,sbyte#
format overtaking other formats. To get back to the previous behavior
the patterns need to intertwine just as is presented here.

Signed-off-by: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
2026-03-03 08:53:44 -08:00
Maciej Wieczor-Retman
e68a08cd7d insns.dat: travis: Fix lost FAR encoding
Previous disassembler fix caused the FAR enconding not getting properly
applied when using the rm format.

Put the disassembler entries at the back so they are preffered by the
assembler and the FAR versions of memory references are correctly
matched.

Update the far tests.

Signed-off-by: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
2026-03-03 08:53:44 -08:00
Maciej Wieczor-Retman
f4defff3ea insns.dat: Fix issue #157 - POP not accepting valid size prefixes
POP doesn't have the OSIZE iflag which made it match the 16-bit
instruction variant and the reject valid osize prefixes likes o32 in 32
bit mode.

Signed-off-by: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
2026-03-03 08:53:44 -08:00
Maciej Wieczor-Retman
2fe0c39bdc travis: Update test binaries
Update the travis test binaries that the tests are compared against.
Changes were made to some instruction patterns and the binaries need to
be refreshed.

Signed-off-by: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
2026-03-03 08:53:44 -08:00
H. Peter Anvin (Intel)
c2344472c2 test: add a test for pushing immediates. Add a common header file.
- Add a test for pushing immediates and popping registers of various
  sizes.
- Add a common header file which probably will be useful for many
  tests.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-03-02 12:50:49 -08:00
H. Peter Anvin (Intel)
7c6bcd9589 test: add additional test for immediate sizes and arithmetic
Immediate sizes in arithmetic instructions can be tricky when using
optimization.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-03-02 12:13:21 -08:00
Maciej Wieczor-Retman
9dbff83e77 insns.dat: Fix JMP not assembling sometimes
After readding the JMP rm# variant, to fix the disassembler not
recognizing it, some patterns stopped assembling. It happened due to the
program matching an incorrect template and then complaining that it's
illegal.

Adding the NOLONG to word and dword versions (similarly to CALL) fixes
the problem.

Signed-off-by: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
2026-02-27 13:48:05 +01:00
H. Peter Anvin (Intel)
f7a4d8fd1b openwcom.mak: add zlib to the VPATH
It isn't clear if this is actually mandatory, but it is consistent
with the rest of the directories.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-02-26 15:44:17 -08:00
H. Peter Anvin (Intel)
724efa686f Merge remote-tracking branch 'maciej/for-hpa-fixes' 2026-02-26 15:32:29 -08:00
Maciej Wieczor-Retman
ef587a2566 docs: Fix issue #190 - no cp -u on MacOS prevents building
Use cp without -u to generate the documentation as the -u option doesn't
have to be present on other POSIX platforms and breaks builing the
project on MacOS.

Signed-off-by: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
2026-02-26 07:53:04 +01:00
Maciej Wieczor-Retman
85cd46de67 insns.dat: Fix issue #164 - broken dissasembly on JMP, JMPE and CALL
After macroization it seems the 'JMP rm' form was replaced by 'JPM
rm#|near' which caused the dissasembler to not emit anything.

Signed-off-by: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
2026-02-23 14:29:58 +01:00
Maciej Wieczor-Retman
14f887fb4e insns.dat: Fix issue #171 - valid prefixes not allowed
Instructions like IRET, POPF and PUSHF used to not have a operand size
specifier but after applying macros they received the 'osm' one -
meaning must be the same as the BITS mode. Which is not true for these
instructions, using the operand size prefix doesn't change their
encoding and their default 64-bit encoding is the 32-bit version.

Align these with other similar instructions like RET, RETF and use the
'od#' keyword which returns their previous behavior.

Signed-off-by: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
2026-02-20 19:35:26 +01:00
H. Peter Anvin (Intel)
184f8485b5 nxdisasm.pl: script to use objdump + ndisasm for better disassembly
Add a script which uses objdump to discover sections and symbols from
a binary, and call ndisasm accordingly, then add symbol references to
the ndisasm output.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-02-09 16:11:58 -08:00
H. Peter Anvin (Intel)
ed23d3ba34 ndisasm: add -z option for data size; clean up address handling
- Add a -z option to set the data size to be read (useful with -e)
- Clean up at least some remaining 32-bit assumptions.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2026-02-09 16:10:32 -08:00
Maciej Wieczor-Retman
8744226309 doc: Document jump size behavior
Document the logic behind determining the jump sizes, amounts of bytes
emitted related to size and length keywords. Change is related to
issue #181.

Also fix the JMPABS not being visible due to wrong tag used.

Signed-off-by: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
2026-02-06 19:40:52 +01:00
Maciej Wieczor-Retman
1ef93d643d doc: Fix issue #191 - badly formatted link
Fix bad link formatting that prevents building the documentation.

Signed-off-by: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
2026-02-06 19:15:52 +01:00
Maciej Wieczor-Retman
627ec8b865 insns.dat: Fix issue #196 - CMP not being lockable
Using LOCK on any CMP configuration of operands will result in #UD.

Remove the possibility of adding the LOCK prefix to the CMP instruction.

Signed-off-by: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
2026-02-06 18:13:09 +01:00
Maciej Wieczor-Retman
3910b58e96 parser.c: Fix issue #181 - redundancy needed to avoid NEAR optimized out
To assemble a JMP in the NEAR form the STRICT keyword is needed. This
change introduced recently reportedly breaks building boot sectors and
is non-intuitive since other JMP versions don't behave this way.

Disable optimizing the JMP size if the NEAR keyword is used.

Signed-off-by: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
2026-02-04 17:18:44 +01:00
Maciej Wieczor-Retman
bbff2d7ec6 parser.c: Fix issue #182 - no warning when size is omitted with labels
In cases such as "mov [es:bx], a_label" the operation defaults to a BYTE
size which copies only part of the label value.

Implement a check that warns the user of this issue when no size
specifier is used.

Signed-off-by: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
2026-02-03 23:12:46 +01:00
Maciej Wieczor-Retman
0058d91bec travis: Fix tests after instruction corrections
The UWRMSR was incorrectly encoded with operands swapped. Correct that
mistake.

Some AVX512 and AVX10.2 instructions had incorrect operands in the
database. Correct the tests after fixing the database entries.

Signed-off-by: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
2026-02-03 23:12:42 +01:00
Maciej Wieczor-Retman
89682def9b disp8: Fix issue #185 - EVEX compressed shift for MOVDDUP tuple type
MOVDDUP tuple type uses a compression shift for the disp8 addressing
scheme. The shift depends on the vector lenght and is defined as 8 for
128 bits, 32 for 256 bits and 64 for 512 bits.

Current implementation doesn't work for the 128 bit vector case since
the expression used evaluates to 16 instead of 8. Fix it with a special
if check before the current expression is returned.

Signed-off-by: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
2026-01-27 22:24:25 +01:00
RMarx1456
3f188d7222 disasm.c: Fix issue #193 by swapping arguments of is_class
Incorrect ordering led to specific encoding for implicit shift by one
(M1 - UNITY from include/opflags.h & x86/insnsd.c) being skipped over in
disasm.c:1519.

The skip over the is_class UNITY check would lead to adding 0x0 to the
end of the instruction and moving onwards having emitted the incorrect
immediate operand.

Fixes: 56567a0c4c ("disasm: fix the disassembler for many APX cases")
2026-01-27 22:24:25 +01:00
Maciej Wieczor-Retman
5c224e169e insns.dat: Fix typos and incorrect operands
Fix errors found through comparing XED and NASM instruction encodings.

From APX the UWRMSR instruction had swapped operands.

Most fixes related to AVX/AVX512 deal with operand sizes not matching
the SDM nor the XED produced encodings. Some (like VGETEXPSH) had a
wrong amont of operands. Others (like VP4DPWSSDS) had misspelled
mnemonics.

At last some AVX10.2 instructions had wrong operands sizes that didn't
match the newest (june 2025) AVX10.2 documentation.

Signed-off-by: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
2026-01-27 22:24:25 +01:00
Maciej Wieczor-Retman
d9c93e06ae insns.dat: Fix issue #186 - scalar AVX512 instructions treated as vector operations
Multiple AVX512 instructions were incorrectly encoded when it comes to
the embedded rounding value - they were treated as 128 bit vector
operations when in reality they are scalar operations.

Correct the following instructions' EVEX encodings:

VCVTSD2SI
VCVTSD2USI
VCVTSS2SI
VCVTSS2USI
VCVTTSD2SI
VCVTTSD2USI
VCVTTSS2SI
VCVTTSS2USI
VGETEXPSH
VGETMANTSH

Signed-off-by: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
2026-01-27 22:24:12 +01:00
H. Peter Anvin (Intel)
22a9118f1e nasmlib: mmap.c included the deleted "file.h", but didn't need it
The recently removed "file.h" was #included by mmap.c, but mmap.c just
needed a few standard header files.

Similarly, remove <sys/mman.h> from file.c.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-12-16 17:32:25 -08:00
H. Peter Anvin (Intel)
ff7a315acb nasmlib: move filename_set_extension() into path.c
Move filename_set_extension() into path.c, so it has access to the
filesystem-specific character constants. This prevents something like:

	nasm-code.d/foobar

... from getting truncated to ...

	nasm-code.bin

... instead of producing ...

	nasm-code.d/foobar.bin

Make the extension character (normally '.') configurable; this MIGHT
be usable on RISCOS at some point, although it is not entirely clear
that trying to make sense of RISCOS paths actually is meaningful,
because RISCOS compiler chains seem to do all kinds of path
translation magic trying to behave like other operating systems... it
might simply be more trouble than it is worth, especially for a
non-x86 platform.

As a side bonus, this removes the only use of strrchrnul(), so that
function can be dropped.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-12-15 09:58:42 -08:00
H. Peter Anvin (Intel)
795daf3d2d nasmlib: split file.c into file.c and fileio.c; remove file.h
file.h was only included from file.c; combine the two and declare
functions not used anywhere else as static.

Split out the checking I/O routines into a separate routine fileio.c
as they are (mostly) not host operating system specific, whereas
file.c is mostly host operating system generalization code.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-12-14 17:47:47 -08:00
H. Peter Anvin (Intel)
5dfcfc8cab Windows: use MultiByteToWideChar() instead of mbsrtowcs()
In the Windows-specific filename translation code, use
MultiByteToWideChar() instead of mbsrtowcs(). As this is
Windows-specific code it makes more sense to use the Windows-specific
API, and it might be more widely supported?

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-12-14 17:18:59 -08:00
SEt
b8c2a63286 Fix several issues with Codeview debug information 2025-12-09 16:44:35 -08:00
H. Peter Anvin (Intel)
f4f7d18c06 error: factor out error functions into separate files
Tidy up a *lot* of code by moving error functions into separate source
files. This required breaking out some of the assembler-only files
into a separate library, as it conflicts with stubs in the
disassembler.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-11-07 14:42:33 -08:00
H. Peter Anvin (Intel)
c0e4def0fe assemble: factor out calcsize_speculative()
Currently speculative size calculations is only done during
jmp_match(), but it might be used for other things in the
future. Either way, it is cleaner to have it factored out into a
separate function.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-11-07 11:51:01 -08:00
redzimski
94c6ecda5b fix [warning push] causing "unknown warning name"
[warning push] emitted a "unknown warning name" warning when
-w+unknown-warning is set.
2025-11-04 10:23:54 -08:00
Petr Sumbera
ca178f80d8 Fix for big endian platforms.
https://bugzilla.nasm.us/show_bug.cgi?id=3392745
2025-11-04 10:14:49 -08:00
H. Peter Anvin (Intel)
acfeb7df6c zlib: pass 15 not 0 to inflateInit2()
The convention of passing 0 to inflateInit2() to autodetect the window
size is not supported in really old versions of zlib. The only
downside with simply passing in the maximum value (15) is potential
additional memory buffer allocations, but it is a drop in the bucket
for NASM.

Fixes: https://github.com/netwide-assembler/nasm/issues/165
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-11-04 00:38:17 -08:00
H. Peter Anvin (Intel)
94923e1382 travis: improve the RET instruction test
Split the RET instruction test by mode for ease of disassembly, and
test more subcases.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-15 22:51:34 -07:00
H. Peter Anvin (Intel)
e19c989bd5 insns.dat: correct the handling of RET instructions with prefixes
NASM would throw a warning on some valid prefixed RET instructions,
e.g. "o32 ret" instead of "retd" in 16-bit mode.  Correct that.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-15 22:44:23 -07:00
H. Peter Anvin (Intel)
4709cfe493 Show instruction mismatch errors if another error terminates assembly
Instruction mismatch errors have been held until the last assembly
pass in case changed %if statements cause a code path to be elided in
subsequent passes. However, it is confusing to the user if error
messages aren't shown if another error terminates assembly.

Use the already existing mechanism for warnings to hold the messages
unless another error terminates assembly.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-15 22:32:36 -07:00
H. Peter Anvin
ca67f50341 travis: unbreak the ret.asm test
The ret.asm test was broken because the assembly expected -DERROR=1
whereas the run script provided -DERROR, masking all the actual
errors...

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-15 22:32:32 -07:00
H. Peter Anvin
bf16907c9d travis: unbreak the ret.asm test
The ret.asm test was broken because the assembly expected -DERROR=1
whereas the run script provided -DERROR, masking all the actual
errors...

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-15 22:29:01 -07:00
H. Peter Anvin
1a907c27a5 travis: always generate a list file; show subtest number
Always generate a list file and point output at a given filename, even
if failure is expected.

Remove ad hoc -o output names that generally don't point into safe
locations.

The result is that the preprocessing options (-E) no longer output to
stdout, so change the tests accordingly.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-15 22:11:09 -07:00
H. Peter Anvin (Intel)
94dd4d30a7 test: improve ret.asm
Add more valid and invalid combinations of return instructions.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-15 21:12:58 -07:00
H. Peter Anvin (Intel)
1b939ecf3d errors: add the ability to hold errors, not just warnings
Re-introduce ERR_HOLD, which means that an error is treated like a
warning except for the last pass, but unlike ERR_PASS2 the error
message *will* be issued if another error happens on the same pass, just
like warnings.

This will be used to improve error messages on instruction mismatch.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-15 21:09:05 -07:00
H. Peter Anvin (Intel)
9503778d6e ndisasm: handle byte code 0300..0303 (HINT_NOP)
Avoid ndisasm printing error messages due to an unknown byte code.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-15 21:05:46 -07:00
H. Peter Anvin (Intel)
fc56538bce Makefile: include $(PROGOBJ) in $(DIRS) dependency
The $(DIRS) dependency didn't include $(PROGOBJ), which could cause
Make to try to build asm/nasm.o or disasm/ndisasm.o before the
corresponding object subdirectory had been created.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-15 20:00:36 -07:00
H. Peter Anvin (Intel)
efe066ef40 nasm.c: if enabled, print a pass report even on failure
If printing a pass report is enabled, then do so even if the assembly
session failed -- except for a critical or panic failure (e.g. if
running out of memory, which could cause recursive failures.)

This can help discovering e.g. why certain error messages don't appear
when one would expect them (because they have not been detected in the
current pass.)

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-15 17:34:42 -07:00
H. Peter Anvin (Intel)
ab8787a1fa Rename "headers" directory to "templates", add .h template
Rename the "headers" directory to "templates", and rename the files
within as template.* with the appropriate file types so that editors
will pick up the correct type. Add a .h file template.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-15 17:34:29 -07:00
H. Peter Anvin (Intel)
f520436a7a Make Watcom workarounds a little less obnoxious
Duplicated code is asking for trouble. Make the Watcom brain damage
workarounds at least patternized.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-15 17:34:10 -07:00
KO Myung-Hun
e86773d70b openwcom.mak: clean up internal zlib directory
Signed-off-by: KO Myung-Hun <komh78@gmail.com>
2025-10-15 17:31:44 -07:00
H. Peter Anvin (Intel)
44ec97993a compiler: add and use unreachable() macro
C23 defines unreachable() as a macro in <stddef.h>. For earlier
versions of gcc, __builtin_unreachable() is possible.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-13 17:53:42 -07:00
H. Peter Anvin (Intel)
9ba21c1e50 .gitignore: add .bin16, .bin32, .bin64
New test format suffixes. These are output files and should be ignored
by git.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-12 13:43:00 -07:00
H. Peter Anvin (Intel)
746e7c9efa compiler.h: the test for "neither C++ nor C23" still wrong
The test needs to test for neither nor; as it was it tested "(not C++)
or C23" which was not at all what was intended...

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-12 13:05:55 -07:00
H. Peter Anvin (Intel)
dfb3b0013e version: now working on 3.02... 2025-10-12 12:59:14 -07:00
H. Peter Anvin (Intel)
0bc4333150 Change JMPE encoding from being relative to being absolute
Apparently NASM has been doing this in violation of the spec since
JMPE was first added. Hopefully fixing it won't cause new problems...

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-12 12:58:04 -07:00
H. Peter Anvin (Intel)
44e89ba9b6 compiler.h: drop the stupid C++-style cast-to-bool hack
The C++-style cast-to-bool hack was broken in concept that it doesn't help the
fundamental problem -- implicit conversions are broken for the
backwards compatibility enum definition -- as well as in
implementation, as it misspelled __STDC_VERSION__ as __STDC_VERSION.

The #ifdef bool test *should* have prevented this problem, but
apparently several compilers do define "bool" in <stdbool.h> even when
it is a keyword, in violation of the C23 spec.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-12 12:48:32 -07:00
H. Peter Anvin (Intel)
587ed5e36d x86/bytecode.txt: improve byte code documentation
Improve the byte code reference documentation to make a few opcodes
more clear and add some general properties about the byte codes,
including the files that need to be changed when the byte code
changes.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-12 11:23:28 -07:00
H. Peter Anvin (Intel)
e9fac2faa6 NASM 3.01 2025-10-10 23:42:56 -07:00
Yongjie Sheng
3e925ee75c add project test for intel-ipsec-mb isa-l_crypto isa-l 2025-10-11 09:49:07 +08:00
H. Peter Anvin (Intel)
5d655306f9 NASM 3.01rc9 2025-10-10 17:23:52 -07:00
H. Peter Anvin (Intel)
e20b3087cc changes.src: update release notes
A few more changes.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-10 16:37:04 -07:00
H. Peter Anvin (Intel)
8f1cd30fcb insns.dat: fix CMPXCHG operand size
The operand size prefix byte code (o#) was missing in the CMPXCHG
pattern.

Reported-by: Yongjie Sheng <sheng.yongjie@intel.com>
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-10 16:24:22 -07:00
H. Peter Anvin (Intel)
a7457e66cf Fix matching of branch instructions with prefixes and sizes
Matching of branch instructions with prefixes and sizes is, to say the
least, tricky. Work through it, and add a new macro to help.

Fixes: https://github.com/netwide-assembler/nasm/issues/144
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-10 13:07:46 -07:00
H. Peter Anvin (Intel)
2c71e67762 travis: don't stop on failure
Don't stop travis after a single test failure. It is better to run all
the tests and get a comprehensive list of failing tests.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-10 10:55:11 -07:00
H. Peter Anvin (Intel)
c0aec6969b directives: correctly handle quoted strings in directives
Quoted strings should be valid inside directives, including ones that
contain a ] character. Also check for garbage on the line after the
directive.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-10 10:41:09 -07:00
H. Peter Anvin (Intel)
5a6b276b89 travis: make travis output list files for debugging
It is so much easier to debug problems with a list file in hand.
Generate them, always.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-09 22:28:34 -07:00
H. Peter Anvin (Intel)
4cdb62ffb6 listing: modify active_list_options, not just list_options
If the assembly stops after the first pass, only active_list_options
will be seen; this is also the value that applies for local changes in
the list options. Thus, both variables need to be tweaked.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-09 20:09:33 -07:00
H. Peter Anvin (Intel)
7e82d9d1e3 Add a default-error warning for impossible o64, a64, or a16 prefixes
The o64, a64 and a16 prefixes are only possible in specific
modes. It is a lot easier to debug with a more sensible error message.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-09 19:24:07 -07:00
H. Peter Anvin (Intel)
a16571a705 doc/directiv.src: fix missing ] in prefix/suffix documentation
The prefix/suffix directive documentation were missing some brackets,
lost in the course of editing.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-09 17:29:00 -07:00
H. Peter Anvin (Intel)
b8e256a475 changes.src: add missing \>
Add missing \> marker (bulleted list continuation.)

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-09 17:25:54 -07:00
H. Peter Anvin (Intel)
f87fb5c957 nasm.spec.in: change http:// to https://
Change URLs to https://.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-09 17:19:54 -07:00
H. Peter Anvin (Intel)
b453f9e8ea nasm.spec.in: be extra obnoxious about build requirements
It is better to put in too many BuildRequires than too few.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-09 17:19:09 -07:00
Igor Glücksmann
35ef2e2d1a Fixed PDF doc line overflow
Resolved Conflicts:
	doc/nasmdoc.src

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-09 17:08:35 -07:00
H. Peter Anvin (Intel)
69c25535ae NASM 3.01rc8 2025-10-09 16:15:52 -07:00
H. Peter Anvin (Intel)
ddf85b55ed changes.src: update release notes
Add recent changes to the release notes.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-09 16:14:58 -07:00
H. Peter Anvin (Intel)
3d96ea651a assemble: weaken the test for "absolute address can not be RIP-relative"
The test for "absolute address can not be RIP-relative" is too strict
and causes false positive failures.

Fixes: https://github.com/netwide-assembler/nasm/issues/145
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-09 16:10:35 -07:00
Nico Weber
a8a1dc2b0c Fix Wbitwise-instead-of-logical warning
`a || b` only evaluates b if a is false. `a | b` always evaluates
both a and b. If a and b are of type bool, || is usually what you
want, so clang now warns on `|` where both arguments are of type bool.

This warning fires once in nasm. It looks like `|` is an (inconsequential)
typo of `||`, so use that instead.

No intended behavior change.
2025-10-09 15:48:18 -07:00
H. Peter Anvin (Intel)
9b101e9316 insns.pl: register 0 should add RN_ZERO, not RM_ZERO
Not all registers are valid as memory references, and thus
using RM_ZERO is incorrect. Use RN_ZERO instead, which is simply the
zero-register bit.

Fixes: https://github.com/netwide-assembler/nasm/issues/140
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-09 15:42:29 -07:00
KO Myung-Hun
0c8379825e openwcom.mak: use internal commands if possible
[ hpa: added comment that "rm" really is a WMAKE internal command. ]

Signed-off-by: KO Myung-Hun <komh78@gmail.com>
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-09 15:05:29 -07:00
KO Myung-Hun
29a5aabd7a Fix compilation with Open Watcom
Open Watcom does not support 64-bit constants at 'case'.

[ hpa: I'm pulling this, but I'm really, *really* questioning its
supportability long term. The OpenWatcom people need to fix this, or
we are just going to have to say "OW is not supported."

At some point we *are* going to move to a "C99 is baseline" policy for
code; there are simply too many features in C99 that are actively
painful to be without.

That is, unless we decide to go to C++, which is under consideration
but is a much bigger job. In that case, the target will probably be
either C++11 or C++14 as those C++ versions contain some pretty
essential features. ]

Signed-off-by: KO Myung-Hun <komh78@gmail.com>
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-09 14:52:29 -07:00
H. Peter Anvin (Intel)
013db3d446 nasmlib: rename crc32.c to crc32b.c to avoid conflict with zlib/crc32.c
For the benefit of those platforms which have to rely on VPATH, avoid
having the same filename in multiple subdirectories.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-09 14:49:22 -07:00
InstLatx64
378ee0e9c5 AMX-TRANSPOSE: removed, retag instructions NEVER.
All the 16 AMX-TRANSPOSE instructions were removed from the 59th
edition of "Intel Architecture Instruction Set Extensions and Future
Features Programming Reference" September 2025, 319433-059.

Similar to PCOMMIT, they are tagged as 'NEVER'

[ hpa: don't remove from tests, but suppress the warnings.  Don't
  remove the CPUID tag; a future version of NASM will actually implement
  CPU filtering based on the various CPUID tags; that development is
  genuinely in progress. ]

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-09 14:44:24 -07:00
InstLatx64
62b610ad86 Feature flag change, remove duplicate: AVX512FC16->F16C
VEX version of VCVTPH2PS, VCVTPS2PH is F16C

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-09 14:29:09 -07:00
H. Peter Anvin (Intel)
43f9a71fc0 NASM 3.01rc7 2025-10-08 13:12:29 -07:00
Yongjie2017
a684942de0 the list file existing or not should not fail the copy instead fail the nasm compiling itself so nasm -v is excused 2025-10-08 13:07:07 -07:00
Yongjie Sheng
420313da8c add project test support to dav1d 2025-10-08 13:07:07 -07:00
H. Peter Anvin (Intel)
be03f169b9 travis: let "make travis" show the errors if any
Grep for FAIL in the log and print any errors, otherwise a success
message.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-08 13:03:40 -07:00
H. Peter Anvin (Intel)
51dce26137 travis improvements: look for python3, log output, option to filter
Use autoconf to find either python3 or python.

Add option to travis to filter the contents of stdout or stderr.

Generate the _version.stdout travis matching file from the version
file.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-08 12:56:00 -07:00
H. Peter Anvin (Intel)
a398a41f0a travis: update AMX test
Update AMX test per previous commit from IntLatx64.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-08 11:59:23 -07:00
InstLatx64
019615f85f AMX fix
-- AMX instruction fixes
-- AMX test file extension with new levels
according to Intel ISA Extension Guide 58th edition

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-08 11:59:23 -07:00
InstLatx64
292d852f55 AVX-NE-CONVERT fix
AVX-NE-CONVERT fix:
- only VCVTNEPS2BF16 has EVEX version
AVX-NE-CONVERT32b/64b test files
Checked with XED version: [v2025.06.08]
2025-10-08 11:51:04 -07:00
Iouri Kharon
5a5057ad95 bug in new macro (typo?): alias is SAL (to SHL), not SAR 2025-10-08 11:49:54 -07:00
H. Peter Anvin (Intel)
e027b5919f NASM 3.01rc6 2025-10-07 20:27:43 -07:00
H. Peter Anvin (Intel)
ae9335a0b9 labels: make the prefix/suffix options and pragmas consistent
Make the spellings for the label-mangling options and pragmas
consistent, and implement the directive forms which were documented
but never implemented.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-07 18:46:39 -07:00
H. Peter Anvin (Intel)
c08b4edca1 Sync builtin.mac 2025-10-07 18:06:34 -07:00
H. Peter Anvin (Intel)
495fd738ec NASM 3.01rc5 2025-10-07 16:32:54 -07:00
H. Peter Anvin (Intel)
99df4c97be changes.src: handwavy note about various instruction changes
A lot of minor changes, but not worth enumerating them.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-07 16:31:43 -07:00
H. Peter Anvin (Intel)
e3f26e25a2 Reshuffle shift and rotate patterns for APX
The shift and rotate patterns are "interesting" in the following way:

1. Even though only 4/5/6 bits of the input are ever used, for the
   regular instructions the input is specified as the CL register, but
   for the -X instructions as a size-matching register. This makes the
   optimization patterns "interesting."

2. The sequencing of legacy, VEX -X versions, APX EVEX, and APX -X

For #1, allow any size register to contain the shift count.

For #2, split up the macro generation of the patterns, and add a new
"$xmacro" macro to deal with the combinatorics of generating all the
-X patterns.  Written directly in Perl since it seemed easier than
trying to make anything more general for what is very much a special
case...

Reported-by: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-07 16:26:09 -07:00
hongjinghao
e39b856bde preproc: fix heap memory overflow CVE-2023-31722
paramlen has heap memory of length nparam+1. The value of variable i
may be greater than nparam+1, causing heap memory overflow. Therefore,
i and nparam+1 needs to be determined in the loop.

Fixes: https://bugzilla.nasm.us/show_bug.cgi?id=3392857#c1
Fixes: https://github.com/netwide-assembler/nasm/pull/83
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-07 14:58:03 -07:00
H. Peter Anvin (Intel)
c651c28217 NASM 3.01rc4 2025-10-07 11:18:18 -07:00
H. Peter Anvin (Intel)
6e221c8193 assemble: reduce the priority of "mask not permitted" error
Per BR 75, the "mask not permitted" error is a little too persistent.

Fixes: https://github.com/netwide-assembler/nasm/pull/75 (hopefully)
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-07 11:12:43 -07:00
Henrik Gramner
86919accd9 x86/insns.dat: Enable contracted forms for a few EVEX vcvt* instructions
Most instructions support contracted forms, but those had been overlooked.

Signed-off-by: Henrik Gramner <henrik@gramner.com>
[ hpa: manual merge ]
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-07 11:08:58 -07:00
Henrik Gramner
162d245c30 x86/insns.dat: Fix {er} usage on EVEX vcvtsi2* instructions
The rounding specifier should be applied to src2, not src1.

Furthermore, VCVTSI2SD with a 32-bit source operand does not
support specifying a rounding mode (as no rounding can occur).

Signed-off-by: Henrik Gramner <henrik@gramner.com>
[ hpa: manual merge ]
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-07 11:06:52 -07:00
H. Peter Anvin (Intel)
0a1a9789ec Fix confusion between "postfix" and "suffix"
"suffix" is the more common English term, but NASM used "postfix" for
a long time.  Allow them as aliases, and tidy up the documentation
accordingly.  While making these changes, tidy up the handling of
options in the index.

Fixes: https://github.com/netwide-assembler/nasm/pull/61
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-07 10:49:55 -07:00
Iouri Kharon
89439aa58d Remove unneeded (illegal) evex-encoding of VCVTPS2PH
According to the June edition of SDM evex-form of the VCVTPS2PH command only exists with mmmmm equal to 0f38, and map5 only exists for the VCVTPS2PHX command
2025-10-07 10:16:36 -07:00
H. Peter Anvin (Intel)
41d35bb483 Merge multiple fixes from "InstLatx64" 2025-10-07 10:13:12 -07:00
H. Peter Anvin
e72a54174c insns.dat: correct the [LD][GI]DT patterns
It is somewhat counterintuitive, but the correct flag for the memory
operand is "OSIZE". The "nw" flag takes care of promoting the default
operand size on 64 bits to 64.

Fixes: https://github.com/netwide-assembler/nasm/issues/130
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-07 09:58:54 -07:00
H. Peter Anvin
f047ceeae3 test/Makefile: add .bin{16,32,64} targets
Quick and easy way to run the same test for 16-, 32- and 64-bit output
without mixing them together in one binary output file.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-07 09:57:19 -07:00
H. Peter Anvin
fa43d8e01d asm: new --bits option to set the processor mode on the command line
This is really just a shorthand for the --before option, but it is
really convenient for quickly writing multimode tests.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-07 09:56:20 -07:00
H. Peter Anvin
2c63ab038c asm/preproc.c: generalize pp_pre_command()
Generalize pp_pre_command() so that the first argument doesn't have to
be a preprocessor token. Instead, the two arguments are now both
turned into token streams, separated by a whitespace token.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-07 09:53:15 -07:00
H. Peter Anvin
f1b6d3188c preproc: add a %selbits() function
Although one can implement this "manually" in terms of %sel(), this
function is *really* useful for making multi-mode tests and allows for
better error checking.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-07 09:17:59 -07:00
H. Peter Anvin
e4044cfc48 assemble.c: avoid a panic after invalid instruction error
If an instruction triggers an error (nasm_nonfatal) it is legitimate
for calcsize() to return 0; in that case no further processing is
needed.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-07 09:16:06 -07:00
H. Peter Anvin
6df250aee3 parser: add the actual name of a label to the label-orphan warning
The label-orphan warning is *way* more useful if it includes the
actual label name; this way the programmer can usually spot
immediately if it is a label or misspelled instruction.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-07 08:30:02 -07:00
Yongjie Sheng
d66187c1de reconstruct ffmpegtest to be generic to support more different projects 2025-10-07 08:11:33 -07:00
InstLatx64
2a2acca7c0 AVX512_VP2INTERSECT test files
AVX512_VP2INTERSECT 32b/64b test files
Checked with XED version: [v2025.06.08]
2025-10-07 12:07:55 +02:00
InstLatx64
f4b1a206e0 Remove duplicates
Remove duplicates:
- V{MAX,MIN}{P,S}H
- VEXTRACT{F,I}{32x4,64x2}
- VF{,C}MULCPH
- VF{,N}M{ADD,SUB}{132,213,231}SH
Removed AVX10_1 label from VADDPH/VCMPPH due to consistency
2025-10-07 11:35:15 +02:00
InstLatx64
fb43244978 KUNPCK* fix
KUNPCK* fix, it compiles k_test.asm without errors
2025-10-07 11:07:33 +02:00
InstLatx64
172c4b2342 Missing AVX-VNNI_INT{,8,16} instructions
-- AVX-VNNI_INT{,8,16} instructions: VPDP{B,W}{SS,SU,US,UU}{D,DS}
- AVX-VNNI_INT{,8,16}  test files
Checked with XED version: [v2025.06.08]
2025-10-07 09:52:13 +02:00
Yongjie Sheng
9cb23294a4 fix a displacement offset calculation error for movddup 2025-10-07 14:35:45 +08:00
Alexey Vishnyakov
891c63e64f output: fix null pointer dereferences in output/outaout.c
The bugs were found by Svace static analysis tool:

1. sym can be null in when exact is false, and sym is later dereferenced
   by sym->symnum
2. asym can be null, no return from function is performed, and asym is
   dereferenced by asym->symnum
2025-10-06 14:58:40 -07:00
Ivan Sorokin
bd7185bad1 fix undefined behavior in count_mmac_params
When compiled -fsanitize=undefined nasm produced this error message:

asm/preproc.c:2523:25: runtime error: member access within null pointer of type 'struct Token'

The problem is reproducible on tests avx512f, avx512cd, avx512pf
and avx512er in the test suite.

The problematic line was:

    /* Advance to the next comma */
    maybe_comma = &t->next;                            <<< HERE
    while (tok_isnt(t, ',')) {
        if (!tok_white(t))
            comma = NULL; /* Non-empty parameter */
        maybe_comma = &t->next;
        t = t->next;
    }

When t is NULL this line doesn't cause memory access, but it is still an
undefined behavior according to C standard.

I believe that the underlying problem is that this loop doesn't have a sound
invariant about maybe_comma:

* On first iteration: *maybe_comma == t->next
* On the following iterations: *maybe_comma == t

I don't know what the intended loop invariant is and I decided to just
mechanically fix the deferencing of NULL pointer, completely preserving
the existing behavior.

Signed-off-by: Ivan Sorokin <vanyacpp@gmail.com>
2025-10-06 14:56:45 -07:00
Ivan Sorokin
ad297258c1 fix memory leak in eval_strfunc
When running with -fsanitize=leak enabled nasm prints this error:

==19965==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 360 byte(s) in 90 object(s) allocated from:
    #0 0x7faee9396867 in __interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:145
    #1 0x5645d39a401c in nasm_malloc nasmlib/alloc.c:55
    #2 0x5645d3a41f9d in string_transform asm/strfunc.c:356
    #3 0x5645d3a37d40 in eval_strfunc asm/eval.c:761
    #4 0x5645d3a37d40 in expr6 asm/eval.c:906
    #5 0x5645d3a3968d in expr5 asm/eval.c:627
    #6 0x5645d3a39aca in expr4 asm/eval.c:602
    #7 0x5645d3a39b72 in expr3 asm/eval.c:563
    #8 0x5645d3a39db8 in expr2 asm/eval.c:537
    #9 0x5645d3a39f38 in expr1 asm/eval.c:511
    #10 0x5645d3a3a0b8 in expr0 asm/eval.c:485
    #11 0x5645d3a3a242 in rexp3 asm/eval.c:422
    #12 0x5645d3a3a508 in rexp2 asm/eval.c:396
    #13 0x5645d3a3a6a8 in rexp1 asm/eval.c:369
    #14 0x5645d3a3a838 in rexp0 asm/eval.c:342
    #15 0x5645d3a3a838 in cexpr asm/eval.c:305
    #16 0x5645d3a3ad08 in bexpr asm/eval.c:298
    #17 0x5645d3a3ad08 in evaluate asm/eval.c:1032
    #18 0x5645d39e4f20 in parse_line asm/parser.c:959
    #19 0x5645d399e243 in assemble_file asm/nasm.c:1735
    #20 0x5645d3998801 in main asm/nasm.c:719
    #21 0x7faee8aaed8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58
    #22 0x7faee8aaee3f in __libc_start_main_impl ../csu/libc-start.c:392
    #23 0x5645d399acd4 in _start (/home/ivan/d/nasm/nasm+0x2e5cd4)

SUMMARY: AddressSanitizer: 360 byte(s) leaked in 90 allocation(s).

This problem is reproducible on test utf.asm.

The problem was caused by the fact that eval_strfunc doesn't free the string
allocated by string_transform.

Signed-off-by: Ivan Sorokin <vanyacpp@gmail.com>
2025-10-06 14:50:40 -07:00
Elyes Haouas
fc720e7040 Remove useless parentheses in return statements
Signed-off-by: Elyes Haouas <ehaouas@noos.fr>
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-06 14:28:54 -07:00
H. Peter Anvin
f6a17a29c0 nasmlib.h: protect list_last() macro against misuse
The list_last() macro is a statement macro; wrap it in a
do { ... } while(0) block to prevent accidental misuse.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-06 14:27:30 -07:00
Elyes Haouas
f744ec431f Remove trailing semicolon in macros
Signed-off-by: Elyes Haouas <ehaouas@noos.fr>
[ hpa: only one of the defined issues was valid, removed the rest. ]
Signed-off-by: H. Peter Anvin <hpa@zytor.com>
2025-10-06 14:26:42 -07:00
Elyes Haouas
d9494d5240 output/outmacho.c: Add missing space at break quoted strings
Signed-off-by: Elyes Haouas <ehaouas@noos.fr>
2025-10-06 14:22:59 -07:00
Elyes Haouas
346a1b3344 SubmittingPatches: Update git link
Signed-off-by: Elyes Haouas <ehaouas@noos.fr>
2025-10-06 14:22:50 -07:00
H. Peter Anvin
81dd083291 outelf.c: remove stray semicolon
Harmless, but undesirable.

Fixes: https://github.com/netwide-assembler/nasm/pull/57
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-06 14:19:15 -07:00
H. Peter Anvin
0c3a964caf doc: remove stray "are"
"are generate" -> "generate"

Fixes: https://github.com/netwide-assembler/nasm/pull/87
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-06 14:14:09 -07:00
H. Peter Anvin
5b9099c058 asm/parser: print the actual token in an error, not its value
Printing an internal token value is not very user-friendly :) Print
the contents of the actual token in question.

Fixes: https://github.com/netwide-assembler/nasm/pull/90
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-06 14:07:33 -07:00
Yongjie Sheng
8d4710d014 ffmpegtest: fix variable rev change in a subshell does not impact parent
Error status would get lost.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-06 13:58:27 -07:00
KO Myung-Hun
57bf1b7b06 doc: document that the obj output format GROUP directive is cumulative
The GROUP directive can now be specified more than once for a group,
and the result is cumulative (the union of all specified groups.)

Signed-off-by: KO Myung-Hun <komh78@gmail.com>
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-06 13:26:35 -07:00
KO Myung-Hun
c7e17f5dde outobj: make a group cumulative
On any other OMF assemblers such as MASM, TASM and ALP, a group is
cumulative.

Signed-off-by: KO Myung-Hun <komh78@gmail.com>
2025-10-06 13:24:09 -07:00
H. Peter Anvin
755593b128 NASM 3.01rc3 2025-10-06 13:11:59 -07:00
H. Peter Anvin
0bc42dd1e0 changes.src: document TEST reg,mem fix
Add TEST reg,mem to release notes.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-06 13:11:09 -07:00
H. Peter Anvin
b3358fe63e insns.dat: reinstate TEST reg,mem alias
Officially the syntax for TEST is "rm,reg"; however TEST is
commutative in every aspect, and as such "reg,mem" is an equivalent
form that NASM has also supported in the past.

Reinstate it properly.

Fixes: https://bugzilla.nasm.us/show_bug.cgi?id=3392962
Reported-by: E. C. Masloch <pushbx@ulukai.org>
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-06 13:07:09 -07:00
H. Peter Anvin
2bb275d651 NASM 3.01rc2 2025-10-06 12:10:18 -07:00
H. Peter Anvin
11c512850e warnings.pl: tidy up the formatting of the warning output
Clean up the formatting of the generated warning files.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-06 12:07:23 -07:00
H. Peter Anvin
d5705c96bb changes.src: use \c{...} formatting for instructions
Instructions are literals, mark them with \c{...}.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-06 11:57:37 -07:00
Maciej Wieczor-Retman
cb03c02553 doc: Summarize PR changes
Merge PRs 127, 126, 125, 124 and 91. Document some of the most relevant
changes.

Signed-off-by: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
2025-10-06 19:29:38 +02:00
InstLatx64
2488b6cfb3 AVX512_FP16 mnemonic fix
-- VGETMAXPH -> VMAXPH
-- VGETMINPH -> VMINPH
-- VFCMULCPCH -> VFCMULCPH
-- VFMULCPCH -> VFMULCPH
-- VPMADD{132,213,231}SH -> VFMADD{132,213,231}SH
-- VPMSUB{132,213,231}SH -> VFMSUB{132,213,231}SH
2025-10-06 19:29:33 +02:00
InstLatx64
70ed10d2e2 AVX512BF16 fix
AVX512BF16 fix:
-- VCVTNEPS2BF16 operand count
-- VDPBF16PS operand size
AVX512BF16 test files
Checked with XED version: [v2025.06.08]
2025-10-06 19:17:51 +02:00
Maciej Wieczor-Retman
0fb33913d6 x86: tools: Remove unused perl code variables
Merged version of a PR by mknos:
https://github.com/netwide-assembler/nasm/pull/91

Signed-off-by: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
2025-10-06 19:17:51 +02:00
InstLatx64
62f5f6990f AMX-COMPLEX support
-- TCMMIMFP16PS, TCMMRLFP16PS instructions
-- AMX.asm fix: Similar to GATHER instructions, 3-operand AMX instructions cannot have the same operand more than once
Checked with XED version: [v2025.06.08]
2025-10-06 19:17:43 +02:00
Iouri Kharon
8f47ba7cc7 fix TCVTROWPS2PHL (typo?):
see Intel® Architecture Instruction Set Extensions and Future Features Programming Reference, March 2025 319433-057
else (without this correction) it conflict with VPERMI2PS
2025-10-06 18:56:51 +02:00
H. Peter Anvin
f7702bed4d NASM 3.01rc1 2025-10-06 09:47:56 -07:00
H. Peter Anvin
13379eb48a changes.src: document %exitrep/%exitmacro %if fix
Add the fix for %exitrep/%exitmacro to the release notes.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-06 09:43:26 -07:00
H. Peter Anvin
d9958f428a test/exitrep: test for proper %if and %rep evaluation suppression
If a line is suppressed, the %if or %rep condition must never be
evaluated. Test for it, and add the exitrep test to travis.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-06 09:38:55 -07:00
H. Peter Anvin
2255ebb549 preproc: don't evaluate an %if condition if suppressed
When a line is suppressed there is no guarantee that it is
syntactically valid, so treat it exactly like a dead %if branch.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-06 09:20:30 -07:00
H. Peter Anvin
6b1636ab0e changes.src: drop 3.00.01; plan 3.01 as a bug fix release
Looks like there are enough critical changes to justify a release
without a bunch of new development. Let's just call the new
release 3.01 and avoid a bunch of excess dottage.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-06 08:33:16 -07:00
H. Peter Anvin
3bb875f3e5 Merge remote-tracking branch 'origin/nasm-3.00.xx' 2025-10-04 18:31:52 -07:00
H. Peter Anvin
312ea7d2d3 nasmdoc.css: make columns wider, smaller text in Appendix F
The column width really wasn't quite enough.

Make the text size in Appendix F which can be rather wide
smaller. There is also no real reason to put that in a background box.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-04 16:25:21 -07:00
H. Peter Anvin
1ec9d7dc22 changes.src: add obj2 output format to the release notes
Need to be added to the release notes...

Cc: KO Myung-Hun <komh78@gmail.com>
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-04 15:59:13 -07:00
KO Myung-Hun
38fd561a0b outfmt.src: Add explanation for obj2 output format
Signed-off-by: KO Myung-Hun <komh78@gmail.com>
2025-10-04 15:57:30 -07:00
KO Myung-Hun
c7f426f5e5 outobj: add obj2 driver
Obj2 is an obj variation for OS/2.

Obj2 has the following differences from obj.

1. Default attributes for a segment are ALIGN=16 and USE32.
2. Add a segment to FLAT group implicitly if 32-bit segment.
3. Recognize Unix sections .text, .rodata, .data and .bss as TEXT32,
   CONST32, DATA32 and BSS32 respectively for compatibility with other
   Unix platforms.
4. Set default classes implicitly for known segments such as TEXT32,
   CONST32, DATA32, BSS32 and so on.

Signed-off-by: KO Myung-Hun <komh78@gmail.com>
2025-10-04 15:57:24 -07:00
Adam Sampson
a65be7d59b bytesex.h: fix typo in le32toh function name
This fixes the build on 32-bit/64-bit ARM.

Signed-off-by: Adam Sampson <ats@offog.org>
2025-10-04 15:54:49 -07:00
H. Peter Anvin
cd5dfb8c5f warnings: always regenerate outputs; tidy up unnecessary rules
With warnings disaggregated, there is no reason to play games with not
updating the output timestamp. Always write the files as usual.

Remove unnecessary Makefile rules.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
1# Please enter the commit message for your changes. Lines starting
2025-10-04 14:04:31 -07:00
H. Peter Anvin
69f1aa6c6a Makefile.in: re-introduce rules that can be made common
Rules that are now simple again can be made common.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-04 13:55:21 -07:00
H. Peter Anvin
a8bcdb641b Warnings: disaggregate from source and tidy up documentation
The idea of putting the warnings in the source code was a nice one,
really, but it ended up being a nightmare from the perspective of
build dependencies. Disaggregate them, and tweak the documentation for
easier reading.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-04 13:46:39 -07:00
H. Peter Anvin
bb3a51e5d6 warnings: remove stray whitespace before warning specification
The actual warning specification should begin immediately after *!.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-04 12:09:05 -07:00
Gabriel Barrantes
19e1f4bf81 Setup CI/CD pipeline
Setup job for travis tests

Signed-off-by: Gabriel Barrantes <gabriel.barrantes.dev@outlook.com>
2025-10-04 10:51:08 -07:00
H. Peter Anvin
3472f368cd This is the development branch intended to become NASM 3.01
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-03 12:59:05 -07:00
H. Peter Anvin
fe7c3c7171 This is the maintenance branch destined to become NASM 3.00.01 2025-10-03 12:58:02 -07:00
H. Peter Anvin
063e6d52e0 NASM 3.00 2025-10-03 12:37:44 -07:00
H. Peter Anvin
372e0910ba nasm.spec.in: make -doc package depend on the roboto fonts
It is not *really* required, but it is probably better to have the tag
than not.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-03 12:03:16 -07:00
H. Peter Anvin
568fbff1cd changes.src: add a few more release notes
A few more notes about changes.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-03 12:01:05 -07:00
H. Peter Anvin
e357f9489f NASM 3.00rc20 2025-10-03 10:55:23 -07:00
Fabian Giesen
912849c48c Document Mach-O build_version directive
Signed-off-by: Fabian Giesen <fabian.giesen@epicgames.com>

Resolved Conflicts:
	doc/outfmt.src

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-03 10:48:19 -07:00
Fabian Giesen
83655f041e build_version pragma + macro for Mach-O
Matches the llvm-as .build_version syntax. Newer MacOS linker
complains when object files don't contain a LC_BUILD_VERSION.

Signed-off-by: Fabian Giesen <fabian.giesen@epicgames.com>
2025-10-03 10:47:27 -07:00
Fabian Giesen
0ee113ce68 Don't assume pragma directives are a single word
pragma->tail is described as "anything after the operation", but
existing parsing passed just the first whitespace-delimited
word. Change the parsing to just strip leading and trailing
white space off the rest of the line, but keep interior spaces
if there are any.

This is preparation for a build_version pragma for Mach-O matching
the llvm-as .build_version syntax.

Signed-off-by: Fabian Giesen <fabian.giesen@epicgames.com>
2025-10-03 10:47:25 -07:00
H. Peter Anvin
b4697f09e7 Conditionalize __builtin_prefetch() on it existing!!
You have to check that something that isn't standard C actually exists
before trying to use it...

Cc: Colin Ian King <colin.i.king@intel.com>
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-03 10:47:23 -07:00
Colin Ian King
d6dc97dfc0 Add prefetching on strings before hashing
Turns out that the hotspots of nasm are mainly on string hashing
when accessing memory. A simple performance improvement is to
prefetch the first cacheline of a string to be hashed. Ran 50 tests
on an i9-12900 building intel-ipsec-mb that heavily uses nasm and
improved wall clock build times from 56.1 seconds to 53.2 seconds or
around 5% speed improvement.

Signed-off-by: Colin Ian King <colin.i.king@intel.com>
2025-10-03 10:31:27 -07:00
Zachary Turner
6f48f8f7b7 Support nested response files.
This allows response files specified with -@ to reference other
response files.  This keeps parity with many other common toolchains
such as MSVC, GCC, and Clang which all support nested response
files.

Signed-off-by: Zachary Turner <zturner@roblox.com>
2025-10-03 10:31:12 -07:00
Fabian Giesen
9e03a95922 elf: change form for DW_AT_frame_base to DW_form_exprloc
data4 was not spec-compliant here, causing some tools reading
DWARF debug info to complain. Thanks to Nikita Smith for
debugging this!

Signed-off-by: Fabian Giesen <fabian.giesen@epicgames.com>
2025-10-03 10:30:55 -07:00
KO Myung-Hun
1d72743d6b Disable other warnings in endstruc
endstruc calls __?SECT?__ and this causes unnecessary warnings on obj
output if a section is defined with any attributes, because obj output
does not like a segment definition with any attributes when it appears
again.

Signed-off-by: KO Myung-Hun <komh78@gmail.com>
2025-10-03 10:30:33 -07:00
KO Myung-Hun
bc2108b940 autogen.sh: Use $PATH_SEPARATOR as a path separator of ACLOCAL_PATH
A path separator of ACLOCAL_PATH on OS/2 is ';' not ':'. So use
$PATH_SEPARATOR instead of hard-coded ':'.

Signed-off-by: KO Myung-Hun <komh78@gmail.com>
2025-10-03 10:29:57 -07:00
H. Peter Anvin
95f866d47c changes.src: document FLAT obj changes.
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-03 10:29:08 -07:00
KO Myung-Hun
05343069fa outobj: disallow the combination of USE16(16-bit segment) and FLAT
FLAT should be used only with USE32(32-bit segment).

Signed-off-by: KO Myung-Hun <komh78@gmail.com>
2025-10-03 10:27:39 -07:00
KO Myung-Hun
3f37cacdd2 outobj: allow for segments in the group FLAT to belong to the other group
It's possible that segments belong to both the group FLAT and the other
group because the group FLAT is a pseudo group.

Signed-off-by: KO Myung-Hun <komh78@gmail.com>
2025-10-03 10:27:39 -07:00
H. Peter Anvin
d45ad2e7ed openwcom.mak: use %null instead of @rem for $(SIDE)
%null appears to be the recommended way to do $(SIDE) on WMAKE.

Suggested-by: KO Mying-Hun <komh78@gmail.com>
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-03 10:23:11 -07:00
H. Peter Anvin
a563e84a69 Merge remote-tracking branch 'jperrett256/jdp-doc-edits'
Resolved Conflicts:
	doc/macropkg.src

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
2025-10-03 10:19:32 -07:00
thesmartwon
28b96452a1 fix typo in --help 2025-10-03 10:14:26 -07:00
H. Peter Anvin
505fa79142
Merge pull request #115 from yjh-styx/master
Absent command 'BTS' (typo?)
2025-10-03 10:11:57 -07:00
Yongjie2017
a05239c08e
Merge branch 'netwide-assembler:master' into master 2025-10-03 08:59:55 +08:00
Yongjie2017
f0037ab726
additional note for running nmake building 2025-10-03 08:59:41 +08:00
H. Peter Anvin
f2da39910a doc/rdsrc.pl: fix output file comment
Not at all important, but might as well be consistent...

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-02 17:37:39 -07:00
H. Peter Anvin
40a161bccd NASM 3.00rc19 2025-10-02 17:37:09 -07:00
H. Peter Anvin
467828c431 Even more path hacks for the rpm build
- append /html if htmldir = docdir

- Run autogen.sh with --cleanenv

- Actually use PDFZ and not just Z in doc/Makefile.in.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-02 17:31:58 -07:00
H. Peter Anvin
b0b56c836f tools/release: unset ACLOCAL_PATH
ACLOCAL_PATH should not be used for a release build.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-02 17:12:45 -07:00
H. Peter Anvin
a179a1a826 install: add option for installing .pdf.xz; fix RPMs
- Add an option to use "make install" to install .pdf.xz

- Fix RPM spec file to put the documentation in doc/nasm instead of
  doc/nasm-doc.

- RPM doesn't like unversioned Obsoletes; set a valid cutoff.

- Make nasm-doc depend on nasm.

- Add zlib-devel as a build dependency.

- Add EXTRA_CFLAGS and EXTRA_LDFLAGS for some automated platforms.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-02 17:11:52 -07:00
H. Peter Anvin
7415a1e5f8 Build: update various build installation directories
Modernize and improve the handling of build directories.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-02 16:08:04 -07:00
yjh-styx
4e7a90c4e2
Merge branch 'netwide-assembler:master' into master 2025-10-03 01:45:35 +03:00
H. Peter Anvin
534edcba04 editors: add JSON output
Add JSON formatted editor help output as a way to help more general
editor support code.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-02 14:18:57 -07:00
H. Peter Anvin
c6c67f3011 editors: add explicit special case handing
The automatic extraction procedure can only do so much. At some point
it is simpler to add explicit special case handling.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-02 13:57:15 -07:00
H. Peter Anvin
02042dae1c nasmtok.el: use ${file} to end, to match the start
Use ${file} in both places, in case someone uses a different output
filename for some reason.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-02 13:50:38 -07:00
H. Peter Anvin
01e40a9aeb Move editor help files to editors/, add NASM version number
Move the editor help files (currently nasmtok.el) to the editors/
subdirectory in anticipation of having more such files.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-02 13:49:43 -07:00
H. Peter Anvin
959644a017 msvc.mak: make sure perl is only run if it exists
Only try to run a Perl interpreter if the system actually has one
available. Because timestamps on Windows are apparently not preserved
on archive extraction, otherwise it might happen that nmake will try
to rebuild files even through they already exist.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-01 19:36:22 -07:00
H. Peter Anvin
03391e61ec nasmtok.el: include builtin macros and macro functions
Use a really hacky way to run the NASM binary and extract automatic
builtin macros. As this is not something normally supported during the
NASM build process, the output is canned and will need to be run
manually.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-01 16:06:40 -07:00
H. Peter Anvin
094cc54cd3 emacstbl.pl: extract build-in macro names
Extract builtin macro names into emacstbl.pl, and avoid duplicated
tokens.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-01 15:11:40 -07:00
H. Peter Anvin
869935edfd Merge remote-tracking branch 'emacstbl/emacstbl-footer'
Resolved Conflicts:
	misc/emacstbl.pl

This also reverts the token names to the version without the -token-
infix.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-01 14:35:14 -07:00
H. Peter Anvin
d021e86def NASM 3.00rc18 2025-10-01 14:25:54 -07:00
H. Peter Anvin
72118a9ff6 emacstbl.pl: a few minor tweaks to the emacs token table generator
Hopefully this will be useful to someone.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-01 14:25:04 -07:00
H. Peter Anvin
0b3c971f5b portability: "const macros_t" is redundant
Some C compilers don't like that...

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-01 13:55:38 -07:00
H. Peter Anvin
dfacf9a3d7 Makefiles: remove warnings generation from auxiliary Makefiles
The .time trick doesn't seem to work in general, and auxiliary
Makefiles aren't guaranteed to build modified sources anyway.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-01 13:55:33 -07:00
H. Peter Anvin
205512f3c0 Makefile: a few more portability improvements
Define macros for generating an empty file and for a dummy (side
effect) target.

Tweak MSVC compiler options.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-01 13:55:07 -07:00
H. Peter Anvin
a54a902f4e Makefile: unbreak msvc.mak
With these changes msvc.mak works on Visual Studio 2022.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-01 13:54:04 -07:00
H. Peter Anvin
80cea0baa3 mkdep.pl: don't get confused by messed up line endings
Just strip any whitespace at the end of a line.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-01 13:53:20 -07:00
H. Peter Anvin
37d8ee5768 nasmlib/rlimit.c: fix broken comment
A comment that apparently was mangled during SPDX conversion.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-01 13:53:05 -07:00
yjh-styx
ad0a206964
Merge branch 'netwide-assembler:master' into master 2025-10-01 23:04:07 +03:00
H. Peter Anvin
4acc3dbccc Fix more license headers 2025-10-01 12:05:34 -07:00
H. Peter Anvin
85a8d85174 tools/spdx.pl: use the same format SPDX header ;)
The tool that fixes the files wasn't fixed...

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-01 11:49:23 -07:00
H. Peter Anvin
c811a80700 tools: sync the "cleanfile" and "cleanpatch" with Linux
Sync the "cleanfile" and "cleanpatch" scripts with the versions from
the Linux kernel.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-01 11:46:06 -07:00
H. Peter Anvin
23ce05f906 treewide: replace verbose copyright headers with SPDX tags
SPDX is an international standard for documenting software license
requirements. Remove the existing headers and replace with a brief
SPDX preamble.

See: https://spdx.dev/use/specifications/

The script used to convert the files is added to "tools", and the
file header templates in headers/ are updated.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-01 11:45:31 -07:00
H. Peter Anvin
ee85248e85 version.pl: strip ALL whitespace
Strip all whitespace from version.pl input, in case combinations of
tools causes stray \r or other whitespace characters (which has been
observed.)

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-10-01 11:20:05 -07:00
Iouri Kharon
eb4e4470cc Absent command 'BTS' (typo?) 2025-10-01 11:08:18 +03:00
H. Peter Anvin
f8680b2b45 NASM 3.00rc17 2025-09-30 15:20:48 -07:00
H. Peter Anvin
aa1306c308 ffmpegtest: save the results in a file
Save the result output to a file.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-09-30 15:19:56 -07:00
H. Peter Anvin
981740c7a1 ffmpegtest: don't redo the whole compile every time
Don't redo the whole clone and compile if one wants to re-run the
test. Only rebuild the NASM files.

Minor script cleanups.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-09-30 14:30:04 -07:00
H. Peter Anvin
48f7170772 insns.pl: sanity-check that instruction encodings match operands
Error out if an encoding position is invalid, like an "r" operand
matches an "xmmrm" operand.

Document the instruction encoding symbols; there are too many of them
by now.

Add symbols 'n' and 'w' meaning immediates that are supposed to be
encoded as if they were 'm' memory addresses and 'v' register numbers,
respectively; this is necessary to indicate a validation exception.

Remove broken ARPL "memory-like" encoding. It probably never worked
anyway.

This verification caught two bugs already:

- VPMASKMOV[DQ] cannot omit the second operand.

- Incorrect operand encoding order for VREDUCESH.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-09-30 12:06:11 -07:00
H. Peter Anvin
54547eba35 Merge remote-tracking branch 'yongjie/master' 2025-09-30 09:47:53 -07:00
H. Peter Anvin
595afc6f4b portability: add missing PRI* constants, signed 1 in bitfield hack
Add missing uses of PRI constants.

Create a PRI constant for size_t, since %z isn't available on all
platforms. Notably, the legacy Windows runtime needs %I instead of %z.
Use that on UCRT as well, since there doesn't seem to be a way to
determine if you are compiling for MSVCRT or UCRT.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-09-30 09:41:03 -07:00
Yongjie Sheng
95095b325c add few more avx10.2 convert instructions 2025-09-30 23:29:30 +08:00
Yongjie2017
3095ce61f8
Merge pull request #2 from Yongjie2018/master
Update vmovd and vmovw operand sequence
2025-09-30 14:37:13 +08:00
Sheng, Yongjie
f350ad1f4b Update vmovd and vmovw operand sequence 2025-09-30 15:34:08 +01:00
Sheng, Yongjie
4e7fdc1d62 update travis test for vextract instruction family 2025-09-30 14:47:10 +01:00
Yongjie2017
f513a44f27
Merge pull request #1 from Yongjie2018/master
update travis test for vextract instruction family
2025-09-30 13:49:37 +08:00
Yongjie2017
24557c4128
Merge branch 'netwide-assembler:master' into master 2025-09-30 13:47:51 +08:00
H. Peter Anvin
1185c1f118 Document the [LIST] directive and add -LF option to suppress it
- Document the [LIST] directive
- Add an option -LF to ignore the [LIST] directive
- Fix [LIST -] suppressing output on a following pass
- Minor other documentation fixes

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-09-29 21:48:43 -07:00
Yongjie2017
e6d7fcc62a
Merge branch 'netwide-assembler:master' into master 2025-09-30 11:54:39 +08:00
H. Peter Anvin
df4bb50e23 changes.src: add %use vtern to the release notes
One more thing for the release notes...

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-09-29 20:51:45 -07:00
H. Peter Anvin
f7e91f7868 doc: document %use vtern, minor tidying of the syntax chapter
Document the "vtern" macro package, and do some quite minor tidying of
the syntax chapter.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-09-29 20:47:18 -07:00
H. Peter Anvin
ca0ceeb546 doc: switch from Adobe Source to Google Roboto
The NASM webpage is already using Roboto, and looks more legible in
the end.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-09-29 18:52:01 -07:00
Yongjie2017
c33fd34969
Correct operands sequence for VEXTRACT instruction family 2025-09-30 09:34:07 +08:00
Yongjie2017
9f4e8b95c4
Merge branch 'netwide-assembler:master' into master 2025-09-30 08:50:02 +08:00
H. Peter Anvin
36f4c324d0 doc: add more space after the section numbers in HTML
Use an &ensp; instead of a regular space, and add a period.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-09-29 17:36:04 -07:00
H. Peter Anvin
22cef23b34 macros: add st() macro to the masm macro package
A very easy way to improve portability.  Guarded with %ifndef just in
case...

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-09-29 17:31:42 -07:00
H. Peter Anvin
b80bec7435 doc: "MS-DOS" isn't a literal keyword, don't use \c{}
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-09-29 17:26:17 -07:00
H. Peter Anvin
cf538e23dd doc: tweak the HTML look of fixed text
Go for 90% rather than 80% size;
For inline (code) tags make font bold.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-09-29 17:22:56 -07:00
H. Peter Anvin
7582ebb22a doc: more HTML formatting hacks
Make the titles look nicer...

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-09-29 17:15:43 -07:00
H. Peter Anvin
6a8b135389 NASM 3.00rc16 2025-09-29 16:34:41 -07:00
H. Peter Anvin
55b179ef37 doc: add a few more items to the clean target
Add a few more things that should be cleaned up when making the
documentation...

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-09-29 16:30:57 -07:00
H. Peter Anvin
12f6270124 asm: better error messages for missing instructions
The assembler can't know if something is a colonless label or a
misspelled instruction, so print both when complaining about a missing
instruction.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-09-29 16:09:04 -07:00
H. Peter Anvin
fec865e75e macros: add a %use vtern macro package for ternary logic
A very simple %use package to support the ternary logic
instructions.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-09-29 15:51:23 -07:00
H. Peter Anvin
33f309c886 Merge remote-tracking branch 'maciej/apx.wip.for-hpa' 2025-09-29 15:30:13 -07:00
H. Peter Anvin
c67b688f37 doc: more HTML compliance and prettification work 2025-09-29 14:31:24 -07:00
H. Peter Anvin
0e253844da doc: prettify the HTML documentation
- Improve the look of the TOC
- Add some highlight to code blocks

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-09-29 11:28:12 -07:00
Maciej Wieczor-Retman
c5f7fb183a insns: Move NOP and HINT_NOP at the end of the file
For disassembler to work correctly NOPs should be at the very end of the
database file.

Signed-off-by: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
2025-09-29 17:17:39 +02:00
Maciej Wieczor-Retman
7db0df3a2d doc: Call/Jump subchapter and far call syntax
Start the subchapter on jmp and call syntax summary. Move the far call
syntax paragraph from language chapter to the syntax chapter.

Add a couple of paragraphs about possible syntaxes of the jump/call
instructions.

Signed-off-by: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
2025-09-29 15:08:04 +02:00
Maciej Wieczor-Retman
6cf6693fda doc: Add subchapter on NDS/NDD compact syntax
Signed-off-by: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
2025-09-29 15:07:35 +02:00
Maciej Wieczor-Retman
9abbc4aa41 doc: 64 bit moffs in the syntax chapter
Mention 64 bit moffs and link to the section in the 64-bit chapter.

Signed-off-by: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
2025-09-29 15:05:42 +02:00
Maciej Wieczor-Retman
1653419dde doc: Move the split EA note to the syntax chapter
Add a split EA subchapter to the syntax chapter end remove it from the
language chapter, leaving a hyperlink to the new location.

Signed-off-by: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
2025-09-29 15:03:46 +02:00
Maciej Wieczor-Retman
b48741a833 doc: Add note on lack of syntax for the ternary logic instruction
Signed-off-by: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
2025-09-29 14:59:57 +02:00
Yongjie Sheng
1838e46786 add ffmpeg test 2025-09-28 21:47:44 +08:00
Maciej Wieczor-Retman
9eb39f7ff6 doc: Move APX doc to the syntax doc
The syntax chapter is supposed to be about concepts or instructions that
either have a lot of different syntaxes or new/odd ones.

Signed-off-by: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
2025-09-26 22:12:40 +02:00
Maciej Wieczor-Retman
0e55f84762 doc: Fix missing index tag
\I without anything in the curly brackets made the "procedure linkage
table" text disappear.

Signed-off-by: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
2025-09-26 22:12:40 +02:00
Maciej Wieczor-Retman
a9b35e56b2 doc: Fix missing closing curly brackets
Signed-off-by: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
2025-09-26 22:06:14 +02:00
H. Peter Anvin
945d4327b5 build: even more fixes for building in a separate directory
Move the directories dependency to a variable to break secondary make
versions.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-09-25 13:28:08 -07:00
H. Peter Anvin
fb9afe4226 build: more fixes for building in a separate build directory
- Fix additional broken rules
- Add some more files to WARNOBJ
- $^ is not supported by POSIX, apparently
- Update warnings.pl to *actually* use the srcdir and list of
  passed-in files.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-09-25 13:20:29 -07:00
H. Peter Anvin
1f095bea4a Makefile.in: fix rules for separate-directory build
1. POSIX does not allow $< in a non-pattern rule.
2. insns.xda is a build-time generated file.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-09-25 12:18:02 -07:00
H. Peter Anvin
35bd26e17a NASM 3.00rc15 2025-09-25 12:11:06 -07:00
H. Peter Anvin
1fd289c340 doc: cccl for compiling with MSVC, source build section edits
Make a note about the availability of the cccl wrapper for building
with MSVC using GNU make.

Minor tidying up of the building from source section in general.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-09-25 12:08:58 -07:00
H. Peter Anvin
729abf395d Makefile.in: remove additional path guards
They don't work, and can cause problems.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-09-25 09:46:11 -07:00
H. Peter Anvin
5f67f04f00 Makefile: make nsis building work in a separate build directory
Use $< rather than the hard-coded path

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-09-25 09:30:12 -07:00
H. Peter Anvin
ac1a64c4d2 Makefile: move syncfiles into a separate target
It isn't actually required to have $(PERLREQ) to run syncfiles,
so factor it out into a separate target.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-09-25 09:26:01 -07:00
H. Peter Anvin
512f587ed6 Makefile.in: remove '' filename protect; they don't work anyway
Using '' filename protects break the generated alternative makefiles,
but it is also largely useless -- building in relative paths which
require escaping breaks anyway as make and the shell would require
different escaping.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-09-25 09:13:16 -07:00
H. Peter Anvin
df6b966ca9 nasmlib.h: use int for the enum macros, for strict ISO C
ISO C before C23 restricted enum ranges to type "int" (not even
"unsigned int"). This limits the usability of enums for bit fields,
but it still covers our main use cases.

On gcc/clang this just produces a warning, but who knows what other
compilers will do.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-09-25 08:33:17 -07:00
Yongjie Sheng
8ce0504457 update instruction VP2INTERSECT 2025-09-24 22:12:45 +08:00
Yongjie Sheng
d12a5b5156 add instruction VBCSTNEBF162PS 2025-09-24 21:09:36 +08:00
Yongjie Sheng
e548c76ab3 add AMX instruction TDPFP16PS 2025-09-24 19:52:27 +08:00
H. Peter Anvin
a2a421ec1d NASM 3.00rc14 2025-09-23 21:09:28 -07:00
Yongjie Sheng
b15f0373d6 insns.dat: add the keylocker AESKLEWIDE_KL instructions
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-09-23 21:07:56 -07:00
Yongjie Sheng
8a30c94a09 add aes key locker instructions 2025-09-24 11:25:51 +08:00
H. Peter Anvin
5a32fcb8a7 doc: fix instruction spelling: PPUSH -> PUSHP et al
The "paired" attribute is a suffix, not a prefix.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-09-23 16:00:24 -07:00
H. Peter Anvin
73e666a87e test: check in the actual source file for the pshuf test
Use the source, Luke...

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-09-23 15:57:56 -07:00
H. Peter Anvin
af40cc63d2 isnsn.dat: remove unnecessary SM from PSHUF* instructions
The MMX and early SSE PSHUF* instructions were annotated SM0-1, which
is unnecessary (no ambiguity) but broke the tighter SM matching the
assembler now uses.

This is almost certainly underspecified now, but the MMX and early SSE
instruction patterns need to be tidied up anyway, and this is the
least impactful change that seems to fix the problem.

This unbreaks compiling ffmpeg.

Reported-by: Yongjie Sheng (Intel) <sheng.yongjie@outlook.com>
Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-09-23 15:45:42 -07:00
H. Peter Anvin
ad6752e3e1 NASM 3.00rc13 2025-09-23 12:14:21 -07:00
H. Peter Anvin
c0be53fc85 insns.dat: fix flags for the MSR instructions
- The MSR immediate instructions are under a separate flag
- All MSR instructions are privileged

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-09-23 12:12:12 -07:00
H. Peter Anvin
d782d1339f Merge remote-tracking branch 'maciej/apx.wip.for-hpa' 2025-09-23 12:01:24 -07:00
H. Peter Anvin
7e0dc756f5 doc: tidy up the APX documentation and a few other minor changes
Major tidying up of the APX chapter; do a couple of other minor fixes
in the process.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-09-23 12:00:31 -07:00
H. Peter Anvin
4b0a1a4539 test: simple tests for Scc syntax
Test more Scc syntax cases.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-09-23 11:57:58 -07:00
H. Peter Anvin
e8a0c32ba7 DFV: allow {dfv=pf} as an alias for {dfv=cf}; EQU {dfv}
PF and CF are always set to the same value; allow the programmer to
specify either or both.

Allow EQU to take a {dfv} expression without needing parens.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-09-23 11:56:31 -07:00
Maciej Wieczor-Retman
3edef01637 insns: avx: amx: Add missing instructions from ISE june 2025
Add all the missing instructions / instruction variants that are
specified in the 2025 June Intel ISE.

Signed-off-by: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
2025-09-23 18:56:26 +02:00
Maciej Wieczor-Retman
b92e1c638b insns: avx: Correct VSM4KEY4 memory operand size
Memory operand size for all VSM4KEY4 versions is specified as 128 bit
long, while the ymm register version should use 256 bit size.

Signed-off-by: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
2025-09-23 18:56:25 +02:00
H. Peter Anvin
010b23ae84 altreg.mac: add R16L..R31L
Add macros for the R16L-R31L aliases for the corresponding -B
registers.

The order in the file changed to put all the -L registers at the end,
to make it easier to maintain this file.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-09-23 09:38:28 -07:00
H. Peter Anvin
0393cf6502 doc: document that appendices C, D and E should be unchanged
Currently, the website links directly to appendix C, D, and E by name.

At some point, change the HTML generation to use the chapter names
rather than numbers.

Signed-off-by: H. Peter Anvin (Intel) <hpa@zytor.com>
2025-09-23 08:13:48 -07:00
Maciej Wieczor-Retman
a3191aee77 doc: apx: Document the APX syntax
Add documentation on how the new syntax elements related to APX work.

Signed-off-by: Maciej Wieczor-Retman <maciej.wieczor-retman@intel.com>
2025-09-23 16:01:30 +02:00
Joshua Perrett
afc863ebe3 doc: 64-bit section correction, added info about win64 shadow space
Both Win64 ABI and System V ABI clearly state that 16-byte stack
alignment is required _before_ the call, not after.
Added some additional details about the Win64 ABI, including a mention
of "shadow space", which is one of the less intuitive aspects.
2025-09-09 20:21:25 +01:00
Joshua Perrett
066b045c73 doc: preprocessor section corrections 2025-09-09 20:20:31 +01:00
Joshua Perrett
57e708d349 doc: win64 SEH section edited heavily for clarity 2025-09-09 20:20:31 +01:00
Joshua Perrett
2d9b58f293 doc: corrections and improvements (no changes to intended meaning) 2025-09-09 20:20:31 +01:00
8dcc
8545d631d6
emacstbl.pl: Add proper header and footer 2025-03-20 18:54:12 +01:00
19925 changed files with 262227 additions and 18655 deletions

147
.github/workflows/test.yml vendored Normal file
View file

@ -0,0 +1,147 @@
name: NASM CI/CD
on:
push:
branches: [ "*" ]
pull_request:
branches: [ "*" ]
jobs:
build:
name: Build and test
runs-on: ubuntu-latest
container:
image: ubuntu:24.04
steps:
- name: Install dependencies
run: |
apt-get update && apt-get install -y automake perl python3 build-essential
- name: Checkout repository
uses: actions/checkout@v6
- name: Prepare build system
run: |
sh autogen.sh
sh configure
- name: Build
run: |
make
./nasm --version
- name: Run travis tests
run: |
make travis
- name: Upload travis.log
if: always()
uses: actions/upload-artifact@v7
with:
name: travis-log
path: travis.log
if-no-files-found: warn
build-msvc:
name: Build with MSVC (Windows)
runs-on: windows-latest
steps:
- name: Checkout repository
uses: actions/checkout@v6
- name: Set up MSVC developer environment
# step-security/msvc-dev-cmd is a StepSecurity-maintained,
# actively updated (Node 24) drop-in replacement for
# ilammy/msvc-dev-cmd@v1, which is Node 20 and has no newer
# release addressing that.
uses: step-security/msvc-dev-cmd@v1
with:
arch: x64
- name: Install NSIS
# Needed to build the Windows installer (nsis/nasm.nsi) via the
# "nsis" nmake target below. Not preinstalled on windows-latest.
# choco updates the machine PATH, but that doesn't propagate to
# the already-running Actions Runner process (and thus not to
# later steps), so add makensis's directory to $GITHUB_PATH
# explicitly.
run: |
choco install nsis --no-progress -y
Get-Item "${env:ProgramFiles(x86)}\NSIS", "$env:ProgramFiles\NSIS" -ErrorAction SilentlyContinue |
Select-Object -First 1 -ExpandProperty FullName |
Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
- name: Install Perl CPAN modules for doc build
# doc/genps.pl's font-metrics computation needs Font::TTF, and
# the wider doc toolchain needs a handful of other non-core
# CPAN modules; see doc/perlbreq.src (generated from
# doc/source.src's requirements list by tools/genperlbreq.pl)
# for the authoritative list. windows-latest ships Strawberry
# Perl, which bundles cpanm.
shell: cmd
run: cpanm --notest Font::TTF JSON Sort::Versions Compress::Zlib Win32::TieRegistry
- name: Install Ghostscript and doc-build fonts
# nasmdoc.pdf (packaged into the installer) is built via
# doc/pspdf.pl, which shells out to Ghostscript, and
# doc/genps.pl, which needs the Roboto and Roboto Mono font
# files to compute glyph metrics (see doc/source.src, "Optional
# Build Tools"). Neither is preinstalled on windows-latest.
#
# Font versions match what Fedora's google-roboto-fonts (from
# github.com/google/roboto, release v2.138) and
# google-roboto-mono-fonts (from github.com/googlefonts/RobotoMono)
# packages ship, which is known-good: only Bold/BoldItalic/
# Italic/Regular of Roboto and Bold/Medium/Regular of Roboto
# Mono are actually used by doc/psfonts.ph. Dropping the .ttf
# files straight into %windir%\Fonts is sufficient: findfont.ph
# falls back to scanning that directory directly and identifies
# faces from each file's own name table, no font-registration
# step required.
shell: pwsh
run: |
choco install ghostscript --no-progress -y
$fontsDir = "$env:windir\Fonts"
Invoke-WebRequest -Uri "https://github.com/google/roboto/releases/download/v2.138/roboto-unhinted.zip" -OutFile roboto.zip
Expand-Archive -Path roboto.zip -DestinationPath roboto-unhinted
foreach ($f in "Regular", "Bold", "Italic", "BoldItalic") {
Copy-Item "roboto-unhinted\Roboto-$f.ttf" $fontsDir
}
foreach ($f in "Regular", "Bold", "Medium") {
Invoke-WebRequest -Uri "https://raw.githubusercontent.com/googlefonts/RobotoMono/main/fonts/ttf/RobotoMono-$f.ttf" -OutFile "$fontsDir\RobotoMono-$f.ttf"
}
- name: Build with nmake/cl.exe
shell: cmd
run: |
nmake /f Mkfiles\msvc.mak
- name: Smoke-test the resulting binaries
shell: cmd
run: |
nasm.exe --version
ndisasm.exe --version
echo mov eax, 1 > smoke.asm
echo ret >> smoke.asm
nasm.exe -f bin smoke.asm -o smoke.bin
ndisasm.exe -b 64 smoke.bin
nasm.exe -f win64 smoke.asm -o smoke.obj
- name: Build documentation and NSIS installer
shell: cmd
run: |
nmake /f Mkfiles\msvc.mak docs
nmake /f Mkfiles\msvc.mak nsis
- name: Upload installer artifact
uses: actions/upload-artifact@v7
with:
name: nasm-windows-installer
path: nasm-*-installer-*.exe
if-no-files-found: error

12
.gitignore vendored
View file

@ -2,6 +2,9 @@
*.aout
*.aoutb
*.bin
*.bin16
*.bin32
*.bin64
*.coff
*.com
*.dbg
@ -11,6 +14,7 @@
*.ith
*.lib
*.lst
*.log
*.map
*.mo32
*.mo64
@ -78,9 +82,10 @@ TAGS
/doc/pptok.src
/doc/fontpath
/doc/Fontmap
/editors/nasmtok.el
/editors/nasmtok.json
/include/warnings.h
/macros/macros.c
/misc/nasmtok.el
/misc/omfdump
/misc/Makefile
/nasm
@ -93,6 +98,10 @@ TAGS
/test/golden
/test/perf/*.asm
/test/testresults
/test/ffmpegtest
/test/x264test
/travis.mk
/travis.mak
/version.h
/version.mac
/version.mak
@ -116,3 +125,4 @@ TAGS
/autoconf/config.*
/autoconf/install-sh
/autoconf/clean.sh
/travis/_version/_version.stdout

View file

@ -52,8 +52,8 @@ D: RDOFF support
N: H. Peter Anvin
E: hpa@zytor.com
D: Primary maintainer for the 0.98, late 0.98.x and 2.x releases.
C: Contributions since 2008-12-15 are Copyright Intel Corporation.
D: Primary maintainer for the 0.98, late 0.98.x and 2+ releases.
C: Contributions from 2008-12-15 to 2026-08-15 are Copyright Intel Corporation.
N: John Fine
E: johnfine@earthlink.net

View file

@ -1,7 +1,9 @@
NASM is now licensed under the 2-clause BSD license, also known as the
simplified BSD license.
Copyright 1996-2010 the NASM Authors - All rights reserved.
SPDX-License-Identifier: BSD-2-Clause
Copyright 1996-2025 the NASM Authors - All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following
@ -13,7 +15,7 @@ simplified BSD license.
copyright notice, this list of conditions and the following
disclaimer in the documentation and/or other materials provided
with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF

View file

@ -1,12 +1,14 @@
#
# -*- makefile -*-
# SPDX-License-Identifier: BSD-2-Clause
# Copyright 1996-2025 The NASM Authors - All Rights Reserved
# Auto-configuring Makefile for the Netwide Assembler.
#
# The Netwide Assembler is copyright (C) 1996 Simon Tatham and
# Julian Hall. All rights reserved. The software is
# redistributable under the license given in the file "LICENSE"
# distributed in the NASM archive.
@SET_MAKE@
export MAKE
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
top_srcdir = @top_srcdir@
srcdir = @srcdir@
@ -17,6 +19,12 @@ exec_prefix = @exec_prefix@
bindir = @bindir@
mandir = @mandir@
datarootdir = @datarootdir@
datadir = @datadir@
pkgdatadir = $(datadir)/$(PACKAGE_TARNAME)
docdir = @docdir@
htmldir = @htmldir@
pdfdir = @pdfdir@
psdir = @psdir@
CC = @CC@
CFLAGS = @CFLAGS@
@ -30,9 +38,11 @@ INTERNAL_CFLAGS = -I$(srcdir) -I$(objdir) \
-I$(srcdir)/disasm -I$(objdir)/disasm \
-I$(srcdir)/output -I$(objdir)/output \
$(ZLIBINC)
ALL_CFLAGS = $(BUILD_CFLAGS) $(INTERNAL_CFLAGS)
EXTRA_CFLAGS =
ALL_CFLAGS = $(BUILD_CFLAGS) $(INTERNAL_CFLAGS) $(EXTRA_CFLAGS)
LDFLAGS = @LDFLAGS@
ALL_LDFLAGS = $(ALL_CFLAGS) $(LDFLAGS)
EXTRA_LDFLAGS =
ALL_LDFLAGS = $(ALL_CFLAGS) $(LDFLAGS) $(EXTRA_LDFLAGS)
LIBS = @LIBS@
ZLIB = @ZLIB@
@ -49,15 +59,16 @@ PERLFLAGS = -I$(top_srcdir)/perllib -I$(srcdir)
RUNPERL = $(PERL) $(PERLFLAGS)
EMPTY = : >
SIDE = @: Generated by side effect
PYTHON3 = python3
PYTHON3 = @PYTHON3@
GREP = grep
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
# Optional tools
NROFF = @NROFF@
ASCIIDOC = @ASCIIDOC@
XMLTO = @XMLTO@
MAKENSIS = @MAKENSIS@
@ -93,9 +104,12 @@ endif
.SUFFIXES:
.SUFFIXES: $(X) .$(O) .$(A) .xml .1 .c .i .s .txt .time
# Use to mark phony targets in global lists
PHONY =
.PHONY: all doc misc install clean distclean cleaner spotless test
.PHONY: install_doc everything install_everything strip perlreq dist tags TAGS
.PHONY: nothing manpages nsis
.PHONY: install_doc everything install_everything strip perlreq warnings
.PHONY: dist tags TAGS nothing manpages nsis editors travis
.c.$(O):
$(CC) -c $(ALL_CFLAGS) -o $@ $<
@ -121,7 +135,46 @@ NDISASM = disasm/ndisasm.$(O)
PROGOBJ = $(NASM) $(NDISASM)
PROGS = nasm$(X) ndisasm$(X)
# Files dependent on extracted warnings
# Objects for the local copy of zlib. The variable ZLIB is set to
# $(ZLIBOBJ) if the internal version of zlib should be used.
ZLIBOBJ = \
zlib/adler32.$(O) \
zlib/crc32.$(O) \
zlib/infback.$(O) \
zlib/inffast.$(O) \
zlib/inflate.$(O) \
zlib/inftrees.$(O) \
zlib/zutil.$(O)
# Common library objects
LIBOBJ_COM = \
stdlib/snprintf.$(O) stdlib/vsnprintf.$(O) stdlib/strlcpy.$(O) \
stdlib/strnlen.$(O) \
\
nasmlib/ver.$(O) \
nasmlib/alloc.$(O) nasmlib/asprintf.$(O) \
nasmlib/crc32b.$(O) nasmlib/crc64.$(O) nasmlib/md5c.$(O) \
nasmlib/string.$(O) nasmlib/nctype.$(O) \
nasmlib/file.$(O) nasmlib/fileio.$(O) nasmlib/mmap.$(O) \
nasmlib/realpath.$(O) nasmlib/path.$(O) \
nasmlib/ilog2.$(O) nasmlib/numstr.$(O) \
nasmlib/rlimit.$(O) \
nasmlib/zerobuf.$(O) nasmlib/bsi.$(O) \
nasmlib/rbtree.$(O) nasmlib/hashtbl.$(O) \
nasmlib/raa.$(O) nasmlib/saa.$(O) \
nasmlib/strlist.$(O) \
nasmlib/perfhash.$(O) nasmlib/badenum.$(O) \
nasmlib/readnum.$(O) \
\
common/common.$(O) common/errstubs.$(O) common/files.$(O) \
\
x86/insnsa.$(O) x86/insnsb.$(O) x86/insnsn.$(O) \
x86/regs.$(O) x86/regvals.$(O) x86/regflags.$(O) \
x86/iflag.$(O) \
\
$(ZLIB)
# Files dependent on warnings.dat
WARNOBJ = asm/warnings.$(O)
WARNFILES = asm/warnings_c.h include/warnings.h doc/warnings.src
@ -134,10 +187,8 @@ OUTPUTOBJ = \
output/outdbg.$(O) output/outieee.$(O) output/outmacho.$(O) \
output/codeview.$(O)
# The source files for these objects are scanned for warnings
LIBOBJ_W = \
nasmlib/readnum.$(O) \
\
# Assembler-only library objects
LIBOBJ_ASM = \
asm/error.$(O) \
asm/floats.$(O) \
asm/directiv.$(O) \
@ -150,16 +201,7 @@ LIBOBJ_W = \
asm/strfunc.$(O) \
asm/segalloc.$(O) \
asm/rdstrnum.$(O) \
asm/srcfile.$(O)
# The source files for these objects are NOT scanned for warnings;
# normally this will include all generated files.
# It is entirely possible that it may be necessary to move some of these
# files to LIBOBJ_W, notably $(OUTPUTOBJ)
LIBOBJ_NW = \
stdlib/snprintf.$(O) stdlib/vsnprintf.$(O) stdlib/strlcpy.$(O) \
stdlib/strnlen.$(O) stdlib/strrchrnul.$(O) \
\
asm/srcfile.$(O) \
asm/directbl.$(O) \
asm/pptok.$(O) \
asm/tokhash.$(O) \
@ -167,84 +209,62 @@ LIBOBJ_NW = \
\
macros/macros.$(O) \
\
nasmlib/ver.$(O) \
nasmlib/alloc.$(O) nasmlib/asprintf.$(O) \
nasmlib/crc32.$(O) nasmlib/crc64.$(O) nasmlib/md5c.$(O) \
nasmlib/string.$(O) nasmlib/nctype.$(O) \
nasmlib/file.$(O) nasmlib/mmap.$(O) nasmlib/ilog2.$(O) \
nasmlib/realpath.$(O) nasmlib/path.$(O) \
nasmlib/filename.$(O) nasmlib/rlimit.$(O) \
nasmlib/numstr.$(O) \
nasmlib/zerobuf.$(O) nasmlib/bsi.$(O) \
nasmlib/rbtree.$(O) nasmlib/hashtbl.$(O) \
nasmlib/raa.$(O) nasmlib/saa.$(O) \
nasmlib/strlist.$(O) \
nasmlib/perfhash.$(O) nasmlib/badenum.$(O) \
\
common/common.$(O) \
\
x86/insnsa.$(O) x86/insnsb.$(O) x86/insnsn.$(O) \
x86/regs.$(O) x86/regvals.$(O) x86/regflags.$(O) \
x86/iflag.$(O) \
\
$(OUTPUTOBJ) \
\
$(WARNOBJ)
$(WARNOBJ) \
$(OUTPUTOBJ)
# Objects which are only used for the disassembler
LIBOBJ_DIS = \
disasm/disasm.$(O) disasm/sync.$(O) disasm/prefix.$(O) \
disasm/diserror.$(O) \
\
x86/insnsd.$(O) x86/regdis.$(O)
# Objects for the local copy of zlib. The variable ZLIB is set to
# $(ZLIBOBJ) if the internal version of zlib should be used.
ZLIBOBJ = \
zlib/adler32.$(O) \
zlib/crc32.$(O) \
zlib/infback.$(O) \
zlib/inffast.$(O) \
zlib/inflate.$(O) \
zlib/inftrees.$(O) \
zlib/zutil.$(O)
LIBOBJ = $(LIBOBJ_W) $(LIBOBJ_NW) $(ZLIB)
ALLOBJ_W = $(NASM) $(LIBOBJ_W)
LIBOBJ = $(LIBOBJ_COM) $(LIBOBJ_ASM) $(LIBOBJ_DIS)
ALLOBJ = $(PROGOBJ) $(LIBOBJ)
SUBDIRS = stdlib nasmlib include config output asm disasm x86 \
common zlib macros misc
XSUBDIRS = test doc nsis win
XSUBDIRS = nsis win test doc editors
DEPDIRS = . $(SUBDIRS)
EDITORS = editors/nasmtok.el editors/nasmtok.json
#-- End File Lists --#
all: dirs
$(MAKE) $(PROGS)
all: $(PROGS)
DIRS = dirs
$(DIRS):
@$(MKDIR_P) $(SUBDIRS) $(XSUBDIRS)
NASMLIB = libnasm.$(A)
DISLIB = libndis.$(A)
ASMLIB = libasm.$(A)
DISLIB = libdis.$(A)
dirs:
$(MKDIR_P) $(SUBDIRS) $(XSUBDIRS)
$(NASMLIB): $(LIBOBJ)
$(NASMLIB): $(LIBOBJ_COM)
$(RM_F) $(NASMLIB)
$(AR) cq $(NASMLIB) $(LIBOBJ)
$(AR) cq $(NASMLIB) $(LIBOBJ_COM)
$(RANLIB) $(NASMLIB)
$(ASMLIB): $(LIBOBJ_ASM)
$(RM_F) $(ASMLIB)
$(AR) cq $(ASMLIB) $(LIBOBJ_ASM)
$(RANLIB) $(ASMLIB)
$(DISLIB): $(LIBOBJ_DIS)
$(RM_F) $(DISLIB)
$(AR) cq $(DISLIB) $(LIBOBJ_DIS)
$(RANLIB) $(DISLIB)
nasm$(X): $(NASM) $(MANIFEST) $(NASMLIB)
$(CC) $(ALL_LDFLAGS) -o nasm$(X) $^ $(LIBS)
nasm$(X): $(NASM) $(MANIFEST) $(ASMLIB) $(NASMLIB)
$(CC) $(ALL_LDFLAGS) -o $@ $(NASM) $(MANIFEST) \
$(ASMLIB) $(NASMLIB) $(LIBS)
ndisasm$(X): $(NDISASM) $(MANIFEST) $(DISLIB) $(NASMLIB)
$(CC) $(ALL_LDFLAGS) -o ndisasm$(X) $^ $(LIBS)
$(CC) $(ALL_LDFLAGS) -o $@ $(NDISASM) $(MANIFEST) \
$(DISLIB) $(NASMLIB) $(LIBS)
# These are specific to certain Makefile syntaxes...
WARNTIMES = $(WARNFILES:=.time)
WARNSRCS = $(ALLOBJ_W:.$(O)=.c)
# Make sure we have subdirectories set up...
$(ALLOBJ): $(DIRS)
#-- Begin Generated File Rules --#
@ -261,43 +281,36 @@ PERLREQ_CLEANABLE = \
macros/macros.c \
asm/pptok.ph asm/directbl.c asm/directiv.h \
$(WARNFILES) \
misc/nasmtok.el \
version.h version.mac version.mak nsis/version.nsh
# Special hack to keep config/unconfig.h from getting deleted
# by "make spotless"...
PERLREQ = config/unconfig.h $(PERLREQ_CLEANABLE)
PERLREQ = $(PERLREQ_CLEANABLE)
INSDEP = x86/insns.xda x86/insns.pl x86/insns-iflags.ph x86/iflags.ph
INSDEP = x86/insns.xda x86/insns.pl x86/insns-iflags.ph x86/iflags.ph x86/insns-cc.ph
x86/insns.xda: x86/insns.dat x86/preinsns.pl
$(RUNPERL) '$(srcdir)'/x86/preinsns.pl $< $@
config/unconfig.h: config/config.h.in autoconf/unconfig.pl
$(RUNPERL) '$(srcdir)'/autoconf/unconfig.pl \
'$(srcdir)' config/config.h.in config/unconfig.h
x86/insns.xda: x86/insns.dat x86/preinsns.pl $(DIRS)
$(RUNPERL) $(srcdir)/x86/preinsns.pl $(srcdir)/x86/insns.dat $@
x86/iflag.c: $(INSDEP)
$(RUNPERL) $(srcdir)/x86/insns.pl -fc \
$(srcdir)/x86/insns.xda x86/iflag.c
x86/insns.xda x86/iflag.c
x86/iflaggen.h: $(INSDEP)
$(RUNPERL) $(srcdir)/x86/insns.pl -fh \
$(srcdir)/x86/insns.xda x86/iflaggen.h
x86/insns.xda x86/iflaggen.h
x86/insnsb.c: $(INSDEP)
$(RUNPERL) $(srcdir)/x86/insns.pl -b \
$(srcdir)/x86/insns.xda x86/insnsb.c
x86/insns.xda x86/insnsb.c
x86/insnsa.c: $(INSDEP)
$(RUNPERL) $(srcdir)/x86/insns.pl -a \
$(srcdir)/x86/insns.xda x86/insnsa.c
x86/insns.xda x86/insnsa.c
x86/insnsd.c: $(INSDEP)
$(RUNPERL) $(srcdir)/x86/insns.pl -d \
$(srcdir)/x86/insns.xda x86/insnsd.c
x86/insns.xda x86/insnsd.c
x86/insnsi.h: $(INSDEP)
$(RUNPERL) $(srcdir)/x86/insns.pl -i \
$(srcdir)/x86/insns.xda x86/insnsi.h
x86/insns.xda x86/insnsi.h
x86/insnsn.c: $(INSDEP)
$(RUNPERL) $(srcdir)/x86/insns.pl -n \
$(srcdir)/x86/insns.xda x86/insnsn.c
x86/insns.xda x86/insnsn.c
# These files contains all the standard macros that are derived from
# the version number.
@ -309,7 +322,7 @@ version.sed: version version.pl
$(RUNPERL) $(srcdir)/version.pl sed < $(srcdir)/version > version.sed
version.mak: version version.pl
$(RUNPERL) $(srcdir)/version.pl make < $(srcdir)/version > version.mak
nsis/version.nsh: version version.pl
nsis/version.nsh: version version.pl $(DIRS)
$(RUNPERL) $(srcdir)/version.pl nsis < $(srcdir)/version > nsis/version.nsh
# This source file is generated from the standard macros file
@ -341,43 +354,6 @@ x86/regs.h: x86/regs.dat x86/regs.pl
$(RUNPERL) $(srcdir)/x86/regs.pl h \
$(srcdir)/x86/regs.dat > x86/regs.h
# Extract warnings from source code. This is done automatically if any
# C files have changed; the script is fast enough that that is
# reasonable, but doesn't update the time stamp if the files aren't
# changed, to avoid rebuilding everything every time. Track the actual
# dependency by the empty file asm/warnings.time.
.PHONY: warnings
warnings: dirs
$(RM_F) $(WARNFILES) $(WARNTIMES) asm/warnings.time
$(MAKE) asm/warnings.time
asm/warnings.time: $(WARNSRCS) asm/warnings.pl
$(EMPTY) asm/warnings.time
$(MAKE) $(WARNTIMES)
asm/warnings_c.h.time: asm/warnings.pl asm/warnings.time
$(RUNPERL) $(srcdir)/asm/warnings.pl c asm/warnings_c.h \
'$(srcdir)' $(WARNSRCS)
$(EMPTY) asm/warnings_c.h.time
asm/warnings_c.h: asm/warnings_c.h.time
@: Side effect
include/warnings.h.time: asm/warnings.pl asm/warnings.time
$(RUNPERL) $(srcdir)/asm/warnings.pl h include/warnings.h \
'$(srcdir)' $(WARNSRCS)
$(EMPTY) include/warnings.h.time
include/warnings.h: include/warnings.h.time
@: Side effect
doc/warnings.src.time: asm/warnings.pl asm/warnings.time
$(RUNPERL) $(srcdir)/asm/warnings.pl doc doc/warnings.src \
'$(srcdir)' $(WARNSRCS)
$(EMPTY) doc/warnings.src.time
doc/warnings.src : doc/warnings.src.time
@: Side effect
# Assembler token hash
asm/tokhash.c: x86/insns.xda x86/insnsn.c asm/tokens.dat asm/tokhash.pl \
@ -415,33 +391,58 @@ asm/directbl.c: asm/directiv.dat nasmlib/perfhash.pl perllib/phash.ph
$(RUNPERL) $(srcdir)/nasmlib/perfhash.pl c \
$(srcdir)/asm/directiv.dat asm/directbl.c
# Emacs token files
misc/nasmtok.el: misc/emacstbl.pl asm/tokhash.c asm/pptok.c \
asm/directiv.dat version
$(RUNPERL) $< $@ "$(srcdir)" "$(objdir)"
# Editor token files
editors/nasmtok.el: editors/nasmtok.pl asm/tokhash.c asm/pptok.c \
asm/directiv.dat macros/macros.c editors/builtin.mac \
version.mak
$(RUNPERL) $(srcdir)/editors/nasmtok.pl -el $@ $(srcdir) $(objdir)
editors/nasmtok.json: editors/nasmtok.pl asm/tokhash.c asm/pptok.c \
asm/directiv.dat macros/macros.c editors/builtin.mac \
version.mak
$(RUNPERL) $(srcdir)/editors/nasmtok.pl -json $@ $(srcdir) $(objdir)
editors: $(EDITORS) $(PHONY)
asm/warnings_c.h: asm/warnings.pl asm/warnings.dat
$(RUNPERL) $(srcdir)/asm/warnings.pl c asm/warnings_c.h \
$(srcdir)/asm/warnings.dat
include/warnings.h: asm/warnings.pl asm/warnings.dat
$(RUNPERL) $(srcdir)/asm/warnings.pl h include/warnings.h \
$(srcdir)/asm/warnings.dat
doc/warnings.src: asm/warnings.pl asm/warnings.dat
$(RUNPERL) $(srcdir)/asm/warnings.pl doc doc/warnings.src \
$(srcdir)/asm/warnings.dat
$(PERLREQ): $(DIRS)
perlreq: $(PERLREQ) $(PHONY)
warnings: $(WARNFILES) $(PHONY)
#-- End Generated File Rules --#
perlreq: dirs
$(MAKE) $(PERLREQ)
#-- Begin NSIS Rules --#
nsis/arch.nsh: nsis/getpearch.pl nasm$(X)
nsis/arch.nsh: nsis/getpearch.pl nasm$(X) $(DIRS)
$(PERL) $(srcdir)/nsis/getpearch.pl nasm$(X) > nsis/arch.nsh
# Should only be done after "make everything".
# The use of redirection here keeps makensis from moving the cwd to the
# source directory.
nsis: nsis/nasm.nsi nsis/arch.nsh nsis/version.nsh
$(MAKENSIS) -Dsrcdir="$(srcdir)" -Dobjdir="$(objdir)" - < nsis/nasm.nsi
$(MAKENSIS) -Dsrcdir=$(srcdir) -Dobjdir=$(objdir) - \
< $(srcdir)/nsis/nasm.nsi
#-- End NSIS Rules --#
# Windows embedded manifest
MANIFEST_RC = win/manifest.rc
win/manifest.$(O): win/manifest.xml $(MANIFEST_RC)
$(WINDRES) -I. -Iwin -DMANIFEST_FILE='\"$<\"' -i $(MANIFEST_RC) -o $@
win/manifest.$(O): win/manifest.xml $(MANIFEST_RC) $(DIRS)
$(WINDRES) -I. -Iwin -DMANIFEST_FILE='\"$(srcdir)/manifest.xml\"' \
-i $(MANIFEST_RC) -o $@
# Generated manpages, also pregenerated for distribution
manpages: nasm.1 ndisasm.1
@ -453,6 +454,10 @@ install: $(PROGS)
$(INSTALL_DATA) $(srcdir)/nasm.1 $(DESTDIR)$(mandir)/man1/nasm.1
$(INSTALL_DATA) $(srcdir)/ndisasm.1 $(DESTDIR)$(mandir)/man1/ndisasm.1
install_editors: $(EDITORS)
$(MKDIR_P) $(DESTDIR)$(pkgdatadir)
$(INSTALL_DATA) $(EDITORS) $(DESTDIR)$(pkgdatadir)
clean:
for d in . $(SUBDIRS) $(XSUBDIRS); do \
$(RM_F) "$$d"/*.$(O) "$$d"/*.s "$$d"/*.i "$$d"/*.$(A) ; \
@ -465,15 +470,14 @@ clean:
distclean: clean
for d in . $(SUBDIRS) $(XSUBDIRS); do \
$(RM_F) "$$d"/.\# "$$d"/\# "$$d"/*~ "$$d"/*.bak \
"$$d"/*.lst "$$d"/*.bin ; \
$(RM_F) "$$d"/.\#* "$$d"/\#* "$$d"/*~ "$$d"/*.bak \
"$$d"/*.lst "$$d"/*.bin "$$d"/*.dep ; \
done
$(RM_F) test/*.$(O)
$(RM_F) *.dep
-$(SHELL) autoconf/clean.sh || $(SHELL) '$(srcdir)'/autoconf/clean.sh
-$(SHELL) autoconf/clean.sh || $(SHELL) $(srcdir)/autoconf/clean.sh
cleaner:
$(RM_F) $(PERLREQ_CL) *.1 nasm.spec
$(RM_F) $(PERLREQ_CL) $(EDITORS) *.1 nasm.spec
$(MAKE) -C doc clean
$(MAKE) -C misc clean
$(MAKE) distclean
@ -504,7 +508,9 @@ doc: doc/warnings.src doc/perlbreq.src doc/pptok.src
doc_install install_doc install-doc:
$(MAKE) -C doc install
.PHONY: misc
misc:
$(MKDIR_P) misc
$(MAKE) -C misc all
misc_install install_misc install-misc:
@ -513,19 +519,24 @@ misc_install install_misc install-misc:
# Dummy target to prevent accidental invocation of the default "all" target
nothing:
always_everything: dirs
always_everything: $(DIRS)
$(MAKE) all doc
everything: always_everything
$(MAKE) $(MANPAGES) $(NSIS) nothing
install_everything: everything install install_doc
install_everything: everything install install_doc install_editors
editor_builtin: nasm$(X)
$(SHELL) editors/dumpbuiltin.sh ./nasm$(X) > editors/builtin.mac
dist:
$(MAKE) alldeps
$(MAKE) perlreq warnings spec $(MANPAGES)
$(MAKE) perlreq spec
$(MAKE) editor_builtin
$(MAKE) editors $(MANPAGES)
$(MAKE) distclean
./autogen.sh
$(SHELL) autogen.sh --clearenv
tar: dist
tar -cv --exclude CVS --exclude .git -C .. -f - `basename \`pwd\`` | \
@ -540,7 +551,7 @@ perlbreq.si: $(ALLPERLSRC)
sed -r -e '/perl\((Win32.*)\)/d' | \
sort | uniq > perlbreq.si
doc/perlbreq.src: perlbreq.si
doc/perlbreq.src: perlbreq.si $(DIRS)
sed -n -r -e 's/^BuildRequires: perl\((.*)\)$$/\\c \1/p' \
< perlbreq.si > doc/perlbreq.src
echo '\c Win32 (if building on Windows only)' >> doc/perlbreq.src
@ -552,14 +563,17 @@ nasm.spec: nasm.spec.in nasm.spec.sed version.sed perlbreq.si
splint:
splint -weak *.c
test: $(PROGS)
cd test && $(RUNPERL) performtest.pl --nasm=../nasm *.asm
#
# Travis tests
#
travis test: $(PROGS)
$(MAKE) -f travis.mak all
golden: $(PROGS)
cd test && $(RUNPERL) performtest.pl --golden --nasm=../nasm *.asm
clean-travis travis-clean:
$(MAKE) -f travis.mak clean
travis: $(PROGS)
$(PYTHON3) travis/nasm-t.py run
update-travis travis-update golden:
$(MAKE) -f travis.mak update
#
# Rules to run autogen if necessary
@ -581,13 +595,12 @@ doc/Makefile: Makefile
config/config.h: config.status
#
# Dummy rules that changes make behavior
# (at end to avoid confusing non-GNU makes)
#
.SECONDARY:
.DELETE_ON_ERROR:
#
# Synchronize auxiliary Makefiles
#
syncfiles: $(tools)/syncfiles.pl
$(RUNPERL) $(tools)/syncfiles.pl Makefile.in Mkfiles/*.mak
#
# Does this version of this file have external dependencies? This definition
@ -602,19 +615,17 @@ EXTERNAL_DEPENDENCIES = 1
# pollute the git logs.
#
Makefile.dep: $(tools)/mkdep.pl config.status $(PERLREQ)
$(RUNPERL) $(tools)/mkdep.pl -s '$(top_srcdir)' \
$(RUNPERL) $(tools)/mkdep.pl -s $(top_srcdir) \
-M $(srcdir)/Makefile.in -- $(DEPDIRS)
dep: Makefile.dep
#
# This build dependencies in *ALL* makefiles, and forces all
# dependencies to be inserted inline. For that reason, it should only
# be invoked manually or via "make dist". It should be run before
# creating release archives.
#
alldeps: $(PERLREQ) $(tools)/syncfiles.pl $(tools)/mkdep.pl
$(RUNPERL) $(tools)/syncfiles.pl Makefile.in Mkfiles/*.mak
alldeps: syncfiles $(PERLREQ) $(tools)/mkdep.pl
$(RUNPERL) $(tools)/mkdep.pl -i -M Makefile.in Mkfiles/*.mak -- \
$(DEPDIRS)
$(RM_F) *.dep
@ -624,8 +635,7 @@ alldeps: $(PERLREQ) $(tools)/syncfiles.pl $(tools)/mkdep.pl
# Strip internal dependency information from all Makefiles; this makes
# the output good for git checkin
cleandeps: $(PERLREQ) $(tools)/syncfiles.pl $(tools)/mkdep.pl
$(RUNPERL) $(tools)/syncfiles.pl Makefile.in Mkfiles/*.mak
cleandeps: syncfiles $(PERLREQ) $(tools)/mkdep.pl
$(RUNPERL) $(tools)/mkdep.pl -e -M Makefile.in Mkfiles/*.mak -- \
$(DEPDIRS)
$(RM_F) *.dep
@ -633,6 +643,14 @@ cleandeps: $(PERLREQ) $(tools)/syncfiles.pl $(tools)/mkdep.pl
sh config.status; \
fi
#
# Dummy rules that changes make behavior
# (at end to avoid confusing non-GNU makes)
#
.SECONDARY:
.DELETE_ON_ERROR:
#-- Magic hints to mkdep.pl --#
# @object-ending: ".$(O)"
# @path-separator: "/"

View file

@ -10,6 +10,8 @@ The Makefiles are:
For building on a Win32 host using Microsoft Visual C++.
Usage: nmake /f Mkfiles\msvc.mak
(Note: make sure you have a MSVC Developer Command Prompt console before
running the nmake command)
If the following tools are installed, the full installer package can
be built:
@ -19,8 +21,8 @@ The Makefiles are:
http://nsis.sourceforge.net/Download
3. Ghostscript (ps2pdf) or Acrobat Distriller (acrodist)
https://downloads.ghostscript.com/
4. The Adobe Source Sans Pro and Source Code Pro fonts
https://github.com/adobe-fonts
4. The Google Roboto and Roboto Mono fonts
https://github.com/googlefonts/
5. The Perl module Font::TTF (can usually be installed
via the "CPAN Client" in your Perl distribution)
http://search.cpan.org/~bhallissy/Font-TTF/

View file

@ -1,11 +1,11 @@
# -*- makefile -*-
# SPDX-License-Identifier: BSD-2-Clause
# Copyright 1996-2025 The NASM Authors - All Rights Reserved
#
# Makefile for building NASM using Microsoft Visual C++ and NMAKE.
# Tested on Microsoft Visual C++ 2005 Express Edition.
#
# Make sure to put the appropriate directories in your PATH, in
# the case of MSVC++ 2005, they are ...\VC\bin and ...\Common7\IDE.
# Last tested on Visual Studio 2022 Community Edition.
#
# Make sure to have the proper directories in your path.
# This is typically done by opening the Visual Studio Command Prompt.
#
@ -18,39 +18,49 @@ exec_prefix = $(prefix)
bindir = $(prefix)/bin
mandir = $(prefix)/man
MANIFEST_FLAGS = /MANIFEST:EMBED /MANIFESTFILE:$(MANIFEST)
MANIFEST_FLAGS = /manifest:embed /manifestfile:$(MANIFEST)
!IF "$(DEBUG)" == "1"
CFLAGS = /Od /Zi
LDFLAGS = /DEBUG
OPTFLAGS = /Od
LDFLAGS = /debug
!ELSE
CFLAGS = /O2 /Zi
OPTFLAGS = /O2
# /OPT:REF and /OPT:ICF two undo /DEBUG harm
LDFLAGS = /DEBUG /OPT:REF /OPT:ICF
LDFLAGS = /debug /opt:ref /opt:icf
!ENDIF
CC = cl
AR = lib
ARFLAGS = /nologo
CFLAGS = $(OPTFLAGS) /Zi /nologo /std:c11 /bigobj
BUILD_CFLAGS = $(CFLAGS) /W2
INTERNAL_CFLAGS = /I$(srcdir) /I. \
/I$(srcdir)/include /I./include \
/I$(srcdir)/x86 /I./x86 \
/I$(srcdir)/asm /I./asm \
/I$(srcdir)/disasm /I./disasm \
/I$(srcdir)/output /I./output
/I$(srcdir)/output /I./output \
/I$(srcdir)/zlib
ALL_CFLAGS = $(BUILD_CFLAGS) $(INTERNAL_CFLAGS)
MANIFEST_FLAGS = /MANIFEST:EMBED /MANIFESTINPUT:$(MANIFEST)
ALL_LDFLAGS = /link $(LDFLAGS) $(MANIFEST_FLAGS) /SUBSYSTEM:CONSOLE /RELEASE
MANIFEST_FLAGS = /manifest:embed /manifestinput:$(MANIFEST)
ALL_LDFLAGS = /link $(LDFLAGS) $(MANIFEST_FLAGS) /subsystem:console /release
LIBS =
PERL = perl
PERLFLAGS = -I$(srcdir)/perllib -I$(srcdir)
!IF [$(PERL) $(PERLFLAGS) -e "exit 0;"] == 0
RUNPERL = $(PERL) $(PERLFLAGS)
!ELSE
RUNPERL = :
!ENDIF
MAKENSIS = makensis
RM_F = -del /f
LN_S = copy
RM_F = -del /s /f /q
LN_S = copy /y
EMPTY = copy /y nul:
SIDE = @rem Created by side effect
# Binary suffixes
O = obj
@ -60,10 +70,12 @@ X = .exe
.SUFFIXES: $(X) .$(A) .obj .c .i .s .1 .man
.c.obj:
$(CC) /c $(ALL_CFLAGS) /Fo$@ $<
$(CC) /c $(ALL_CFLAGS) /Fo:$@ $<
MANIFEST = win/manifest.xml
DIRS =
ZLIB = $(ZLIBOBJ)
#-- Begin File Lists --#
@ -74,81 +86,6 @@ NDISASM = disasm\ndisasm.obj
PROGOBJ = $(NASM) $(NDISASM)
PROGS = nasm$(X) ndisasm$(X)
# Files dependent on extracted warnings
WARNOBJ = asm\warnings.obj
WARNFILES = asm\warnings_c.h include\warnings.h doc\warnings.src
OUTPUTOBJ = \
output\outform.obj output\outlib.obj \
output\nulldbg.obj output\nullout.obj \
output\outbin.obj output\outaout.obj output\outcoff.obj \
output\outelf.obj \
output\outobj.obj output\outas86.obj \
output\outdbg.obj output\outieee.obj output\outmacho.obj \
output\codeview.obj
# The source files for these objects are scanned for warnings
LIBOBJ_W = \
nasmlib\readnum.obj \
\
asm\error.obj \
asm\floats.obj \
asm\directiv.obj \
asm\pragma.obj \
asm\assemble.obj asm\labels.obj asm\parser.obj \
asm\preproc.obj asm\quote.obj \
asm\listing.obj asm\eval.obj asm\exprlib.obj asm\exprdump.obj \
asm\stdscan.obj \
asm\strfunc.obj \
asm\segalloc.obj \
asm\rdstrnum.obj \
asm\srcfile.obj
# The source files for these objects are NOT scanned for warnings;
# normally this will include all generated files.
# It is entirely possible that it may be necessary to move some of these
# files to LIBOBJ_W, notably $(OUTPUTOBJ)
LIBOBJ_NW = \
stdlib\snprintf.obj stdlib\vsnprintf.obj stdlib\strlcpy.obj \
stdlib\strnlen.obj stdlib\strrchrnul.obj \
\
asm\directbl.obj \
asm\pptok.obj \
asm\tokhash.obj \
asm\uncompress.obj \
\
macros\macros.obj \
\
nasmlib\ver.obj \
nasmlib\alloc.obj nasmlib\asprintf.obj nasmlib\errfile.obj \
nasmlib\crc32.obj nasmlib\crc64.obj nasmlib\md5c.obj \
nasmlib\string.obj nasmlib\nctype.obj \
nasmlib\file.obj nasmlib\mmap.obj nasmlib\ilog2.obj \
nasmlib\realpath.obj nasmlib\path.obj \
nasmlib\filename.obj nasmlib\rlimit.obj \
nasmlib\numstr.obj \
nasmlib\zerobuf.obj nasmlib\bsi.obj \
nasmlib\rbtree.obj nasmlib\hashtbl.obj \
nasmlib\raa.obj nasmlib\saa.obj \
nasmlib\strlist.obj \
nasmlib\perfhash.obj nasmlib\badenum.obj \
\
common\common.obj \
\
x86\insnsa.obj x86\insnsb.obj x86\insnsn.obj \
x86\regs.obj x86\regvals.obj x86\regflags.obj \
x86\iflag.obj \
\
$(OUTPUTOBJ) \
\
$(WARNOBJ)
# Objects which are only used for the disassembler
LIBOBJ_DIS = \
disasm\disasm.obj disasm\sync.obj disasm\prefix.obj \
\
x86\insnsd.obj x86\regdis.obj
# Objects for the local copy of zlib. The variable ZLIB is set to
# $(ZLIBOBJ) if the internal version of zlib should be used.
ZLIBOBJ = \
@ -160,35 +97,115 @@ ZLIBOBJ = \
zlib\inftrees.obj \
zlib\zutil.obj
LIBOBJ = $(LIBOBJ_W) $(LIBOBJ_NW) $(ZLIB)
ALLOBJ_W = $(NASM) $(LIBOBJ_W)
# Common library objects
LIBOBJ_COM = \
stdlib\snprintf.obj stdlib\vsnprintf.obj stdlib\strlcpy.obj \
stdlib\strnlen.obj \
\
nasmlib\ver.obj \
nasmlib\alloc.obj nasmlib\asprintf.obj \
nasmlib\crc32b.obj nasmlib\crc64.obj nasmlib\md5c.obj \
nasmlib\string.obj nasmlib\nctype.obj \
nasmlib\file.obj nasmlib\fileio.obj nasmlib\mmap.obj \
nasmlib\realpath.obj nasmlib\path.obj \
nasmlib\ilog2.obj nasmlib\numstr.obj \
nasmlib\rlimit.obj \
nasmlib\zerobuf.obj nasmlib\bsi.obj \
nasmlib\rbtree.obj nasmlib\hashtbl.obj \
nasmlib\raa.obj nasmlib\saa.obj \
nasmlib\strlist.obj \
nasmlib\perfhash.obj nasmlib\badenum.obj \
nasmlib\readnum.obj \
\
common\common.obj common\errstubs.obj common\files.obj \
\
x86\insnsa.obj x86\insnsb.obj x86\insnsn.obj \
x86\regs.obj x86\regvals.obj x86\regflags.obj \
x86\iflag.obj \
\
$(ZLIB)
# Files dependent on warnings.dat
WARNOBJ = asm\warnings.obj
WARNFILES = asm\warnings_c.h include\warnings.h doc\warnings.src
OUTPUTOBJ = \
output\outform.obj output\outlib.obj \
output\nulldbg.obj output\nullout.obj \
output\outbin.obj output\outaout.obj output\outcoff.obj \
output\outelf.obj \
output\outobj.obj output\outas86.obj \
output\outdbg.obj output\outieee.obj output\outmacho.obj \
output\codeview.obj
# Assembler-only library objects
LIBOBJ_ASM = \
asm\error.obj \
asm\floats.obj \
asm\directiv.obj \
asm\pragma.obj \
asm\assemble.obj asm\labels.obj asm\parser.obj \
asm\preproc.obj asm\quote.obj \
asm\listing.obj asm\eval.obj asm\exprlib.obj asm\exprdump.obj \
asm\stdscan.obj \
asm\getbool.obj \
asm\strfunc.obj \
asm\segalloc.obj \
asm\rdstrnum.obj \
asm\srcfile.obj \
asm\directbl.obj \
asm\pptok.obj \
asm\tokhash.obj \
asm\uncompress.obj \
\
macros\macros.obj \
\
$(WARNOBJ) \
$(OUTPUTOBJ)
# Objects which are only used for the disassembler
LIBOBJ_DIS = \
disasm\disasm.obj disasm\sync.obj disasm\prefix.obj \
disasm\diserror.obj \
\
x86\insnsd.obj x86\regdis.obj
LIBOBJ = $(LIBOBJ_COM) $(LIBOBJ_ASM) $(LIBOBJ_DIS)
ALLOBJ = $(PROGOBJ) $(LIBOBJ)
SUBDIRS = stdlib nasmlib include config output asm disasm x86 \
common zlib macros
XSUBDIRS = test doc nsis win
common zlib macros misc
XSUBDIRS = nsis win test doc editors
DEPDIRS = . $(SUBDIRS)
EDITORS = editors\nasmtok.el editors\nasmtok.json
#-- End File Lists --#
NASMLIB = libnasm.$(A)
NDISLIB = libndis.$(A)
ASMLIB = libasm.$(A)
DISLIB = libdis.$(A)
all: nasm$(X) ndisasm$(X)
nasm$(X): $(NASM) $(MANIFEST) $(NASMLIB)
$(CC) /Fe$@ $(NASM) $(ALL_LDFLAGS) $(NASMLIB) $(LIBS)
nasm$(X): $(NASM) $(MANIFEST) $(ASMLIB) $(NASMLIB)
$(CC) /Fe:$@ $(ALL_CFLAGS) $(NASM) $(ASMLIB) $(NASMLIB) $(LIBS) \
$(ALL_LDFLAGS)
ndisasm$(X): $(NDISASM) $(MANIFEST) $(NDISLIB) $(NASMLIB)
$(CC) /Fe$@ $(NDISASM) $(ALL_LDFLAGS) $(NDISLIB) $(NASMLIB) $(LIBS)
ndisasm$(X): $(NDISASM) $(MANIFEST) $(DISLIB) $(NASMLIB)
$(CC) /Fe:$@ $(ALL_CFLAGS) $(NDISASM) $(DISLIB) $(NASMLIB) $(LIBS) \
$(ALL_LDFLAGS)
$(NASMLIB): $(LIBOBJ)
$(AR) $(ARFLAGS) /OUT:$@ $**
$(NASMLIB): $(LIBOBJ_COM)
$(AR) $(ARFLAGS) /out:$@ $**
$(NDISLIB): $(LIBOBJ_DIS)
$(AR) $(ARFLAGS) /OUT:$@ $**
$(ASMLIB): $(LIBOBJ_ASM)
$(AR) $(ARFLAGS) /out:$@ $**
$(DISLIB): $(LIBOBJ_DIS)
$(AR) $(ARFLAGS) /out:$@ $**
# These are specific to certain Makefile syntaxes...
WARNTIMES = $(patsubst %,%.time,$(WARNFILES))
WARNSRCS = $(patsubst %.obj,%.c,$(LIBOBJ_NW))
WARNSRCS = $(LIBOBJ_NW:.c=.obj)
#-- Begin Generated File Rules --#
# Edit in Makefile.in, not here!
@ -206,43 +223,36 @@ PERLREQ_CLEANABLE = \
macros\macros.c \
asm\pptok.ph asm\directbl.c asm\directiv.h \
$(WARNFILES) \
misc\nasmtok.el \
version.h version.mac version.mak nsis\version.nsh
# Special hack to keep config\unconfig.h from getting deleted
# by "make spotless"...
PERLREQ = config\unconfig.h $(PERLREQ_CLEANABLE)
PERLREQ = $(PERLREQ_CLEANABLE)
INSDEP = x86\insns.xda x86\insns.pl x86\insns-iflags.ph x86\iflags.ph
INSDEP = x86\insns.xda x86\insns.pl x86\insns-iflags.ph x86\iflags.ph x86\insns-cc.ph
x86\insns.xda: x86\insns.dat x86\preinsns.pl
$(RUNPERL) '$(srcdir)'\x86\preinsns.pl $< $@
config\unconfig.h: config\config.h.in autoconf\unconfig.pl
$(RUNPERL) '$(srcdir)'\autoconf\unconfig.pl \
'$(srcdir)' config\config.h.in config\unconfig.h
x86\insns.xda: x86\insns.dat x86\preinsns.pl $(DIRS)
$(RUNPERL) $(srcdir)\x86\preinsns.pl $(srcdir)\x86\insns.dat $@
x86\iflag.c: $(INSDEP)
$(RUNPERL) $(srcdir)\x86\insns.pl -fc \
$(srcdir)\x86\insns.xda x86\iflag.c
x86\insns.xda x86\iflag.c
x86\iflaggen.h: $(INSDEP)
$(RUNPERL) $(srcdir)\x86\insns.pl -fh \
$(srcdir)\x86\insns.xda x86\iflaggen.h
x86\insns.xda x86\iflaggen.h
x86\insnsb.c: $(INSDEP)
$(RUNPERL) $(srcdir)\x86\insns.pl -b \
$(srcdir)\x86\insns.xda x86\insnsb.c
x86\insns.xda x86\insnsb.c
x86\insnsa.c: $(INSDEP)
$(RUNPERL) $(srcdir)\x86\insns.pl -a \
$(srcdir)\x86\insns.xda x86\insnsa.c
x86\insns.xda x86\insnsa.c
x86\insnsd.c: $(INSDEP)
$(RUNPERL) $(srcdir)\x86\insns.pl -d \
$(srcdir)\x86\insns.xda x86\insnsd.c
x86\insns.xda x86\insnsd.c
x86\insnsi.h: $(INSDEP)
$(RUNPERL) $(srcdir)\x86\insns.pl -i \
$(srcdir)\x86\insns.xda x86\insnsi.h
x86\insns.xda x86\insnsi.h
x86\insnsn.c: $(INSDEP)
$(RUNPERL) $(srcdir)\x86\insns.pl -n \
$(srcdir)\x86\insns.xda x86\insnsn.c
x86\insns.xda x86\insnsn.c
# These files contains all the standard macros that are derived from
# the version number.
@ -254,7 +264,7 @@ version.sed: version version.pl
$(RUNPERL) $(srcdir)\version.pl sed < $(srcdir)\version > version.sed
version.mak: version version.pl
$(RUNPERL) $(srcdir)\version.pl make < $(srcdir)\version > version.mak
nsis\version.nsh: version version.pl
nsis\version.nsh: version version.pl $(DIRS)
$(RUNPERL) $(srcdir)\version.pl nsis < $(srcdir)\version > nsis\version.nsh
# This source file is generated from the standard macros file
@ -286,43 +296,6 @@ x86\regs.h: x86\regs.dat x86\regs.pl
$(RUNPERL) $(srcdir)\x86\regs.pl h \
$(srcdir)\x86\regs.dat > x86\regs.h
# Extract warnings from source code. This is done automatically if any
# C files have changed; the script is fast enough that that is
# reasonable, but doesn't update the time stamp if the files aren't
# changed, to avoid rebuilding everything every time. Track the actual
# dependency by the empty file asm\warnings.time.
.PHONY: warnings
warnings: dirs
$(RM_F) $(WARNFILES) $(WARNTIMES) asm\warnings.time
$(MAKE) asm\warnings.time
asm\warnings.time: $(WARNSRCS) asm\warnings.pl
$(EMPTY) asm\warnings.time
$(MAKE) $(WARNTIMES)
asm\warnings_c.h.time: asm\warnings.pl asm\warnings.time
$(RUNPERL) $(srcdir)\asm\warnings.pl c asm\warnings_c.h \
'$(srcdir)' $(WARNSRCS)
$(EMPTY) asm\warnings_c.h.time
asm\warnings_c.h: asm\warnings_c.h.time
@: Side effect
include\warnings.h.time: asm\warnings.pl asm\warnings.time
$(RUNPERL) $(srcdir)\asm\warnings.pl h include\warnings.h \
'$(srcdir)' $(WARNSRCS)
$(EMPTY) include\warnings.h.time
include\warnings.h: include\warnings.h.time
@: Side effect
doc\warnings.src.time: asm\warnings.pl asm\warnings.time
$(RUNPERL) $(srcdir)\asm\warnings.pl doc doc\warnings.src \
'$(srcdir)' $(WARNSRCS)
$(EMPTY) doc\warnings.src.time
doc\warnings.src : doc\warnings.src.time
@: Side effect
# Assembler token hash
asm\tokhash.c: x86\insns.xda x86\insnsn.c asm\tokens.dat asm\tokhash.pl \
@ -348,6 +321,9 @@ asm\pptok.c: asm\pptok.dat asm\pptok.pl perllib\phash.ph
asm\pptok.ph: asm\pptok.dat asm\pptok.pl perllib\phash.ph
$(RUNPERL) $(srcdir)\asm\pptok.pl ph \
$(srcdir)\asm\pptok.dat asm\pptok.ph
doc\pptok.src: asm\pptok.dat asm\pptok.pl perllib\phash.ph
$(RUNPERL) $(srcdir)\asm\pptok.pl src \
$(srcdir)\asm\pptok.dat doc\pptok.src
# Directives hash
asm\directiv.h: asm\directiv.dat nasmlib\perfhash.pl perllib\phash.ph
@ -357,10 +333,39 @@ asm\directbl.c: asm\directiv.dat nasmlib\perfhash.pl perllib\phash.ph
$(RUNPERL) $(srcdir)\nasmlib\perfhash.pl c \
$(srcdir)\asm\directiv.dat asm\directbl.c
# Emacs token files
misc\nasmtok.el: misc\emacstbl.pl asm\tokhash.c asm\pptok.c \
asm\directiv.dat version
$(RUNPERL) $< $@ "$(srcdir)" "$(objdir)"
# Editor token files
editors\nasmtok.el: editors\nasmtok.pl asm\tokhash.c asm\pptok.c \
asm\directiv.dat macros\macros.c editors\builtin.mac \
version.mak
$(RUNPERL) $(srcdir)\editors\nasmtok.pl -el $@ $(srcdir) $(objdir)
editors\nasmtok.json: editors\nasmtok.pl asm\tokhash.c asm\pptok.c \
asm\directiv.dat macros\macros.c editors\builtin.mac \
version.mak
$(RUNPERL) $(srcdir)\editors\nasmtok.pl -json $@ $(srcdir) $(objdir)
editors: $(EDITORS) $(PHONY)
asm\warnings_c.h: asm\warnings.pl asm\warnings.dat
$(RUNPERL) $(srcdir)\asm\warnings.pl c asm\warnings_c.h \
$(srcdir)\asm\warnings.dat
include\warnings.h: asm\warnings.pl asm\warnings.dat
$(RUNPERL) $(srcdir)\asm\warnings.pl h include\warnings.h \
$(srcdir)\asm\warnings.dat
doc\warnings.src: asm\warnings.pl asm\warnings.dat
$(RUNPERL) $(srcdir)\asm\warnings.pl doc doc\warnings.src \
$(srcdir)\asm\warnings.dat
doc\perlbreq.src: tools\genperlbreq.pl $(DIRS)
$(RUNPERL) tools\genperlbreq.pl $(srcdir) doc\perlbreq.src
$(PERLREQ): $(DIRS)
perlreq: $(PERLREQ) $(PHONY)
warnings: $(WARNFILES) $(PHONY)
#-- End Generated File Rules --#
@ -369,14 +374,15 @@ perlreq: $(PERLREQ)
#-- Begin NSIS Rules --#
# Edit in Makefile.in, not here!
nsis\arch.nsh: nsis\getpearch.pl nasm$(X)
nsis\arch.nsh: nsis\getpearch.pl nasm$(X) $(DIRS)
$(PERL) $(srcdir)\nsis\getpearch.pl nasm$(X) > nsis\arch.nsh
# Should only be done after "make everything".
# The use of redirection here keeps makensis from moving the cwd to the
# source directory.
nsis: nsis\nasm.nsi nsis\arch.nsh nsis\version.nsh
$(MAKENSIS) -Dsrcdir="$(srcdir)" -Dobjdir="$(objdir)" - < nsis\nasm.nsi
$(MAKENSIS) -Dsrcdir=$(srcdir) -Dobjdir=$(objdir) - \
< $(srcdir)\nsis\nasm.nsi
#-- End NSIS Rules --#
@ -415,14 +421,31 @@ cleaner: clean
spotless: distclean cleaner
-del /f doc\Makefile
-del /f doc\msvc.mak
-del doc\*~
-del doc\*.bak
strip:
# Abuse doc/Makefile.in to build nasmdoc.pdf only
docs:
cd doc && $(MAKE) /f Makefile.in srcdir=. top_srcdir=.. \
# Abuse doc/Makefile.in to build nasmdoc.pdf only.
#
# doc/Makefile.in expects doc\warnings.src, doc\perlbreq.src and
# doc\pptok.src to already have been generated by the top-level build
# (as the Unix "doc" target does); build them here first.
#
# doc/Makefile.in is written for GNU make and relies on a few
# constructs nmake cannot parse at all ($^, $< outside an inference
# rule, and the GNU-only "-include *.dep" directive); tools/mkmsvcdocmak.pl
# rewrites those to their nmake-safe equivalents in a generated copy,
# doc\msvc.mak, which is what actually gets fed to nmake below.
#
# Building the documentation requires Ghostscript and the Roboto /
# Roboto Mono fonts to be installed and discoverable; see
# doc/source.src ("Optional Build Tools") for details.
docs: doc\warnings.src doc\perlbreq.src doc\pptok.src
$(RUNPERL) $(srcdir)\tools\mkmsvcdocmak.pl \
$(srcdir)\doc\Makefile.in doc\msvc.mak
cd doc && $(MAKE) /f msvc.mak srcdir=. top_srcdir=.. \
PERL=$(PERL) PDFOPT= nasmdoc.pdf
everything: all docs nsis

View file

@ -6,202 +6,235 @@
top_srcdir = .
srcdir = .
VPATH = $(srcdir)\asm;$(srcdir)\x86;asm;x86;$(srcdir)\macros;macros;$(srcdir)\output;$(srcdir)\lib;$(srcdir)\common;$(srcdir)\stdlib;$(srcdir)\nasmlib;$(srcdir)\disasm
VPATH = $(srcdir)/asm;$(srcdir)/x86;$(srcdir)/macros;$(srcdir)/output;
VPATH +=$(srcdir)/common;$(srcdir)/stdlib;$(srcdir)/nasmlib;
VPATH +=$(srcdir)/disasm;$(srcdir)/zlib;asm;x86;macros
prefix = C:\Program Files\NASM
exec_prefix = $(prefix)
bindir = $(prefix)\bin
mandir = $(prefix)\man
bindir = $(prefix)/bin
mandir = $(prefix)/man
CC = *wcl386
CC = *wcc386
DEBUG =
CFLAGS = -zq -6 -ox -wx -wcd=124 -ze -fpi $(DEBUG)
BUILD_CFLAGS = $(CFLAGS) $(%TARGET_CFLAGS)
INTERNAL_CFLAGS = -I$(srcdir) -I. -I$(srcdir)\include -I$(srcdir)\x86 -Ix86 -I$(srcdir)\asm -Iasm -I$(srcdir)\disasm -I$(srcdir)\output
BUILD_CFLAGS = $(CFLAGS) $(%TARGET_CFLAGS)
INTERNAL_CFLAGS = -I. -Iasm -Ix86 -Iinclude -I"$(srcdir)" -I"$(srcdir)/include" &
-I"$(srcdir)/asm" -I"$(srcdir)/x86" -I"$(srcdir)/disasm" -I"$(srcdir)/output" &
-I"$(srcdir)/zlib"
ALL_CFLAGS = $(BUILD_CFLAGS) $(INTERNAL_CFLAGS)
LD = *wlink
LD = *wlink
LDEBUG =
LDFLAGS = op q $(%TARGET_LFLAGS) $(LDEBUG)
LIBS =
STRIP = wstrip
PERL = perl
PERLFLAGS = -I$(srcdir)\perllib -I$(srcdir)
RUNPERL = $(PERL) $(PERLFLAGS)
PERL = perl
PERLFLAGS = -I$(srcdir)/perllib -I$(srcdir)
RUNPERL = $(PERL) $(PERLFLAGS)
EMPTY = $(RUNPERL) -e ""
!ifdef __LOADDLL__
!loaddll wcc wccd.dll
!loaddll wcc386 wccd386.dll
!loaddll wlib wlibd.dll
!loaddll wlink wlinkd.dll
!endif
MAKENSIS = makensis
.BEFORE
@set INCLUDE=
@set COPYCMD=/y
@for %d in ($(SUBDIRS) $(XSUBDIRS)) do @if not exist %d mkdir %d
# rm is handled internally by WMAKE, so it does work even on non-Unix systems
RM_F = -rm -f
LN_S = copy
EMPTY = %create
SIDE = %null Created by side effect
PHONY = .SYMBOLIC
MAKENSIS = makensis
# Binary suffixes
O = obj
X = .exe
O = obj
A = lib
X = .exe
# WMAKE errors out if a suffix is declared more than once, including
# its own built-in declarations. Thus, we need to explicitly clear the list
# first. Also, WMAKE only allows implicit rules that point "to the left"
# in this list!
.SUFFIXES:
.SUFFIXES: .man .1 .obj .i .c
.SUFFIXES: .man .1 .obj .i .c .lib .exe
# Needed to find C files anywhere but in the current directory
.c : $(VPATH)
.c.obj:
@set INCLUDE=
$(CC) -c $(ALL_CFLAGS) -fo=$^@ $[@
.c.obj: .AUTODEPEND
$(CC) $(ALL_CFLAGS) -fo=$^@ $[@
MANIFEST =
MANIFEST =
ZLIB = $(ZLIBOBJ)
ZLIB = $(ZLIBOBJ)
#-- Begin File Lists --#
# Edit in Makefile.in, not here!
NASM = asm\nasm.obj
NDISASM = disasm\ndisasm.obj
NASM = asm/nasm.obj
NDISASM = disasm/ndisasm.obj
PROGOBJ = $(NASM) $(NDISASM)
PROGS = nasm$(X) ndisasm$(X)
# Files dependent on extracted warnings
WARNOBJ = asm\warnings.obj
WARNFILES = asm\warnings_c.h include\warnings.h doc\warnings.src
OUTPUTOBJ = &
output\outform.obj output\outlib.obj &
output\nulldbg.obj output\nullout.obj &
output\outbin.obj output\outaout.obj output\outcoff.obj &
output\outelf.obj &
output\outobj.obj output\outas86.obj &
output\outdbg.obj output\outieee.obj output\outmacho.obj &
output\codeview.obj
# The source files for these objects are scanned for warnings
LIBOBJ_W = &
nasmlib\readnum.obj &
&
asm\error.obj &
asm\floats.obj &
asm\directiv.obj &
asm\pragma.obj &
asm\assemble.obj asm\labels.obj asm\parser.obj &
asm\preproc.obj asm\quote.obj &
asm\listing.obj asm\eval.obj asm\exprlib.obj asm\exprdump.obj &
asm\stdscan.obj &
asm\strfunc.obj &
asm\segalloc.obj &
asm\rdstrnum.obj &
asm\srcfile.obj
# The source files for these objects are NOT scanned for warnings;
# normally this will include all generated files.
# It is entirely possible that it may be necessary to move some of these
# files to LIBOBJ_W, notably $(OUTPUTOBJ)
LIBOBJ_NW = &
stdlib\snprintf.obj stdlib\vsnprintf.obj stdlib\strlcpy.obj &
stdlib\strnlen.obj stdlib\strrchrnul.obj &
&
asm\directbl.obj &
asm\pptok.obj &
asm\tokhash.obj &
asm\uncompress.obj &
&
macros\macros.obj &
&
nasmlib\ver.obj &
nasmlib\alloc.obj nasmlib\asprintf.obj nasmlib\errfile.obj &
nasmlib\crc32.obj nasmlib\crc64.obj nasmlib\md5c.obj &
nasmlib\string.obj nasmlib\nctype.obj &
nasmlib\file.obj nasmlib\mmap.obj nasmlib\ilog2.obj &
nasmlib\realpath.obj nasmlib\path.obj &
nasmlib\filename.obj nasmlib\rlimit.obj &
nasmlib\numstr.obj &
nasmlib\zerobuf.obj nasmlib\bsi.obj &
nasmlib\rbtree.obj nasmlib\hashtbl.obj &
nasmlib\raa.obj nasmlib\saa.obj &
nasmlib\strlist.obj &
nasmlib\perfhash.obj nasmlib\badenum.obj &
&
common\common.obj &
&
x86\insnsa.obj x86\insnsb.obj x86\insnsn.obj &
x86\regs.obj x86\regvals.obj x86\regflags.obj &
x86\iflag.obj &
&
$(OUTPUTOBJ) &
&
$(WARNOBJ)
# Objects which are only used for the disassembler
LIBOBJ_DIS = &
disasm\disasm.obj disasm\sync.obj disasm\prefix.obj &
&
x86\insnsd.obj x86\regdis.obj
# Objects for the local copy of zlib. The variable ZLIB is set to
# $(ZLIBOBJ) if the internal version of zlib should be used.
ZLIBOBJ = &
zlib\adler32.obj &
zlib\crc32.obj &
zlib\infback.obj &
zlib\inffast.obj &
zlib\inflate.obj &
zlib\inftrees.obj &
zlib\zutil.obj
zlib/adler32.obj &
zlib/crc32.obj &
zlib/infback.obj &
zlib/inffast.obj &
zlib/inflate.obj &
zlib/inftrees.obj &
zlib/zutil.obj
LIBOBJ = $(LIBOBJ_W) $(LIBOBJ_NW) $(ZLIB)
ALLOBJ_W = $(NASM) $(LIBOBJ_W)
# Common library objects
LIBOBJ_COM = &
stdlib/snprintf.obj stdlib/vsnprintf.obj stdlib/strlcpy.obj &
stdlib/strnlen.obj &
&
nasmlib/ver.obj &
nasmlib/alloc.obj nasmlib/asprintf.obj &
nasmlib/crc32b.obj nasmlib/crc64.obj nasmlib/md5c.obj &
nasmlib/string.obj nasmlib/nctype.obj &
nasmlib/file.obj nasmlib/fileio.obj nasmlib/mmap.obj &
nasmlib/realpath.obj nasmlib/path.obj &
nasmlib/ilog2.obj nasmlib/numstr.obj &
nasmlib/rlimit.obj &
nasmlib/zerobuf.obj nasmlib/bsi.obj &
nasmlib/rbtree.obj nasmlib/hashtbl.obj &
nasmlib/raa.obj nasmlib/saa.obj &
nasmlib/strlist.obj &
nasmlib/perfhash.obj nasmlib/badenum.obj &
nasmlib/readnum.obj &
&
common/common.obj common/errstubs.obj common/files.obj &
&
x86/insnsa.obj x86/insnsb.obj x86/insnsn.obj &
x86/regs.obj x86/regvals.obj x86/regflags.obj &
x86/iflag.obj &
&
$(ZLIB)
# Files dependent on warnings.dat
WARNOBJ = asm/warnings.obj
WARNFILES = asm/warnings_c.h include/warnings.h doc/warnings.src
OUTPUTOBJ = &
output/outform.obj output/outlib.obj &
output/nulldbg.obj output/nullout.obj &
output/outbin.obj output/outaout.obj output/outcoff.obj &
output/outelf.obj &
output/outobj.obj output/outas86.obj &
output/outdbg.obj output/outieee.obj output/outmacho.obj &
output/codeview.obj
# Assembler-only library objects
LIBOBJ_ASM = &
asm/error.obj &
asm/floats.obj &
asm/directiv.obj &
asm/pragma.obj &
asm/assemble.obj asm/labels.obj asm/parser.obj &
asm/preproc.obj asm/quote.obj &
asm/listing.obj asm/eval.obj asm/exprlib.obj asm/exprdump.obj &
asm/stdscan.obj &
asm/getbool.obj &
asm/strfunc.obj &
asm/segalloc.obj &
asm/rdstrnum.obj &
asm/srcfile.obj &
asm/directbl.obj &
asm/pptok.obj &
asm/tokhash.obj &
asm/uncompress.obj &
&
macros/macros.obj &
&
$(WARNOBJ) &
$(OUTPUTOBJ)
# Objects which are only used for the disassembler
LIBOBJ_DIS = &
disasm/disasm.obj disasm/sync.obj disasm/prefix.obj &
disasm/diserror.obj &
&
x86/insnsd.obj x86/regdis.obj
LIBOBJ = $(LIBOBJ_COM) $(LIBOBJ_ASM) $(LIBOBJ_DIS)
ALLOBJ = $(PROGOBJ) $(LIBOBJ)
SUBDIRS = stdlib nasmlib include config output asm disasm x86 &
common zlib macros
XSUBDIRS = test doc nsis win
common zlib macros misc
XSUBDIRS = nsis win test doc editors
DEPDIRS = . $(SUBDIRS)
EDITORS = editors/nasmtok.el editors/nasmtok.json
#-- End File Lists --#
what: .SYMBOLIC
what: $(PHONY)
@echo Please build "dos", "win32", "os2" or "linux386"
dos: .SYMBOLIC
@set TARGET_CFLAGS=-bt=DOS -I"$(%WATCOM)\h"
dos: $(PHONY)
@set TARGET_CFLAGS=-bt=DOS -I"$(%WATCOM)/h"
@set TARGET_LFLAGS=sys causeway
@%make all
win32: .SYMBOLIC
@set TARGET_CFLAGS=-bt=NT -I"$(%WATCOM)\h" -I"$(%WATCOM)\h\nt"
win32: $(PHONY)
@set TARGET_CFLAGS=-bt=NT -I"$(%WATCOM)/h" -I"$(%WATCOM)/h/nt"
@set TARGET_LFLAGS=sys nt
@%make all
os2: .SYMBOLIC
@set TARGET_CFLAGS=-bt=OS2 -I"$(%WATCOM)\h" -I"$(%WATCOM)\h\os2"
os2: $(PHONY)
@set TARGET_CFLAGS=-bt=OS2 -I"$(%WATCOM)/h" -I"$(%WATCOM)/h/os2"
@set TARGET_LFLAGS=sys os2v2
@%make all
linux386: .SYMBOLIC
@set TARGET_CFLAGS=-bt=LINUX -I"$(%WATCOM)\lh"
linux386: $(PHONY)
@set TARGET_CFLAGS=-bt=LINUX -I"$(%WATCOM)/lh"
@set TARGET_LFLAGS=sys linux
@%make all
all: perlreq nasm$(X) ndisasm$(X) .SYMBOLIC
all: perlreq nasm$(X) ndisasm$(X) $(PHONY)
# cd rdoff && $(MAKE) all
NASMLIB = nasm.lib
NDISLIB = ndisasm.lib
ASMLIB = asm.lib
DISLIB = dis.lib
nasm$(X): $(NASM) $(NASMLIB)
$(LD) $(LDFLAGS) name nasm$(X) libr {$(NASMLIB) $(LIBS)} file {$(NASM)}
nasm$(X): $(NASM) $(ASMLIB) $(NASMLIB)
$(LD) $(LDFLAGS) name nasm$(X) libr {$(ASMLIB) $(NASMLIB) $(LIBS)} file {$(NASM)}
ndisasm$(X): $(NDISASM) $(NDISLIB) $(NASMLIB)
$(LD) $(LDFLAGS) name ndisasm$(X) libr {$(NDISLIB) $(NASMLIB) $(LIBS)} file {$(NDISASM)}
ndisasm$(X): $(NDISASM) $(DISLIB) $(NASMLIB)
$(LD) $(LDFLAGS) name ndisasm$(X) libr {$(DISLIB) $(NASMLIB) $(LIBS)} file {$(NDISASM)}
nasm.lib: $(LIBOBJ)
wlib -q -b -n $@ $(LIBOBJ)
<<<<<<< HEAD
nasm.lib: $(LIBOBJ_COM)
wlib -q -b -n $@ $(LIBOBJ_COM)
ndisasm.lib: $(LIBOBJ_DIS)
asm.lib: $(LIBOBJ_ASM)
wlib -q -b -n $@ $(LIBOBJ_ASM)
dis.lib: $(LIBOBJ_DIS)
wlib -q -b -n $@ $(LIBOBJ_DIS)
# These are specific to certain Makefile syntaxes (what are they
# actually supposed to look like for wmake?)
WARNTIMES = $(WARNFILES:=.time)
WARNSRCS = $(LIBOBJ_NW:.obj=.c)
=======
nasm.lib: $(LIBOBJ)
*wlib -q -b -n $@ $<
ndisasm.lib: $(LIBOBJ_DIS)
*wlib -q -b -n $@ $<
>>>>>>> 61e7e23c94c8 (open-watcom: fix Open Watcom build make file)
#-- Begin Generated File Rules --#
# Edit in Makefile.in, not here!
@ -212,221 +245,206 @@ WARNSRCS = $(LIBOBJ_NW:.obj=.c)
# Perl-generated source files
PERLREQ_CLEANABLE = &
x86\insnsb.c x86\insnsa.c x86\insnsd.c x86\insnsi.h x86\insnsn.c &
x86\regs.c x86\regs.h x86\regflags.c x86\regdis.c x86\regdis.h &
x86\regvals.c asm\tokhash.c asm\tokens.h asm\pptok.h asm\pptok.c &
x86\iflag.c x86\iflaggen.h &
macros\macros.c &
asm\pptok.ph asm\directbl.c asm\directiv.h &
x86/insnsb.c x86/insnsa.c x86/insnsd.c x86/insnsi.h x86/insnsn.c &
x86/regs.c x86/regs.h x86/regflags.c x86/regdis.c x86/regdis.h &
x86/regvals.c asm/tokhash.c asm/tokens.h asm/pptok.h asm/pptok.c &
x86/iflag.c x86/iflaggen.h &
macros/macros.c &
asm/pptok.ph asm/directbl.c asm/directiv.h &
$(WARNFILES) &
misc\nasmtok.el &
version.h version.mac version.mak nsis\version.nsh
version.h version.mac version.mak nsis/version.nsh
# Special hack to keep config\unconfig.h from getting deleted
# by "make spotless"...
PERLREQ = config\unconfig.h $(PERLREQ_CLEANABLE)
PERLREQ = $(PERLREQ_CLEANABLE)
INSDEP = x86\insns.xda x86\insns.pl x86\insns-iflags.ph x86\iflags.ph
INSDEP = x86/insns.xda x86/insns.pl x86/insns-iflags.ph x86/iflags.ph x86/insns-cc.ph
x86\insns.xda: x86\insns.dat x86\preinsns.pl
$(RUNPERL) '$(srcdir)'\x86\preinsns.pl $< $@
x86/insns.xda: x86/insns.dat x86/preinsns.pl $(DIRS)
$(RUNPERL) $(srcdir)/x86/preinsns.pl $(srcdir)/x86/insns.dat $@
config\unconfig.h: config\config.h.in autoconf\unconfig.pl
$(RUNPERL) '$(srcdir)'\autoconf\unconfig.pl &
'$(srcdir)' config\config.h.in config\unconfig.h
x86\iflag.c: $(INSDEP)
$(RUNPERL) $(srcdir)\x86\insns.pl -fc &
$(srcdir)\x86\insns.xda x86\iflag.c
x86\iflaggen.h: $(INSDEP)
$(RUNPERL) $(srcdir)\x86\insns.pl -fh &
$(srcdir)\x86\insns.xda x86\iflaggen.h
x86\insnsb.c: $(INSDEP)
$(RUNPERL) $(srcdir)\x86\insns.pl -b &
$(srcdir)\x86\insns.xda x86\insnsb.c
x86\insnsa.c: $(INSDEP)
$(RUNPERL) $(srcdir)\x86\insns.pl -a &
$(srcdir)\x86\insns.xda x86\insnsa.c
x86\insnsd.c: $(INSDEP)
$(RUNPERL) $(srcdir)\x86\insns.pl -d &
$(srcdir)\x86\insns.xda x86\insnsd.c
x86\insnsi.h: $(INSDEP)
$(RUNPERL) $(srcdir)\x86\insns.pl -i &
$(srcdir)\x86\insns.xda x86\insnsi.h
x86\insnsn.c: $(INSDEP)
$(RUNPERL) $(srcdir)\x86\insns.pl -n &
$(srcdir)\x86\insns.xda x86\insnsn.c
x86/iflag.c: $(INSDEP)
$(RUNPERL) $(srcdir)/x86/insns.pl -fc &
x86/insns.xda x86/iflag.c
x86/iflaggen.h: $(INSDEP)
$(RUNPERL) $(srcdir)/x86/insns.pl -fh &
x86/insns.xda x86/iflaggen.h
x86/insnsb.c: $(INSDEP)
$(RUNPERL) $(srcdir)/x86/insns.pl -b &
x86/insns.xda x86/insnsb.c
x86/insnsa.c: $(INSDEP)
$(RUNPERL) $(srcdir)/x86/insns.pl -a &
x86/insns.xda x86/insnsa.c
x86/insnsd.c: $(INSDEP)
$(RUNPERL) $(srcdir)/x86/insns.pl -d &
x86/insns.xda x86/insnsd.c
x86/insnsi.h: $(INSDEP)
$(RUNPERL) $(srcdir)/x86/insns.pl -i &
x86/insns.xda x86/insnsi.h
x86/insnsn.c: $(INSDEP)
$(RUNPERL) $(srcdir)/x86/insns.pl -n &
x86/insns.xda x86/insnsn.c
# These files contains all the standard macros that are derived from
# the version number.
version.h: version version.pl
$(RUNPERL) $(srcdir)\version.pl h < $(srcdir)\version > version.h
$(RUNPERL) $(srcdir)/version.pl h < $(srcdir)/version > version.h
version.mac: version version.pl
$(RUNPERL) $(srcdir)\version.pl mac < $(srcdir)\version > version.mac
$(RUNPERL) $(srcdir)/version.pl mac < $(srcdir)/version > version.mac
version.sed: version version.pl
$(RUNPERL) $(srcdir)\version.pl sed < $(srcdir)\version > version.sed
$(RUNPERL) $(srcdir)/version.pl sed < $(srcdir)/version > version.sed
version.mak: version version.pl
$(RUNPERL) $(srcdir)\version.pl make < $(srcdir)\version > version.mak
nsis\version.nsh: version version.pl
$(RUNPERL) $(srcdir)\version.pl nsis < $(srcdir)\version > nsis\version.nsh
$(RUNPERL) $(srcdir)/version.pl make < $(srcdir)/version > version.mak
nsis/version.nsh: version version.pl $(DIRS)
$(RUNPERL) $(srcdir)/version.pl nsis < $(srcdir)/version > nsis/version.nsh
# This source file is generated from the standard macros file
# `standard.mac' by another Perl script. Again, it's part of the
# standard distribution.
macros\macros.c: macros\macros.pl asm\pptok.ph version.mac &
$(srcdir)\macros\*.mac $(srcdir)\output\*.mac
$(RUNPERL) $(srcdir)\macros\macros.pl version.mac &
$(srcdir)\macros\*.mac $(srcdir)\output\*.mac
macros/macros.c: macros/macros.pl asm/pptok.ph version.mac &
$(srcdir)/macros/*.mac $(srcdir)/output/*.mac
$(RUNPERL) $(srcdir)/macros/macros.pl version.mac &
$(srcdir)/macros/*.mac $(srcdir)/output/*.mac
# These source files are generated from regs.dat by yet another
# perl script.
x86\regs.c: x86\regs.dat x86\regs.pl
$(RUNPERL) $(srcdir)\x86\regs.pl c &
$(srcdir)\x86\regs.dat > x86\regs.c
x86\regflags.c: x86\regs.dat x86\regs.pl
$(RUNPERL) $(srcdir)\x86\regs.pl fc &
$(srcdir)\x86\regs.dat > x86\regflags.c
x86\regdis.c: x86\regs.dat x86\regs.pl
$(RUNPERL) $(srcdir)\x86\regs.pl dc &
$(srcdir)\x86\regs.dat > x86\regdis.c
x86\regdis.h: x86\regs.dat x86\regs.pl
$(RUNPERL) $(srcdir)\x86\regs.pl dh &
$(srcdir)\x86\regs.dat > x86\regdis.h
x86\regvals.c: x86\regs.dat x86\regs.pl
$(RUNPERL) $(srcdir)\x86\regs.pl vc &
$(srcdir)\x86\regs.dat > x86\regvals.c
x86\regs.h: x86\regs.dat x86\regs.pl
$(RUNPERL) $(srcdir)\x86\regs.pl h &
$(srcdir)\x86\regs.dat > x86\regs.h
x86/regs.c: x86/regs.dat x86/regs.pl
$(RUNPERL) $(srcdir)/x86/regs.pl c &
$(srcdir)/x86/regs.dat > x86/regs.c
x86/regflags.c: x86/regs.dat x86/regs.pl
$(RUNPERL) $(srcdir)/x86/regs.pl fc &
$(srcdir)/x86/regs.dat > x86/regflags.c
x86/regdis.c: x86/regs.dat x86/regs.pl
$(RUNPERL) $(srcdir)/x86/regs.pl dc &
$(srcdir)/x86/regs.dat > x86/regdis.c
x86/regdis.h: x86/regs.dat x86/regs.pl
$(RUNPERL) $(srcdir)/x86/regs.pl dh &
$(srcdir)/x86/regs.dat > x86/regdis.h
x86/regvals.c: x86/regs.dat x86/regs.pl
$(RUNPERL) $(srcdir)/x86/regs.pl vc &
$(srcdir)/x86/regs.dat > x86/regvals.c
x86/regs.h: x86/regs.dat x86/regs.pl
$(RUNPERL) $(srcdir)/x86/regs.pl h &
$(srcdir)/x86/regs.dat > x86/regs.h
# Extract warnings from source code. This is done automatically if any
# C files have changed; the script is fast enough that that is
# reasonable, but doesn't update the time stamp if the files aren't
# changed, to avoid rebuilding everything every time. Track the actual
# dependency by the empty file asm\warnings.time.
.PHONY: warnings
warnings: dirs
$(RM_F) $(WARNFILES) $(WARNTIMES) asm\warnings.time
$(MAKE) asm\warnings.time
asm\warnings.time: $(WARNSRCS) asm\warnings.pl
$(EMPTY) asm\warnings.time
$(MAKE) $(WARNTIMES)
asm\warnings_c.h.time: asm\warnings.pl asm\warnings.time
$(RUNPERL) $(srcdir)\asm\warnings.pl c asm\warnings_c.h &
'$(srcdir)' $(WARNSRCS)
$(EMPTY) asm\warnings_c.h.time
asm\warnings_c.h: asm\warnings_c.h.time
@: Side effect
include\warnings.h.time: asm\warnings.pl asm\warnings.time
$(RUNPERL) $(srcdir)\asm\warnings.pl h include\warnings.h &
'$(srcdir)' $(WARNSRCS)
$(EMPTY) include\warnings.h.time
include\warnings.h: include\warnings.h.time
@: Side effect
doc\warnings.src.time: asm\warnings.pl asm\warnings.time
$(RUNPERL) $(srcdir)\asm\warnings.pl doc doc\warnings.src &
'$(srcdir)' $(WARNSRCS)
$(EMPTY) doc\warnings.src.time
doc\warnings.src : doc\warnings.src.time
@: Side effect
# Assembler token hash
asm\tokhash.c: x86\insns.xda x86\insnsn.c asm\tokens.dat asm\tokhash.pl &
perllib\phash.ph
$(RUNPERL) $(srcdir)\asm\tokhash.pl c &
x86\insnsn.c $(srcdir)\x86\regs.dat &
$(srcdir)\asm\tokens.dat > asm\tokhash.c
asm/tokhash.c: x86/insns.xda x86/insnsn.c asm/tokens.dat asm/tokhash.pl &
perllib/phash.ph
$(RUNPERL) $(srcdir)/asm/tokhash.pl c &
x86/insnsn.c $(srcdir)/x86/regs.dat &
$(srcdir)/asm/tokens.dat > asm/tokhash.c
# Assembler token metadata
asm\tokens.h: x86\insns.xda x86\insnsn.c asm\tokens.dat asm\tokhash.pl &
perllib\phash.ph
$(RUNPERL) $(srcdir)\asm\tokhash.pl h &
x86\insnsn.c $(srcdir)\x86\regs.dat &
$(srcdir)\asm\tokens.dat > asm\tokens.h
asm/tokens.h: x86/insns.xda x86/insnsn.c asm/tokens.dat asm/tokhash.pl &
perllib/phash.ph
$(RUNPERL) $(srcdir)/asm/tokhash.pl h &
x86/insnsn.c $(srcdir)/x86/regs.dat &
$(srcdir)/asm/tokens.dat > asm/tokens.h
# Preprocessor token hash
asm\pptok.h: asm\pptok.dat asm\pptok.pl perllib\phash.ph
$(RUNPERL) $(srcdir)\asm\pptok.pl h &
$(srcdir)\asm\pptok.dat asm\pptok.h
asm\pptok.c: asm\pptok.dat asm\pptok.pl perllib\phash.ph
$(RUNPERL) $(srcdir)\asm\pptok.pl c &
$(srcdir)\asm\pptok.dat asm\pptok.c
asm\pptok.ph: asm\pptok.dat asm\pptok.pl perllib\phash.ph
$(RUNPERL) $(srcdir)\asm\pptok.pl ph &
$(srcdir)\asm\pptok.dat asm\pptok.ph
asm/pptok.h: asm/pptok.dat asm/pptok.pl perllib/phash.ph
$(RUNPERL) $(srcdir)/asm/pptok.pl h &
$(srcdir)/asm/pptok.dat asm/pptok.h
asm/pptok.c: asm/pptok.dat asm/pptok.pl perllib/phash.ph
$(RUNPERL) $(srcdir)/asm/pptok.pl c &
$(srcdir)/asm/pptok.dat asm/pptok.c
asm/pptok.ph: asm/pptok.dat asm/pptok.pl perllib/phash.ph
$(RUNPERL) $(srcdir)/asm/pptok.pl ph &
$(srcdir)/asm/pptok.dat asm/pptok.ph
doc/pptok.src: asm/pptok.dat asm/pptok.pl perllib/phash.ph
$(RUNPERL) $(srcdir)/asm/pptok.pl src &
$(srcdir)/asm/pptok.dat doc/pptok.src
# Directives hash
asm\directiv.h: asm\directiv.dat nasmlib\perfhash.pl perllib\phash.ph
$(RUNPERL) $(srcdir)\nasmlib\perfhash.pl h &
$(srcdir)\asm\directiv.dat asm\directiv.h
asm\directbl.c: asm\directiv.dat nasmlib\perfhash.pl perllib\phash.ph
$(RUNPERL) $(srcdir)\nasmlib\perfhash.pl c &
$(srcdir)\asm\directiv.dat asm\directbl.c
asm/directiv.h: asm/directiv.dat nasmlib/perfhash.pl perllib/phash.ph
$(RUNPERL) $(srcdir)/nasmlib/perfhash.pl h &
$(srcdir)/asm/directiv.dat asm/directiv.h
asm/directbl.c: asm/directiv.dat nasmlib/perfhash.pl perllib/phash.ph
$(RUNPERL) $(srcdir)/nasmlib/perfhash.pl c &
$(srcdir)/asm/directiv.dat asm/directbl.c
# Emacs token files
misc\nasmtok.el: misc\emacstbl.pl asm\tokhash.c asm\pptok.c &
asm\directiv.dat version
$(RUNPERL) $< $@ "$(srcdir)" "$(objdir)"
# Editor token files
editors/nasmtok.el: editors/nasmtok.pl asm/tokhash.c asm/pptok.c &
asm/directiv.dat macros/macros.c editors/builtin.mac &
version.mak
$(RUNPERL) $(srcdir)/editors/nasmtok.pl -el $@ $(srcdir) $(objdir)
editors/nasmtok.json: editors/nasmtok.pl asm/tokhash.c asm/pptok.c &
asm/directiv.dat macros/macros.c editors/builtin.mac &
version.mak
$(RUNPERL) $(srcdir)/editors/nasmtok.pl -json $@ $(srcdir) $(objdir)
editors: $(EDITORS) $(PHONY)
asm/warnings_c.h: asm/warnings.pl asm/warnings.dat
$(RUNPERL) $(srcdir)/asm/warnings.pl c asm/warnings_c.h &
$(srcdir)/asm/warnings.dat
include/warnings.h: asm/warnings.pl asm/warnings.dat
$(RUNPERL) $(srcdir)/asm/warnings.pl h include/warnings.h &
$(srcdir)/asm/warnings.dat
doc/warnings.src: asm/warnings.pl asm/warnings.dat
$(RUNPERL) $(srcdir)/asm/warnings.pl doc doc/warnings.src &
$(srcdir)/asm/warnings.dat
$(PERLREQ): $(DIRS)
perlreq: $(PERLREQ) $(PHONY)
warnings: $(WARNFILES) $(PHONY)
#-- End Generated File Rules --#
perlreq: $(PERLREQ) .SYMBOLIC
#-- Begin NSIS Rules --#
# Edit in Makefile.in, not here!
nsis\arch.nsh: nsis\getpearch.pl nasm$(X)
$(PERL) $(srcdir)\nsis\getpearch.pl nasm$(X) > nsis\arch.nsh
nsis/arch.nsh: nsis/getpearch.pl nasm$(X) $(DIRS)
$(PERL) $(srcdir)/nsis/getpearch.pl nasm$(X) > nsis/arch.nsh
# Should only be done after "make everything".
# The use of redirection here keeps makensis from moving the cwd to the
# source directory.
nsis: nsis\nasm.nsi nsis\arch.nsh nsis\version.nsh
$(MAKENSIS) -Dsrcdir="$(srcdir)" -Dobjdir="$(objdir)" - < nsis\nasm.nsi
nsis: nsis/nasm.nsi nsis/arch.nsh nsis/version.nsh
$(MAKENSIS) -Dsrcdir=$(srcdir) -Dobjdir=$(objdir) - &
< $(srcdir)/nsis/nasm.nsi
#-- End NSIS Rules --#
clean: .SYMBOLIC
clean: $(PHONY)
rm -f *.obj *.s *.i
rm -f asm\*.obj asm\*.s asm\*.i
rm -f x86\*.obj x86\*.s x86\*.i
rm -f lib\*.obj lib\*.s lib\*.i
rm -f macros\*.obj macros\*.s macros\*.i
rm -f output\*.obj output\*.s output\*.i
rm -f common\*.obj common\*.s common\*.i
rm -f stdlib\*.obj stdlib\*.s stdlib\*.i
rm -f nasmlib\*.obj nasmlib\*.s nasmlib\*.i
rm -f disasm\*.obj disasm\*.s disasm\*.i
rm -f asm/*.obj asm/*.s asm/*.i
rm -f x86/*.obj x86/*.s x86/*.i
rm -f lib/*.obj lib/*.s lib/*.i
rm -f macros/*.obj macros/*.s macros/*.i
rm -f output/*.obj output/*.s output/*.i
rm -f common/*.obj common/*.s common/*.i
rm -f stdlib/*.obj stdlib/*.s stdlib/*.i
rm -f nasmlib/*.obj nasmlib/*.s nasmlib/*.i
rm -f disasm/*.obj disasm/*.s disasm/*.i
rm -f zlib/*.obj zlib/*.s zlib/*.i
rm -f config.h config.log config.status
rm -f nasm$(X) ndisasm$(X) $(NASMLIB) $(NDISLIB)
distclean: clean .SYMBOLIC
distclean: clean $(PHONY)
rm -f config.h config.log config.status
rm -f Makefile *~ *.bak *.lst *.bin
rm -f output\*~ output\*.bak
rm -f test\*.lst test\*.bin test\*.obj test\*.bin
rm -f output/*~ output/*.bak
rm -f test/*.lst test/*.bin test/*.obj test/*.bin
cleaner: clean .SYMBOLIC
cleaner: clean $(PHONY)
rm -f $(PERLREQ)
rm -f *.man
rm -f nasm.spec
# cd doc && $(MAKE) clean
spotless: distclean cleaner .SYMBOLIC
rm -f doc\Makefile doc\*~ doc\*.bak
spotless: distclean cleaner $(PHONY)
rm -f doc/Makefile doc/*~ doc/*.bak
strip: .SYMBOLIC
strip: $(PHONY)
$(STRIP) *.exe
doc:
# cd doc && $(MAKE) all
# cd doc && $(MAKE) all
everything: all doc
@ -434,13 +452,13 @@ everything: all doc
# This build dependencies in *ALL* makefiles. Partially for that reason,
# it's expected to be invoked manually.
#
alldeps: perlreq .SYMBOLIC
$(PERL) syncfiles.pl Makefile.in Mkfiles\openwcom.mak
$(PERL) mkdep.pl -M Makefile.in Mkfiles\openwcom.mak -- . output lib
alldeps: perlreq $(PHONY)
$(PERL) syncfiles.pl Makefile.in Mkfiles/openwcom.mak
$(PERL) mkdep.pl -M Makefile.in Mkfiles/openwcom.mak -- . output lib
#-- Magic hints to mkdep.pl --#
# @object-ending: ".obj"
# @path-separator: "\"
# @path-separator: "/"
# @exclude: "config/config.h"
# @continuation: "&"
#-- Everything below is generated by mkdep.pl - do not edit --#

View file

@ -6,10 +6,10 @@ Actually the rules are pretty simple
Obtaining the source code
-------------------------
The NASM sources are tracked by Git SCM at http://repo.or.cz/w/nasm.git
The NASM sources are tracked by Git SCM at https://github.com/netwide-assembler/nasm.git
repository. You either could download packed sources or use git tool itself
git clone git://repo.or.cz/nasm.git
git clone https://github.com/netwide-assembler/nasm.git
Changin the source code
-----------------------
@ -33,7 +33,7 @@ There are at least two ways to make it right.
at all.
2) Use "diff -up"
Use "diff -up" or "diff -uprN" to create patches.
Signing your work
@ -86,8 +86,10 @@ An example of patch message
From: Random J Developer <random@developer.example.org>
Subject: [PATCH] Short patch description
Long patch description (could be skipped if patch
is trivial enough)
Long patch description:
Explain the problem you are fixing, the consequences of that problem,
and why your patch is the correct way to fix it.
Signed-off-by: Random J Developer <random@developer.example.org>
---

View file

@ -1,35 +1,5 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 2025 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ----------------------------------------------------------------------- */
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 2025 The NASM Authors - All Rights Reserved */
#ifndef NASM_ASMUTIL_H
#define NASM_ASMUTIL_H

View file

@ -1,35 +1,5 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 1996-2025 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ----------------------------------------------------------------------- */
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2025 The NASM Authors - All Rights Reserved */
/*
* assemble.c code generation for the Netwide Assembler
@ -60,9 +30,9 @@ enum match_result {
MERR_OPSIZEINVAL,
MERR_OPSIZEMISSING,
MERR_OPSIZEMISMATCH,
MERR_MASKNOTHERE,
MERR_BRNOTHERE,
MERR_BRNUMMISMATCH,
MERR_MASKNOTHERE,
MERR_DECONOTHERE,
MERR_BADZU,
MERR_MEMZU,
@ -105,11 +75,11 @@ enum match_result {
static int64_t assemble(insn *instruction);
static int64_t insn_size(insn *instruction);
static int64_t calcsize(insn *, const struct itemplate *);
static int64_t calcsize(insn *);
static int64_t calcsize_speculative(const insn *, const struct itemplate *);
static int emit_prefixes(struct out_data *data, const insn *ins);
static void gencode(struct out_data *data, insn *ins);
static enum match_result find_match(const struct itemplate **tempp,
insn *instruction);
static enum match_result find_match(insn *instruction);
static enum match_result matches(const struct itemplate *, const insn *);
static opflags_t regflag(const operand *);
static int32_t regval(const operand *);
@ -279,17 +249,6 @@ static void debug_macro_out(const struct out_data *data)
* generator at the same time, flatten unnecessary relocations,
* and verify backend compatibility.
*/
/*
* This warning is currently issued by backends, but in the future
* this code should be centralized.
*
*!zeroing [on] \c{RES}\e{x} in initialized section becomes zero
*! a \c{RES}\e{x} directive was used in a section which contains
*! initialized data, and the output format does not support
*! this. Instead, this will be replaced with explicit zero
*! content, which may produce a large output file.
*/
/*
* Add the entries in struct out_data for the rather bizarre legacy
* backend interface, and then submit to the backend.
@ -430,78 +389,6 @@ static void out(struct out_data *data)
asize = amax = 0; /* No longer an address */
}
} else {
/*!
*!reloc-abs-byte [off] 8-bit absolute section-crossing relocation
*! warns that an 8-bit absolute relocation that could
*! not be resolved at assembly time was generated in
*! the output format.
*!
*! This is usually normal, but may not be handled by all
*! possible target environments
*/
/*!
*!reloc-abs-word [off] 16-bit absolute section-crossing relocation
*! warns that a 16-bit absolute relocation that could
*! not be resolved at assembly time was generated in
*! the output format.
*!
*! This is usually normal, but may not be handled by all
*! possible target environments
*/
/*!
*!reloc-abs-dword [off] 32-bit absolute section-crossing relocation
*! warns that a 32-bit absolute relocation that could
*! not be resolved at assembly time was generated in
*! the output format.
*!
*! This is usually normal, but may not be handled by all
*! possible target environments
*/
/*!
*!reloc-abs-qword [off] 64-bit absolute section-crossing relocation
*! warns that a 64-bit absolute relocation that could
*! not be resolved at assembly time was generated in
*! the output format.
*!
*! This is usually normal, but may not be handled by all
*! possible target environments
*/
/*!
*!reloc-rel-byte [off] 8-bit relative section-crossing relocation
*! warns that an 8-bit relative relocation that could
*! not be resolved at assembly time was generated in
*! the output format.
*!
*! This is usually normal, but may not be handled by all
*! possible target environments
*/
/*!
*!reloc-rel-word [off] 16-bit relative section-crossing relocation
*! warns that a 16-bit relative relocation that could
*! not be resolved at assembly time was generated in
*! the output format.
*!
*! This is usually normal, but may not be handled by all
*! possible target environments
*/
/*!
*!reloc-rel-dword [off] 32-bit relative section-crossing relocation
*! warns that a 32-bit relative relocation that could
*! not be resolved at assembly time was generated in
*! the output format.
*!
*! This is usually normal, but may not be handled by all
*! possible target environments
*/
/*!
*!reloc-rel-qword [off] 64-bit relative section-crossing relocation
*! warns that an 64-bit relative relocation that could
*! not be resolved at assembly time was generated in
*! the output format.
*!
*! This is usually normal, but may not be handled by all
*! possible target environments
*/
int warn;
const char *type;
@ -568,11 +455,6 @@ static void out(struct out_data *data)
nasm_nonfatal("%u-bit signed relocation unsupported by output format %s",
(unsigned int)(asize << 3), ofmt->shortname);
} else {
/*!
*!zext-reloc [on] relocation zero-extended to match output format
*! warns that a relocation has been zero-extended due
*! to limitations in the output format.
*/
nasm_warn(WARN_ZEXT_RELOC,
"%u-bit %s relocation zero-extended from %u bits",
(unsigned int)(asize << 3),
@ -752,8 +634,85 @@ static void out_reladdr(struct out_data *data, const struct operand *opx,
out(data);
}
/* Issue an error message on match failure */
static void no_match_error(enum match_result m, const insn *ins)
{
/* No match */
switch (m) {
case MERR_INVALOP:
nasm_holderr("invalid combination of opcode and operands");
break;
case MERR_OPSIZEINVAL:
nasm_holderr("invalid operand sizes for instruction");
break;
case MERR_OPSIZEMISSING:
nasm_holderr("operation size not specified");
break;
case MERR_OPSIZEMISMATCH:
nasm_holderr("mismatch in operand sizes");
break;
case MERR_BRNOTHERE:
nasm_holderr("broadcast not permitted on this operand");
break;
case MERR_BRNUMMISMATCH:
nasm_holderr("mismatch in the number of broadcasting elements");
break;
case MERR_MASKNOTHERE:
nasm_holderr("mask not permitted on this operand");
break;
case MERR_DECONOTHERE:
nasm_holderr("unsupported mode decorator for instruction");
break;
case MERR_BADCPU:
nasm_holderr("no instruction for this cpu level");
break;
case MERR_BADMODE:
nasm_holderr("instruction not supported in %d-bit mode", ins->bits);
break;
case MERR_ENCMISMATCH:
if (!ins->prefixes[PPS_REX]) {
nasm_holderr("instruction not encodable without explicit prefix");
} else {
nasm_holderr("instruction not encodable with %s prefix",
prefix_name(ins->prefixes[PPS_REX]));
}
break;
case MERR_BADBND:
case MERR_BADREPNE:
nasm_holderr("%s prefix is not allowed",
prefix_name(ins->prefixes[PPS_REP]));
break;
case MERR_REGSETSIZE:
nasm_holderr("invalid register set size");
break;
case MERR_REGSET:
nasm_holderr("register set not valid for operand");
break;
case MERR_WRONGIMM:
nasm_holderr("operand/operator invalid for this instruction");
break;
case MERR_BADZU:
nasm_holderr("{zu} not applicable to this instruction");
break;
case MERR_MEMZU:
nasm_holderr("{zu} invalid for non-register destination");
break;
case MERR_BADNF:
nasm_holderr("{nf} not available for this instruction");
break;
case MERR_REQNF:
nasm_holderr("{nf} required for this instruction");
break;
default:
if (m < MOK_GOOD)
nasm_holderr("invalid use of instruction");
break;
}
}
/* This is a real hack. The jcc8 or jmp8 byte code must come first. */
static enum match_result jmp_match(const struct itemplate *temp, const insn *ins)
static enum match_result
jmp_match(const insn *ins, const struct itemplate *temp)
{
const struct operand * const op0 = get_operand_const(ins, 0);
int64_t delta;
@ -794,34 +753,18 @@ static enum match_result jmp_match(const struct itemplate *temp, const insn *ins
* instruction size.
*
* Note that the instruction size is to be *subtracted* from the
* initial (beginning-of-instruction) delta value.
* initial (beginning-of-instruction) delta value, or *added* to the
* limiting value compared to.
*/
delta = op0->offset - ins->loc.offset;
if (delta - 2 < -128 || delta - 15 > 127) {
if (delta < -128 + 2 || delta > 127 + 15) {
/* This cannot be a byte-sized jump */
return MERR_INVALOP;
} else if (delta - 15 >= -128 && delta - 2 <= 127) {
} else if (delta >= -128 + 15 && delta <= 127 + 2) {
/* It is guaranteed to be a valid byte-sized jump, no need to test */
} else {
/*
* Need to do this the hard way.
*
* However, calcsize() can modify the instruction structure,
* but after a mismatch we have to revert to the original
* state, so make a copy here and hold error messages.
*/
int64_t isize;
insn tmpins;
errhold hold;
tmpins = *ins;
tmpins.dummy = true;
hold = nasm_error_hold_push();
isize = calcsize(&tmpins, temp);
if (nasm_error_hold_pop(hold, false) >= ERR_NONFATAL)
return MERR_INVALOP;
/* Borderline: need to do this the hard way... */
int64_t isize = calcsize_speculative(ins, temp);
if (isize < 0)
return MERR_INVALOP;
delta -= isize;
@ -928,13 +871,24 @@ static void out_eops(struct out_data *data, const extop *e)
/* This is totally just a wild guess what is reasonable... */
#define INCBIN_MAX_BUF (ZERO_BUF_SIZE * 16)
static void
list_add_template_info(const insn *ins)
{
char *buf;
(void)ins;
buf = nasm_asprintf(" ;;; used template %s:%d from insns.xda:%u",
nasm_insn_names[ins->opcode], ins->itempindex,
ins->itemp->xdaline);
lfmt->line(LIST_INFO, -1, buf);
nasm_free(buf);
}
static int64_t assemble(insn *instruction)
{
struct out_data data;
const struct itemplate *temp;
enum match_result m;
const int64_t start = instruction->loc.offset;
const int bits = instruction->bits;
if (instruction->opcode == I_none)
return 0;
@ -949,6 +903,7 @@ static int64_t assemble(insn *instruction)
const char *fname = instruction->eops->val.string.data;
FILE *fp;
size_t t = instruction->times; /* INCBIN handles TIMES by itself */
bool need_downlevel_times;
off_t base = 0;
off_t len;
const void *map = NULL;
@ -987,7 +942,6 @@ static int64_t assemble(insn *instruction)
}
lfmt->set_offset(data.loc.offset);
lfmt->uplevel(LIST_INCBIN, len);
if (!len)
goto end_incbin;
@ -999,6 +953,7 @@ static int64_t assemble(insn *instruction)
buf = nasm_malloc(blk);
}
need_downlevel_times = false;
while (t--) {
/*
* Consider these irrelevant for INCBIN, since it is fully
@ -1011,6 +966,8 @@ static int64_t assemble(insn *instruction)
data.insoffs = 0;
data.inslen = 0;
lfmt->uplevel(LIST_INCBIN, len);
if (map) {
out_rawdata(&data, map, len);
} else if ((off_t)m == len) {
@ -1021,31 +978,39 @@ static int64_t assemble(insn *instruction)
if (fseeko(fp, base, SEEK_SET) < 0 || ferror(fp)) {
nasm_nonfatal("`incbin': unable to seek on file `%s'",
fname);
goto end_incbin;
}
while (l > 0) {
m = fread(buf, 1, l < (off_t)blk ? (size_t)l : blk, fp);
if (!m || feof(fp)) {
/*
* This shouldn't happen unless the file
* actually changes while we are reading
* it.
*/
nasm_nonfatal("`incbin': unexpected EOF while"
" reading file `%s'", fname);
goto end_incbin;
t = 0; /* No more iterations */
} else {
while (l > 0) {
m = fread(buf, 1, l < (off_t)blk ? (size_t)l : blk, fp);
if (!m || feof(fp)) {
/*
* This shouldn't happen unless the file
* actually changes while we are reading
* it.
*/
nasm_nonfatal("`incbin': unexpected EOF while"
" reading file `%s'", fname);
t = 0; /* No more iterations */
break;
} else {
out_rawdata(&data, buf, m);
l -= m;
}
}
out_rawdata(&data, buf, m);
l -= m;
}
}
lfmt->downlevel(LIST_INCBIN);
if (t && !need_downlevel_times) {
lfmt->uplevel(LIST_TIMES, instruction->times);
need_downlevel_times = true;
}
}
end_incbin:
lfmt->downlevel(LIST_INCBIN);
if (instruction->times > 1) {
lfmt->uplevel(LIST_TIMES, instruction->times);
if (need_downlevel_times)
lfmt->downlevel(LIST_TIMES);
}
end_incbin:
if (ferror(fp)) {
nasm_nonfatal("`incbin': error while"
" reading file `%s'", fname);
@ -1065,10 +1030,15 @@ static int64_t assemble(insn *instruction)
/* Pre-match instruction structure update */
insn_early_setup(instruction);
m = find_match(&temp, instruction);
m = find_match(instruction);
if (m >= MOK_GOOD) {
const struct itemplate * const temp = instruction->itemp;
/* Matches! */
if (list_option('X'))
list_add_template_info(instruction);
if (unlikely(itemp_has(temp, IF_OBSOLETE))) {
errflags warning;
const char *whathappened;
@ -1080,27 +1050,9 @@ static int64_t assemble(insn *instruction)
* warning classes for "obsolete but valid for this
* specific CPU" and "obsolete and gone."
*
*!obsolete-removed [on] instruction obsolete and removed on the target CPU
*! warns for an instruction which has been removed
*! from the architecture, and is no longer included
*! in the CPU definition given in the \c{[CPU]}
*! directive, for example \c{POP CS}, the opcode for
*! which, \c{0Fh}, instead is an opcode prefix on
*! CPUs newer than the first generation 8086.
*
*!obsolete-nop [on] instruction obsolete and is a noop on the target CPU
*! warns for an instruction which has been removed
*! from the architecture, but has been architecturally
*! defined to be a noop for future CPUs.
*
*!obsolete-valid [on] instruction obsolete but valid on the target CPU
*! warns for an instruction which has been removed
*! from the architecture, but is still valid on the
*! specific CPU given in the \c{CPU} directive. Code
*! using these instructions is most likely not
*! forward compatible.
* This currently doesn't really happen correctly;
* it requires better information in insns.dat.
*/
whathappened = never ? "never implemented" : "obsolete";
if (!never && !iflag_cmp_cpu_level(&insns_flags[temp->iflag_idx], &cpu)) {
@ -1118,8 +1070,12 @@ static int64_t assemble(insn *instruction)
whathappened, validity);
}
data.inslen = calcsize(instruction, temp);
nasm_assert(data.inslen >= 0);
data.inslen = calcsize(instruction);
/* This can happen if the instruction generated an error */
if (data.inslen <= 0)
return 0;
data.inslen = merge_resb(instruction, data.inslen);
data.insoffs = 0;
@ -1131,75 +1087,7 @@ static int64_t assemble(insn *instruction)
nasm_assert(data.loc.offset - start == data.inslen);
} else {
/* No match */
switch (m) {
case MERR_INVALOP:
default:
nasm_nonfatal("invalid combination of opcode and operands");
break;
case MERR_OPSIZEINVAL:
nasm_nonfatal("invalid operand sizes for instruction");
break;
case MERR_OPSIZEMISSING:
nasm_nonfatal("operation size not specified");
break;
case MERR_OPSIZEMISMATCH:
nasm_nonfatal("mismatch in operand sizes");
break;
case MERR_BRNOTHERE:
nasm_nonfatal("broadcast not permitted on this operand");
break;
case MERR_BRNUMMISMATCH:
nasm_nonfatal("mismatch in the number of broadcasting elements");
break;
case MERR_MASKNOTHERE:
nasm_nonfatal("mask not permitted on this operand");
break;
case MERR_DECONOTHERE:
nasm_nonfatal("unsupported mode decorator for instruction");
break;
case MERR_BADCPU:
nasm_nonfatal("no instruction for this cpu level");
break;
case MERR_BADMODE:
nasm_nonfatal("instruction not supported in %d-bit mode", bits);
break;
case MERR_ENCMISMATCH:
if (!instruction->prefixes[PPS_REX]) {
nasm_nonfatal("instruction not encodable without explicit prefix");
} else {
nasm_nonfatal("instruction not encodable with %s prefix",
prefix_name(instruction->prefixes[PPS_REX]));
}
break;
case MERR_BADBND:
case MERR_BADREPNE:
nasm_nonfatal("%s prefix is not allowed",
prefix_name(instruction->prefixes[PPS_REP]));
break;
case MERR_REGSETSIZE:
nasm_nonfatal("invalid register set size");
break;
case MERR_REGSET:
nasm_nonfatal("register set not valid for operand");
break;
case MERR_WRONGIMM:
nasm_nonfatal("operand/operator invalid for this instruction");
break;
case MERR_BADZU:
nasm_nonfatal("{zu} not applicable to this instruction");
break;
case MERR_MEMZU:
nasm_nonfatal("{zu} invalid for non-register destination");
break;
case MERR_BADNF:
nasm_nonfatal("{nf} not available for this instruction");
break;
case MERR_REQNF:
nasm_nonfatal("{nf} required for this instruction");
break;
}
no_match_error(m, instruction);
instruction->times = 1; /* Avoid repeated error messages */
}
}
@ -1368,7 +1256,6 @@ static int64_t len_extops(const extop *e)
static int64_t insn_size(insn *instruction)
{
const struct itemplate *temp;
enum match_result m;
int64_t isize = 0;
@ -1416,11 +1303,13 @@ static int64_t insn_size(insn *instruction)
/* Pre-matching setup */
insn_early_setup(instruction);
m = find_match(&temp, instruction);
if (m < MOK_GOOD)
m = find_match(instruction);
if (m < MOK_GOOD) {
no_match_error(m, instruction);
return -1; /* No match */
}
isize = calcsize(instruction, temp);
isize = calcsize(instruction);
debug_set_type(instruction);
isize = merge_resb(instruction, isize);
@ -1447,12 +1336,6 @@ static void bad_hle_warn(const insn * ins, uint8_t hleok)
if (!is_class(MEMORY, ins->oprs[0].type))
ww = w_inval; /* HLE requires operand 0 to be memory */
/*!
*!prefix-hle [on] invalid HLE prefix
*!=hle
*! warns about invalid use of the HLE \c{XACQUIRE} or \c{XRELEASE}
*! prefixes.
*/
switch (ww) {
case w_none:
break;
@ -1509,12 +1392,49 @@ static int ea_evex_flags(insn *ins, const struct operand *opy)
return 0;
}
/*
* Call calcsize() without modifying the source instruction, and without
* generating errors. This is used to answer the question "how long would
* this instruction be if it were to be generated at this point in the
* code." This is currently used by jmp_match() but may be used by other
* things in the future.
*
* Returns < 0 if generating the instruction would throw an error.
*/
static int64_t
calcsize_speculative(const insn *ins, const struct itemplate *itemp)
{
int64_t isize;
insn tmpins;
errhold hold;
tmpins = *ins;
tmpins.dummy = true;
tmpins.itemp = itemp;
hold = nasm_error_hold_push();
isize = calcsize(&tmpins);
if (nasm_error_hold_pop(hold, false) >= ERR_NONFATAL)
return -1;
return isize;
}
/* Common construct */
#define case3(x) case (x): case (x)+1: case (x)+2
#define case4(x) case3(x): case (x)+3
static int64_t calcsize(insn *ins, const struct itemplate * const temp)
/*
* calcsize() is assumed to be processing a *confirmed* instruction for
* the purpose of code generation: it can modify *ins, and will throw
* errors for invalid code. Use calcsize_speculative() if it is necessary
* to calculate the size of a *potential* instruction.
*/
static int64_t calcsize(insn *ins)
{
const struct itemplate * const temp = ins->itemp;
const int bits = ins->bits;
const uint8_t *codes = temp->code;
int64_t length = 0;
@ -1534,11 +1454,9 @@ static int64_t calcsize(insn *ins, const struct itemplate * const temp)
ins->evex = 0; /* Ensure EVEX is reset */
ins->vexreg = 0; /* No V register */
ins->vex_cm = 0; /* No implicit map */
ins->bits = bits; /* Execution mode (default asize) */
ins->itemp = temp; /* Instruction template */
eat = EA_SCALAR; /* Expect a scalar EA */
/* Default operand size */
/* Default operand size (prefixes are handled in the byte code) */
ins->op_size = bits != 16 ? 32 : 16;
nasm_zero(need_pfx);
@ -1583,7 +1501,7 @@ static int64_t calcsize(insn *ins, const struct itemplate * const temp)
if (opx->type & (BITS16 | BITS32 | BITS64))
length += (opx->type & BITS16) ? 2 : 4;
else
length += (bits == 16) ? 2 : 4;
length += (ins->op_size == 16) ? 2 : 4;
break;
case4(040):
@ -1610,7 +1528,7 @@ static int64_t calcsize(insn *ins, const struct itemplate * const temp)
if (opx->type & (BITS16 | BITS32 | BITS64))
length += (opx->type & BITS16) ? 2 : 4;
else
length += (bits == 16) ? 2 : 4;
length += (ins->op_size == 16) ? 2 : 4;
break;
case4(070):
@ -1753,11 +1671,6 @@ static int64_t calcsize(insn *ins, const struct itemplate * const temp)
case 0320:
is_o16:
{
/*! prefix-opsize [on] invalid operand size prefix
*! warns that an operand prefix (\c{o16}, \c{o32}, \c{o64},
*! \c{osp}) invalid for the specified instruction has been specified.
*! The operand prefix will be ignored by the assembler.
*/
enum prefixes pfx = ins->prefixes[PPS_OSIZE];
ins->op_size = 16;
if (bits != 16 && pfx == P_OSP) {
@ -1891,17 +1804,6 @@ static int64_t calcsize(insn *ins, const struct itemplate * const temp)
break;
case 0340:
/*!
*!forward [on] forward reference may have unpredictable results
*! warns that a forward reference is used which may have
*! unpredictable results, notably in a \c{RESB}-type
*! pseudo-instruction. These would be \i\e{critical
*! expressions} (see \k{crit}) but are permitted in a
*! handful of cases for compatibility with older
*! versions of NASM. This warning should be treated as a
*! severe programming error as the code could break at
*! any time for any number of reasons.
*/
/* The bytecode ends in 0, so opx points to operand 0 */
if (!absolute_op(opx)) {
nasm_nonfatal("attempt to reserve non-constant"
@ -1990,16 +1892,6 @@ static int64_t calcsize(insn *ins, const struct itemplate * const temp)
if (ins->prefixes[PPS_REP] == P_BND) {
/* jmp short (opcode eb) cannot be used with bnd prefix. */
ins->prefixes[PPS_REP] = P_none;
/*!
*!prefix-bnd [on] invalid \c{BND} prefix
*!=bnd
*! warns about ineffective use of the \c{BND} prefix when the
*! \c{JMP} instruction is converted to the \c{SHORT} form.
*! This should be extremely rare since the short \c{JMP} only
*! is applicable to jumps inside the same module, but if
*! it is legitimate, it may be necessary to use
*! \c{bnd jmp dword}.
*/
if (!ins->dummy)
nasm_warn(WARN_PREFIX_BND,
"jmp short does not init bnd regs - bnd prefix dropped");
@ -2226,21 +2118,8 @@ static int64_t calcsize(insn *ins, const struct itemplate * const temp)
if (lockcheck && has_prefix(ins, PPS_LOCK, P_LOCK)) {
if ((!itemp_has(temp,IF_LOCK) || !is_class(MEMORY, ins->oprs[0].type)) &&
(!itemp_has(temp,IF_LOCK1) || !is_class(MEMORY, ins->oprs[1].type))) {
/*!
*!prefix-lock-error [on] \c{LOCK} prefix on unlockable instruction
*!=lock
*! warns about \c{LOCK} prefixes on unlockable instructions.
*/
nasm_warn(WARN_PREFIX_LOCK_ERROR, "instruction is not lockable");
} else if (temp->opcode == I_XCHG) {
/*!
*!prefix-lock-xchg [on] superfluous \c{LOCK} prefix on \c{XCHG} instruction
*! warns about a \c{LOCK} prefix added to an \c{XCHG} instruction.
*! The \c{XCHG} instruction is \e{always} locking, and so this
*! prefix is not necessary; however, NASM will generate it if
*! explicitly provided by the user, so this warning indicates that
*! suboptimal code is being generated.
*/
nasm_warn(WARN_PREFIX_LOCK_XCHG,
"superfluous LOCK prefix on XCHG instruction");
}
@ -2262,17 +2141,6 @@ static int64_t calcsize(insn *ins, const struct itemplate * const temp)
*/
if (ins->prefixes[PPS_SEG] == P_PT || ins->prefixes[PPS_SEG] == P_PN) {
if (!itemp_has(temp, IF_JCC_HINT)) {
/*!
*!prefix-hint-dropped [on] invalid branch hint prefix dropped
*! warns that the \c{{PT}} (predict taken) or \c{{PN}}
*! (predict not taken) branch prediction hint prefixes
*! are specified on an instruction that does not take
*! these prefixes. As these prefixes alias the segment
*! override prefixes, this may be a very serious error,
*! and therefore NASM will not generate these prefixes.
*! To force these prefixes to be emitted, use \c{DS} or
*! \c{CS}, instead, respectively.
*/
nasm_warn(WARN_PREFIX_HINT_DROPPED,
"invalid branch hint prefix dropped");
ins->prefixes[PPS_SEG] = 0;
@ -2458,13 +2326,6 @@ static int emit_prefixes(struct out_data *data, const insn *ins)
c = r;
break;
default:
/*!
*!prefix-invalid [on] invalid prefix for instruction
*! this instruction is only valid with certain combinations
*! of prefixes. The prefix will still be generated as
*! requested, but the result may be a completely different
*! instruction.
*/
if (do_warn)
nasm_warn(WARN_PREFIX_INVALID,
"invalid prefix %s for instruction, result may be unexpected",
@ -2483,12 +2344,6 @@ static int emit_prefixes(struct out_data *data, const insn *ins)
/* fall through */
case R_ES:
case R_SS:
/*!
*!prefix-seg [on] segment prefix ignored in 64-bit mode
*! warns that an \c{es}, \c{cs}, \c{ss} or \c{ds} segment override
*! prefix has no effect in 64-bit mode. The prefix will still be
*! generated as requested.
*/
if (do_warn && bits == 64) {
nasm_warn(WARN_PREFIX_SEG,
"%s segment override will be ignored in 64-bit mode",
@ -2612,7 +2467,7 @@ static void gencode(struct out_data *data, insn *ins)
if (opx->type & (BITS16 | BITS32))
size = (opx->type & BITS16) ? 2 : 4;
else
size = (bits == 16) ? 2 : 4;
size = (ins->op_size == 16) ? 2 : 4;
out_imm(data, opx, size, OUT_WRAP);
break;
@ -2648,7 +2503,7 @@ static void gencode(struct out_data *data, insn *ins)
if (opx->type & (BITS16 | BITS32 | BITS64))
size = (opx->type & BITS16) ? 2 : 4;
else
size = (bits == 16) ? 2 : 4;
size = (ins->op_size == 16) ? 2 : 4;
out_reladdr(data, opx, size);
break;
@ -3074,17 +2929,18 @@ static uint32_t op_evexflags(const operand * o, uint32_t mask)
return evexflags(o->decoflags, mask);
}
static enum match_result find_match(const struct itemplate **tempp,
insn *instruction)
static enum match_result find_match(insn *instruction)
{
const int bits = instruction->bits;
const struct itemplate_list *templist;
const struct itemplate *temp;
const struct itemplate *best = NULL;
const struct itemplate *best;
enum match_result m, merr;
int this_good;
int rex = instruction->prefixes[PPS_REX];
unsigned int n;
int n, i, besti;
instruction->itemp = best = NULL;
instruction->itempindex = besti = -1;
/* Impossible encoding request? */
if (bits != 64) {
@ -3093,31 +2949,29 @@ static enum match_result find_match(const struct itemplate **tempp,
}
merr = MERR_INVALOP;
best = NULL;
this_good = 0;
templist = &nasm_instructions[instruction->opcode];
n = templist->ntemp;
temp = templist->temp;
while (n--) {
for (i = 0; i < n; i++) {
m = matches(temp, instruction);
if (m > merr) {
best = temp;
besti = i;
merr = m;
this_good = 1;
if (merr == MOK_GOOD)
break;
} else if (m == merr) {
this_good++;
}
temp++;
}
if (merr >= MOK_FIRST)
merr = MOK_GOOD; /* Fuzzy match but valid */
*tempp = best;
if (merr >= MOK_FIRST) {
/* If this was a fuzzy match it is confirmed now */
merr = MOK_GOOD;
instruction->itemp = best;
instruction->itempindex = besti;
}
return merr;
}
@ -3243,7 +3097,7 @@ static enum match_result matches(const struct itemplate * const itemp,
/* "Default" operand size (from mode and prefixes only) */
op_size = ins->op_size;
if (itemp_has(itemp, IF_NWSIZE) && op_size == 32) {
if (bits == 64 && itemp_has(itemp, IF_NWSIZE) && op_size == 32) {
/* If this is an nw instruction, default to 64 bits in 64-bit mode */
op_size = bits;
}
@ -3283,18 +3137,23 @@ static enum match_result matches(const struct itemplate * const itemp,
/* Handle implied SHORT or NEAR */
if (unlikely(ttype & (NEAR|SHORT))) {
/* Treat BYTE as an alias for SHORT, ignoring size */
if (isize[i] == BITS8) {
itype[i] |= SHORT;
isize[i] = 0;
}
/* An explicit SHORT or BITS8 cancels NEAR; are synonyms */
if (itype[i] & SHORT) {
itype[i] &= ~NEAR;
}
/* NEAR is implicit unless otherwise specified */
if (!(itype[i] & (FAR|SHORT))) {
itype[i] |= ttype & NEAR;
}
if ((ttype & (NEAR|SHORT)) == (NEAR|SHORT)) {
/* Only a short form exists; allow both NEAR and SHORT */
/* Only a short form exists; this is specially coded */
if (!(itype[i] & (FAR|ABS)))
itype[i] |= NEAR|SHORT;
} else if ((itype[i] & SHORT) || isize[i] == BITS8) {
/* An explicit SHORT or BITS8 cancel NEAR; are synonyms */
itype[i] &= ~NEAR;
if (!isize[i])
isize[i] = BITS8;
} else if (!(itype[i] & (FAR|ABS|SHORT))) {
/* NEAR is implicit unless otherwise specified */
itype[i] |= ttype & NEAR;
}
}
@ -3303,20 +3162,18 @@ static enum match_result matches(const struct itemplate * const itemp,
/*
* If this is an *explicitly* sized immediate,
* allow it to match an extending pattern.
*
* NOTE: Open Watcom does not support 64-bit constants
* in switch statements; do not change this to a switch.
*/
switch (isize[i]) {
case BITS8:
if (isize[i] == BITS8) {
if (ttype & BYTEEXTMASK) {
isize[i] = tsize[i];
itype[i] |= BYTEEXTMASK;
}
break;
case BITS32:
} else if (isize[i] == BITS32) {
if (ttype & DWORDEXTMASK)
isize[i] = tsize[i];
break;
default:
break;
}
/*
@ -3539,7 +3396,7 @@ static enum match_result matches(const struct itemplate * const itemp,
* Check if special handling needed for relaxable jump
*/
if (itemp_has(itemp, IF_JMP_RELAX))
return jmp_match(itemp, ins);
return jmp_match(ins, itemp);
return MOK_GOOD;
}
@ -3650,14 +3507,7 @@ static int process_ea(operand *input, int rfield, opflags_t rflags,
input->type |= IP_REL;
}
if ((input->type & IP_REL) == IP_REL) {
/*!
*!ea-absolute [on] absolute address cannot be RIP-relative
*! warns that an address that is inherently absolute cannot
*! be generated with RIP-relative encoding using \c{REL},
*! see \k{default-rel}.
*/
if (input->segment == NO_SEG ||
(input->opflags & OPFLAG_RELATIVE)) {
if (!pass_first() && absolute_op(input)) {
nasm_warn(WARN_EA_ABSOLUTE,
"absolute address can not be RIP-relative");
input->type &= ~IP_REL;
@ -3674,12 +3524,6 @@ static int process_ea(operand *input, int rfield, opflags_t rflags,
if ((eaflags & EAF_BYTEOFFS) ||
((eaflags & EAF_WORDOFFS) &&
input->disp_size != (addrbits != 16 ? 32 : 16))) {
/*!
*!ea-dispsize [on] displacement size ignored on absolute address
*! warns that NASM does not support generating displacements for
*! inherently absolute addresses that do not match the address size
*! of the instruction.
*/
nasm_warn(WARN_EA_DISPSIZE, "displacement size ignored on absolute address");
}

View file

@ -1,35 +1,5 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 1996-2025 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ----------------------------------------------------------------------- */
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2025 The NASM Authors - All Rights Reserved */
/*
* assemble.h - header file for stuff private to the assembler

View file

@ -1,35 +1,5 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 1996-2024 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ----------------------------------------------------------------------- */
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2025 The NASM Authors - All Rights Reserved */
/*
* Parse and handle assembler directives
@ -52,6 +22,7 @@
#include "listing.h"
#include "labels.h"
#include "iflag.h"
#include "quote.h"
struct cpunames {
const char *name;
@ -208,34 +179,51 @@ static int get_bits(const char *value)
static enum directive parse_directive_line(char **directive, char **value)
{
char *p, *q, *buf;
char *p, *q, *eol, *buf;
char c;
buf = nasm_skip_spaces(*directive);
/*
* It should be enclosed in [ ].
* XXX: we don't check there is nothing else on the remainder of the
* line, except a possible comment.
*
* Strip off the comments. We should really strip the comments in
* generic code, not here. While we're at it, it would be better
* to pass the backend a series of tokens instead of a raw string,
* and actually process quoted strings for it, like of like argv
* is handled in C.
*/
if (*buf != '[')
return D_none;
q = strchr(buf, ']');
if (!q)
return D_corrupt;
q = buf;
while ((c = *q) != ']') {
switch (c) {
case '\0':
case ';':
return D_corrupt; /* No ] in directive */
case '\'':
case '\"':
case '`':
q = nasm_skip_string(q);
if (!*q++)
return D_corrupt;
break;
default:
q++;
break;
}
}
/*
* Strip off the comments. XXX: this doesn't account for quoted
* strings inside a directive. We should really strip the
* comments in generic code, not here. While we're at it, it
* would be better to pass the backend a series of tokens instead
* of a raw string, and actually process quoted strings for it,
* like of like argv is handled in C.
* Found the ] at the end of the directive. Make sure there isn't
* anything else at the end of the line, except a possible
* comment.
*/
p = strchr(buf, ';');
if (p) {
if (p < q) /* ouch! somewhere inside */
return D_corrupt;
*p = '\0';
eol = nasm_skip_spaces(q+1);
if (*eol != '\0' && *eol != ';') {
nasm_warn(WARN_DIRECTIVE_GARBAGE_EOL,
"garbage found on line after directive");
}
/* no brace, no trailing spaces */
@ -294,7 +282,7 @@ bool process_directives(char *directive)
switch (d) {
case D_none:
return D_none; /* Not a directive */
return false;
case D_corrupt:
nasm_nonfatal("invalid directive line");
@ -315,6 +303,12 @@ bool process_directives(char *directive)
default:
panic();
}
} else if (d < D_pseudo_ops) {
nasm_nonfatal("internal error: unimplemented directive [%s]",
directive);
break;
} else {
goto unknown;
}
break;
@ -394,6 +388,7 @@ bool process_directives(char *directive)
{
bool validid;
int64_t size = 0;
char *fullvalue = value; /* Including leading $ if present */
char *sizestr;
bool rn_error;
@ -401,7 +396,7 @@ bool process_directives(char *directive)
value++; /* skip escaping $ if present */
validid = nasm_isidchar(*value);
if (globl.dollarhex)
validid &= !nasm_isnumchar(*value);
validid &= !nasm_isnumstart(*value);
} else {
validid = nasm_isidstart(*value);
}
@ -417,7 +412,7 @@ bool process_directives(char *directive)
}
if (!validid) {
nasm_nonfatal("identifier expected after %s, got `%s'",
directive, value);
directive, fullvalue);
break;
}
@ -532,8 +527,9 @@ bool process_directives(char *directive)
push_warnings();
else if (!nasm_stricmp(value, "pop"))
pop_warnings();
} else {
set_warning_status(value);
}
set_warning_status(value);
break;
case D_CPU: /* [CPU] */
@ -546,7 +542,7 @@ bool process_directives(char *directive)
user_nolist = false;
} else {
if (*value == '-') {
user_nolist = true;
user_nolist = !list_option('F');
} else {
bad_param = true;
}
@ -633,13 +629,24 @@ bool process_directives(char *directive)
case D_PRAGMA:
process_pragma(value);
break;
}
case D_PREFIX:
case D_GPREFIX:
case D_SUFFIX:
case D_GSUFFIX:
case D_POSTFIX:
case D_GPOSTFIX:
case D_LPREFIX:
case D_LSUFFIX:
case D_LPOSTFIX:
set_label_mangle(d, value);
break;
}
/* A common error message */
if (bad_param) {
nasm_nonfatal("invalid parameter to [%s] directive", directive);
}
return d != D_none;
return true;
}

View file

@ -1,35 +1,5 @@
;; --------------------------------------------------------------------------
;;
;; Copyright 1996-2025 The NASM Authors - All Rights Reserved
;; See the file AUTHORS included with the NASM distribution for
;; the specific copyright holders.
;;
;; Redistribution and use in source and binary forms, with or without
;; modification, are permitted provided that the following
;; conditions are met:
;;
;; * Redistributions of source code must retain the above copyright
;; notice, this list of conditions and the following disclaimer.
;; * Redistributions in binary form must reproduce the above
;; copyright notice, this list of conditions and the following
;; disclaimer in the documentation and/or other materials provided
;; with the distribution.
;;
;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
;; CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
;; INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
;; MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
;; DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
;; CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
;; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
;; NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
;; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
;; HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
;; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
;; OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
;; EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
;;
;; --------------------------------------------------------------------------
;; SPDX-License-Identifier: BSD-2-Clause
;; Copyright 1996-2025 The NASM Authors - All Rights Reserved
;;
;; List of global NASM directives and pragma operations codes
;;
@ -47,6 +17,12 @@
;; In the future, this will be turned into a general list of keywords
;; to be parsed in special contexts.
;;
;; #special tokens are used to separate different classes of tokens.
;; Make sure to add new tokens to the correct place. If a token is used
;; in both a directive and in pragmas, they should be in the directive
;; part of the list. Tokens used in pragmas *only* go at the end of the
;; list.
;;
; --- General configuration
#name directive
@ -55,10 +31,15 @@
#header directiv.h
; --- Special enum values
; These must be first in the list.
#special none = 0 ; Must be zero
#special unknown
#special corrupt
; --- True directives
; These tokens are accepted as directives by the global code or
; ignored if not implemented.
; --- Global directives
absolute
bits
@ -70,16 +51,29 @@ dollarhex
extern
float
global
static
list
section
segment
warning
sectalign
pragma
required
sectalign
section
segment
static
warning
; --- Common output directives/pragmas
prefix
suffix
postfix
gprefix
gsuffix
gpostfix
lprefix
lsuffix
lpostfix
; --- Pseudo-op list, for the benefit of %isdirective
; Tokens put in this part will be rejected as either directives or
; pragmas
#special pseudo_ops
db
dw
@ -101,6 +95,8 @@ incbin
equ
; --- Format-specific directives
; Tokens put in this part of the list will be forwarded to the
; backend ofmt->directive() method.
#special ofmt
export ; outcoff, outobj
group ; outobj
@ -113,22 +109,17 @@ osabi ; outelf
safeseh ; outcoff
uppercase ; outieee, outobj
; --- The following are tokens used in pragmas, not actual directives
; --- The following are tokens used in pragmas, not actual directives.
; They will not be accepted as directives.
#special pragma_tokens
; --- Assembler pragmas
prefix
suffix
gprefix
gsuffix
lprefix
lsuffix
limit
; --- Listing pragmas
options
; --- Backend pragmas
; --- Backend-specific pragmas
subsections_via_symbols ; macho
no_dead_strip ; macho
maxdump ; dbg

View file

@ -1,35 +1,5 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 1996-2025 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ----------------------------------------------------------------------- */
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2025 The NASM Authors - All Rights Reserved */
/*
* error.c - error message handling routines for the assembler
@ -38,96 +8,28 @@
#include "compiler.h"
#include "nasmlib.h"
#include "error.h"
#include "files.h"
#include "listing.h"
#include "srcfile.h"
#include "strlist.h"
unsigned int debug_nasm; /* Debugging messages? */
unsigned int opt_verbose_info; /* Informational messages? */
struct error_format {
const char *beforeline; /* Before line number, if present */
const char *afterline; /* After line number, if present */
const char *beforemsg; /* Before actual message */
};
/* Common function body */
#define nasm_do_error(_sev,_flags) \
do { \
va_list ap; \
va_start(ap, fmt); \
if ((_sev) >= ERR_CRITICAL) \
nasm_verror_critical((_sev)|(_flags), fmt, ap); \
else \
nasm_verror((_sev)|(_flags), fmt, ap); \
va_end(ap); \
if ((_sev) >= ERR_FATAL) \
abort(); \
} while (0)
/*
* This is the generic function to use when the error type is not
* known a priori. For ERR_DEBUG and ERR_INFO the level can be
* included by
*/
void nasm_error(errflags flags, const char *fmt, ...)
{
nasm_do_error(flags & ERR_MASK, flags);
}
#define nasm_err_helpers(_type, _name, _sev) \
_type nasm_ ## _name ## f (errflags flags, const char *fmt, ...) \
{ \
nasm_do_error(_sev, flags); \
} \
_type nasm_ ## _name (const char *fmt, ...) \
{ \
nasm_do_error(_sev, 0); \
}
nasm_err_helpers(void, listmsg, ERR_LISTMSG)
nasm_err_helpers(void, note, ERR_NOTE)
nasm_err_helpers(void, nonfatal, ERR_NONFATAL)
nasm_err_helpers(fatal_func, fatal, ERR_FATAL)
nasm_err_helpers(fatal_func, critical, ERR_CRITICAL)
nasm_err_helpers(fatal_func, panic, ERR_PANIC)
/*
* Strongly discourage warnings without level by require flags on warnings.
* This means nasm_warn() is the equivalent of the -f variants of the
* other ones.
*
* This is wrapped in a macro to be able to elide it if the warning is
* disabled, hence the extra underscore.
*/
void nasm_warn_(errflags flags, const char *fmt, ...)
{
nasm_do_error(ERR_WARNING, flags);
}
/*
* nasm_info() and nasm_debug() takes mandatory enabling levels.
*/
void nasm_info_(unsigned int level, const char *fmt, ...)
{
if (info_level(level))
nasm_do_error(ERR_INFO, LEVEL(level));
}
void nasm_debug_(unsigned int level, const char *fmt, ...)
{
if (debug_level(level))
nasm_do_error(ERR_DEBUG, LEVEL(level));
}
fatal_func nasm_panic_from_macro(const char *func, const char *file, int line)
{
if (!func)
func = "<unknown>";
nasm_panic("internal error in %s at %s:%d\n", func, file, line);
}
fatal_func nasm_assert_failed(const char *msg, const char *func,
const char *file, int line)
{
if (!func)
func = "<unknown>";
nasm_panic("assertion %s failed in %s at %s:%d", msg, func, file, line);
}
enum error_formats {
ERRFMT_GNU,
ERRFMT_MSVC
};
static const struct error_format errfmts[] = {
{ ":", "", ": " }, /* ERRFMT_GNU */
{ "(", ")", " : " } /* ERRFMT_MSVC */
};
static const struct error_format *errfmt = &errfmts[ERRFMT_GNU];
static void usage(void);
/*
* Warning stack management. Note that there is an implicit "push"
@ -139,6 +41,7 @@ struct warning_stack {
uint8_t state[sizeof warning_state];
};
static struct warning_stack *warning_stack, *warning_state_init;
static struct strlist *warn_list;
/* Push the warning status onto the warning stack */
void push_warnings(void)
@ -158,12 +61,6 @@ void pop_warnings(void)
memcpy(warning_state, ws->state, sizeof warning_state);
if (!ws->next) {
/*!
*!warn-stack-empty [on] warning stack empty
*! a \c{[WARNING POP]} directive was executed when
*! the warning stack is empty. This is treated
*! as a \c{[WARNING *all]} directive.
*/
nasm_warn(WARN_WARN_STACK_EMPTY, "warning stack empty");
} else {
warning_stack = ws->next;
@ -171,16 +68,33 @@ void pop_warnings(void)
}
}
/* Call after the command line is parsed, but before the first pass */
void init_warnings(void)
/* Called after the command line is parsed, but before the first pass */
static void init_warnings(void)
{
push_warnings();
warning_state_init = warning_stack;
}
void error_init(void)
{
erropt.worst = 0;
init_warnings();
}
/* Call after each pass */
void reset_warnings(void)
/* Called before each pass. Buffer warnings if "final" is false. */
void error_pass_start(bool final)
{
nasm_assert(!warn_list);
erropt.worst = 0;
if (!final)
warn_list = strlist_alloc(false);
}
/*
* Called after the completion of each pass. This MUST preserve erropt.worst!
*/
static void reset_warnings(void)
{
struct warning_stack *ws = warning_stack;
@ -194,19 +108,19 @@ void reset_warnings(void)
memcpy(warning_state, ws->state, sizeof warning_state);
}
void error_pass_end(void)
{
strlist_free(&warn_list);
reset_warnings();
}
/*
* This is called when processing a -w or -W option, or a warning directive.
* Returns ok if the action was successful.
*
* Special pseudo-warnings:
*
*!other [on] any warning not specifically mentioned above
*! specifies any warning not included in any specific warning class.
*
*!all [all] all possible warnings
*! is an group alias for \e{all} warning classes. Thus, \c{-w+all}
*! enables all available warnings, and \c{-w-all} disables warnings
*! entirely (since NASM 2.13).
* Special pseudo-warnings (see warnings.dat):
* all - all possible warnings
* other - any warning not specifically assigned a class
*/
bool set_warning_status(const char *value)
{
@ -300,18 +214,21 @@ bool set_warning_status(const char *value)
warning_state[i] |= mask;
break;
case WID_RESET:
{
uint8_t old;
if (warning_state_init)
old = warning_state_init->state[i];
else
old = warning_default[i];
warning_state[i] &= ~mask;
warning_state[i] |= warning_state_init->state[i] & mask;
warning_state[i] |= old & mask;
break;
}
}
}
if (!ok && value) {
/*!
*!unknown-warning [off] unknown warning in \c{-W}/\c{-w} or warning directive
*! warns about a \c{-w} or \c{-W} option or a \c{[WARNING]} directive
*! that contains an unknown warning name or is otherwise not possible to process.
*/
nasm_warn(WARN_UNKNOWN_WARNING, "unknown warning name: %s", value);
}
@ -346,3 +263,504 @@ const char *error_pfx(errflags severity)
return "internal error: ";
}
}
static bool skip_this_pass(errflags severity)
{
errflags type = severity & ERR_MASK;
/*
* See if it's a pass-specific error or warning which should be skipped.
* We can never skip fatal errors as by definition they cannot be
* resumed from.
*/
if (type >= ERR_FATAL)
return false;
/*
* ERR_LISTMSG and ERR_NOTE messages are always skipped; the list
* file receives them anyway as this function is not consulted for
* sending to the list file.
*/
if (type <= ERR_NOTE)
return true;
/*
* This message is not applicable unless it is the last pass we
* are going to execute; this can be either the final
* code-generation pass or the single pass executed in
* preproc-only mode.
*/
return (severity & ERR_PASS2) && !pass_final_or_preproc();
}
/**
* check for suppressed message (usually warnings or notes)
*
* @param severity the severity of the warning or error
* @return true if we should abort error/warning printing
*/
static bool is_suppressed(errflags flags)
{
const errflags severity = flags & ERR_MASK;
const errflags level = WARN_IDX(flags);
if (severity >= ERR_FATAL) {
/* Fatal errors or higher can never be suppressed */
return false;
}
if (flags & erropt.never)
return true;
switch (severity) {
case ERR_WARNING:
if (!(warning_state[level] & WARN_ST_ENABLED))
return true;
break;
case ERR_INFO:
if (!info_level(level))
return true;
break;
case ERR_DEBUG:
if (!debug_level(level))
return true;
break;
default:
break;
}
/* Suppressed by the preprocessor? */
if (!(flags & ERR_PP_LISTMACRO))
return pp_suppress_error(flags);
return false;
}
/**
* Return the true error type (the ERR_MASK part) of the given
* severity, accounting for warnings that may need to be promoted to
* error.
*
* @param severity the severity of the warning or error
* @return true if we should error out
*/
static errflags pure_func true_error_type(errflags severity)
{
const uint8_t warn_is_err = WARN_ST_ENABLED|WARN_ST_ERROR;
int type;
type = severity & ERR_MASK;
if (type == ERR_WARNING) {
/* Promote warning to error? */
uint8_t state = warning_state[WARN_IDX(severity)];
if ((state & warn_is_err) == warn_is_err)
type = ERR_NONFATAL;
}
return type;
}
static const char no_file_name[] = "nasm"; /* What to print if no file name */
/*
* For fatal/critical/panic errors, kill this process.
*
* For FATAL errors doing cleanups, tidying up the list process,
* and so in is acceptable.
*
* For CRITICAL errors, minimize dependencies on memory allocation
* and/or having a system valid state.
*
* For PANIC, if abort_on_panic is set, abort without any other action.
*/
static_fatal_func die_hard(errflags true_type, errflags severity)
{
if (true_type < ERR_PANIC || !erropt.abort_on_panic) {
if (true_type < ERR_CRITICAL) {
/* FATAL shutdown, general cleanup actions are valid */
print_final_report(true);
lfmt->cleanup();
}
fflush(NULL);
close_output(true);
if (severity & ERR_USAGE)
usage();
/* Terminate immediately (exit closes any still open files) */
exit(true_type - ERR_FATAL + 1);
}
/*
* abort() shouldn't ever return, but be paranoid about this,
* plus it helps some compilers clue in to the fact that this
* function can never, ever return.
*/
while (1)
abort();
}
/*
* Returns the struct src_location appropriate for use, after some
* potential filename mangling.
*/
static struct src_location error_where(errflags severity)
{
struct src_location where;
if (severity & ERR_NOFILE) {
where.filename = NULL;
where.lineno = 0;
} else {
where = src_where_error();
if (!where.filename) {
enum filenames fn;
for (fn = FN_INFILE; fn <= FN_OUTFILE; fn++) {
const char *name = get_filename(fn);
if (name && *name) {
where.filename = name;
break;
}
}
where.lineno = 0;
}
}
return where;
}
/*
* error reporting for critical and panic errors: minimize
* the amount of system dependencies for getting a message out,
* and in particular try to avoid memory allocations.
*/
fatal_func nasm_verror_critical(errflags severity, const char *fmt, va_list args)
{
struct src_location where;
errflags true_type = severity & ERR_MASK;
static bool been_here = false;
while (unlikely(been_here))
abort(); /* Recursive critical error... just die */
been_here = true;
erropt.worst = true_type;
where = error_where(severity);
if (!where.filename)
where.filename = no_file_name;
fputs(error_pfx(severity), erropt.file);
fputs(where.filename, erropt.file);
if (where.lineno) {
fprintf(erropt.file, "%s%"PRId32"%s",
errfmt->beforeline, where.lineno, errfmt->afterline);
}
fputs(errfmt->beforemsg, erropt.file);
vfprintf(erropt.file, fmt, args);
fputc('\n', erropt.file);
die_hard(true_type, severity);
unreachable();
}
/**
* Stack of tentative error hold lists.
*/
struct nasm_errtext {
struct nasm_errtext *next;
char *msg; /* Owned by this structure */
struct src_location where; /* Owned by the srcfile system */
errflags severity;
errflags true_type;
int c_errno; /* Saved errno (for ERR_PERROR) */
};
struct nasm_errhold {
struct nasm_errhold *up;
struct nasm_errtext *head, **tail;
};
static struct strlist *warn_list;
static struct nasm_errhold *errhold_stack;
static void nasm_free_error(struct nasm_errtext *et)
{
nasm_free(et->msg);
nasm_free(et);
}
static void nasm_issue_error(struct nasm_errtext *et);
struct nasm_errhold *nasm_error_hold_push(void)
{
struct nasm_errhold *eh;
nasm_new(eh);
eh->up = errhold_stack;
eh->tail = &eh->head;
errhold_stack = eh;
return eh;
}
/* Pop an error hold. Returns the highest severity issued or dropped. */
errflags nasm_error_hold_pop(struct nasm_errhold *eh, bool issue)
{
struct nasm_errtext *et, *etmp;
errflags worst = 0;
/*
* Allow calling with a null argument saying no hold in the first place.
*/
if (!eh)
return worst;
/* This *must* be the current top of the errhold stack */
nasm_assert(eh == errhold_stack);
if (eh->head) {
if (issue) {
if (eh->up) {
/* Commit the current hold list to the previous level */
*eh->up->tail = eh->head;
eh->up->tail = eh->tail;
} else {
/* Issue errors */
list_for_each_safe(et, etmp, eh->head) {
if (et->true_type > worst)
worst = et->true_type;
nasm_issue_error(et);
}
}
} else {
/* Free the list, drop errors */
list_for_each_safe(et, etmp, eh->head) {
if (et->true_type > worst)
worst = et->true_type;
nasm_free_error(et);
}
}
}
errhold_stack = eh->up;
nasm_free(eh);
return worst;
}
/**
* common error reporting
* This is the common back end of the error reporting schemes currently
* implemented. It prints the nature of the warning and then the
* specific error message to erropt.file and may or may not return. It
* doesn't return if the error severity is a "panic" or "debug" type.
*
* @param severity the severity of the warning or error
* @param fmt the printf style format string
*/
void nasm_verror(errflags severity, const char *fmt, va_list args)
{
struct nasm_errtext *et;
int c_errno = errno;
errflags true_type = true_error_type(severity);
if (true_type >= ERR_CRITICAL) {
nasm_verror_critical(severity, fmt, args);
abort();
}
if (is_suppressed(severity))
return;
nasm_new(et);
et->c_errno = c_errno;
et->severity = severity;
et->true_type = true_type;
et->msg = nasm_vasprintf(fmt, args);
et->where = error_where(severity);
if (errhold_stack && true_type <= ERR_NONFATAL) {
/* It is a tentative error */
*errhold_stack->tail = et;
errhold_stack->tail = &et->next;
} else {
nasm_issue_error(et);
}
/*
* Don't do this before then, if we do, we lose messages in the list
* file, as the list file is only generated in the last pass.
*/
if (skip_this_pass(severity))
return;
if (!(severity & (ERR_HERE|ERR_PP_LISTMACRO)))
pp_error_list_macros(severity);
}
/*
* Actually print, list and take action on an error
*/
static void nasm_issue_error(struct nasm_errtext *et)
{
const char *pfx;
char warnsuf[64]; /* Warning suffix */
char linestr[64]; /* Formatted line number if applicable */
const errflags severity = et->severity;
const errflags true_type = et->true_type;
const struct src_location where = et->where;
const char *cerrsep = "";
const char *cerrmsg = "";
bool buffer = true_type < ERR_NONFATAL || (severity & ERR_HOLD);
if (severity & ERR_NO_SEVERITY)
pfx = "";
else
pfx = error_pfx(true_type);
*warnsuf = 0;
if (!(severity & (ERR_HERE|ERR_PP_LISTMACRO))) {
switch (severity & ERR_MASK) {
case ERR_WARNING:
{
const unsigned int level = WARN_IDX(severity);
snprintf(warnsuf, sizeof warnsuf, " [-w+%s%s]",
(true_type >= ERR_NONFATAL) ? "error=" : "",
warning_name[level]);
break;
}
case ERR_DEBUG:
snprintf(warnsuf, sizeof warnsuf, " [--debug=%u]", erropt.debug_nasm);
break;
case ERR_INFO:
snprintf(warnsuf, sizeof warnsuf, " [--info=%u]", erropt.verbose_info);
break;
default:
/* Not WARNING, DEBUG or INFO, not suppressible */
break;
}
if (severity & ERR_PERROR) {
cerrsep = ":";
cerrmsg = strerror(et->c_errno);
}
}
*linestr = 0;
if (where.lineno) {
snprintf(linestr, sizeof linestr, "%s%"PRId32"%s",
errfmt->beforeline, where.lineno, errfmt->afterline);
}
if (!skip_this_pass(severity)) {
const char *file = where.filename ? where.filename : no_file_name;
const char *here = "";
if (severity & ERR_HERE) {
here = where.filename ? " here" : " in an unknown location";
}
if (!warn_list)
buffer = false;
if (buffer) {
/*
* Buffer up warnings and held errors until we either get
* an error or we are on the code-generation pass.
*/
strlist_printf(warn_list, "%s%s%s%s%s%s%s%s%s",
file, linestr, errfmt->beforemsg,
pfx, et->msg, cerrsep, cerrmsg,
here, warnsuf);
} else {
/*
* Actually output an error. If we have buffered
* warnings, and this is a non-warning, output them now.
*/
if (warn_list) {
strlist_write(warn_list, "\n", erropt.file);
strlist_free(&warn_list);
}
fprintf(erropt.file, "%s%s%s%s%s%s%s%s%s\n",
file, linestr, errfmt->beforemsg,
pfx, et->msg, cerrsep, cerrmsg,
here, warnsuf);
}
}
/* Are we recursing from error_list_macros? */
if (severity & ERR_PP_LISTMACRO)
goto done;
/*
* Don't suppress this with skip_this_pass(), or we don't get
* pass1 or preprocessor warnings in the list file
*/
if (severity & ERR_HERE) {
if (where.lineno)
lfmt->error(severity, "%s%s at %s:%"PRId32"%s",
pfx, et->msg, where.filename, where.lineno, warnsuf);
else if (where.filename)
lfmt->error(severity, "%s%s in file %s%s",
pfx, et->msg, where.filename, warnsuf);
else
lfmt->error(severity, "%s%s in an unknown location%s",
pfx, et->msg, warnsuf);
} else {
lfmt->error(severity, "%s%s%s", pfx, et->msg, warnsuf);
}
if (skip_this_pass(severity))
goto done;
if (true_type >= ERR_FATAL) {
die_hard(true_type, severity);
} else if (!buffer) {
if (true_type > erropt.worst)
erropt.worst = true_type;
if (true_type >= ERR_NONFATAL)
erropt.never |= ERR_UNDEAD;
}
done:
nasm_free_error(et);
}
int set_error_format(const char *fmt)
{
if (!nasm_stricmp("vc", fmt) ||
!nasm_stricmp("msvc", fmt) ||
!nasm_stricmp("ms", fmt))
errfmt = &errfmts[ERRFMT_MSVC];
else if (!nasm_stricmp("gnu", fmt) ||
!nasm_stricmp("gcc", fmt))
errfmt = &errfmts[ERRFMT_GNU];
else
return -1;
return 0;
}
static void usage(void)
{
fprintf(erropt.file,
"Usage: %s [-@ response_file] [options...] [--] filename\n"
" For additional help:\n"
" %s -h [run|topics|all|-option]\n",
_progname, _progname);
}
void warn_dollar_hex(void)
{
nasm_warn(WARN_NUMBER_DEPRECATED_HEX,
"$ prefix for hexadecimal is deprecated");
}

View file

@ -1,35 +1,5 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 1996-2024 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ----------------------------------------------------------------------- */
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2024 The NASM Authors - All Rights Reserved */
/*
* eval.c expression evaluator for the Netwide Assembler
@ -766,6 +736,7 @@ static expr *eval_strfunc(enum strfunc type, const char *name)
}
val = readstrnum(string, string_len, &rn_warn);
nasm_free(string);
if (parens) {
scan();
if (tt != ')') {

View file

@ -1,35 +1,5 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 1996-2009 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ----------------------------------------------------------------------- */
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2009 The NASM Authors - All Rights Reserved */
/*
* eval.h header file for eval.c

View file

@ -1,35 +1,5 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 1996-2017 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ----------------------------------------------------------------------- */
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2017 The NASM Authors - All Rights Reserved */
/*
* exprdump.c
@ -61,9 +31,9 @@ static const char *expr_type(int32_t type)
if (type >= EXPR_REG_START && type <= EXPR_REG_END) {
return nasm_reg_names[type - EXPR_REG_START];
} else if (type >= EXPR_SEGBASE) {
snprintf(seg_str, sizeof seg_str, "%sseg %d",
snprintf(seg_str, sizeof seg_str, "%sseg %lu",
(type - EXPR_SEGBASE) == location.segment ? "this " : "",
type - EXPR_SEGBASE);
(unsigned long)(type - EXPR_SEGBASE));
return seg_str;
} else {
return "ERR";
@ -74,6 +44,7 @@ void dump_expr(const expr *e)
{
printf("[");
for (; e->type; e++)
printf("<%s(%d),%"PRId64">", expr_type(e->type), e->type, e->value);
printf("<%s(%"PRId32"),%"PRId64">",
expr_type(e->type), e->type, e->value);
printf("]\n");
}

View file

@ -1,35 +1,5 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 1996-2017 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ----------------------------------------------------------------------- */
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2017 The NASM Authors - All Rights Reserved */
/*
* exprlib.c

View file

@ -1,35 +1,5 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 1996-2020 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ----------------------------------------------------------------------- */
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2020 The NASM Authors - All Rights Reserved */
/*
* float.c floating-point constant support for the Netwide Assembler
@ -229,10 +199,6 @@ static bool ieee_flconvert(const char *string, fp_limb *mant,
*p++ = *string - '0';
} else {
if (!warned) {
/*!
*!float-toolong [on] too many digits in floating-point number
*! warns about too many digits in floating-point numbers.
*/
nasm_warn(WARN_FLOAT_TOOLONG|ERR_PASS2,
"floating-point constant significand contains "
"more than %i digits", MANT_DIGITS);
@ -833,19 +799,10 @@ int float_const(const char *str, int s, uint8_t *result, enum floatize ffmt)
mant[0] |= exponent << (LIMB_BITS-1 - fmt->exponent);
} else {
if (daz || is_zero(mant)) {
/*!
*!float-underflow [off] floating point underflow
*! warns about floating point underflow (a nonzero
*! constant rounded to zero.)
*/
nasm_warn(WARN_FLOAT_UNDERFLOW|ERR_PASS2,
"underflow in floating-point constant");
goto zero;
} else {
/*!
*!float-denorm [off] floating point denormal
*! warns about denormal floating point constants.
*/
nasm_warn(WARN_FLOAT_DENORM|ERR_PASS2,
"denormal floating-point constant");
}
@ -862,10 +819,6 @@ int float_const(const char *str, int s, uint8_t *result, enum floatize ffmt)
ieee_shr(mant, 1);
exponent++;
if (exponent >= (expmax << 1)-1) {
/*!
*!float-overflow [on] floating point overflow
*! warns about floating point underflow.
*/
nasm_warn(WARN_FLOAT_OVERFLOW|ERR_PASS2,
"overflow in floating-point constant");
type = FL_INFINITY;

View file

@ -1,35 +1,5 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 1996-2020 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ----------------------------------------------------------------------- */
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2020 The NASM Authors - All Rights Reserved */
/*
* floats.h header file for the floating-point constant module of

View file

@ -1,35 +1,5 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 2025 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ----------------------------------------------------------------------- */
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 2025 The NASM Authors - All Rights Reserved */
#include "compiler.h"
#include "nasm.h"

View file

@ -1,35 +1,5 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 1996-2025 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ----------------------------------------------------------------------- */
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2025 The NASM Authors - All Rights Reserved */
/*
* labels.c label handling for the Netwide Assembler
@ -240,6 +210,9 @@ static union label *find_label(const char *label, bool create, bool *created)
if (lptr || !create) {
if (created)
*created = false;
if (label_str)
nasm_free(label_str);
return lptr;
}
@ -292,14 +265,45 @@ static inline bool is_global(enum label_type type)
return type == LBL_GLOBAL || type == LBL_COMMON;
}
enum mangle_index {
LM_LPREFIX, /* Local variable prefix */
LM_LSUFFIX, /* Local variable suffix */
LM_GPREFIX, /* Global variable prefix */
LM_GSUFFIX /* GLobal variable suffix */
};
static const char *mangle_strings[] = {"", "", "", ""};
static bool mangle_string_set[ARRAY_SIZE(mangle_strings)];
/*
* Set a prefix or suffix
*/
void set_label_mangle(enum mangle_index which, const char *what)
void set_label_mangle(enum directive how, const char *what)
{
enum mangle_index which;
switch (how) {
case D_PREFIX:
case D_GPREFIX:
which = LM_GPREFIX;
break;
case D_SUFFIX:
case D_GSUFFIX:
case D_POSTFIX:
case D_GPOSTFIX:
which = LM_GSUFFIX;
break;
case D_LPREFIX:
which = LM_LPREFIX;
break;
case D_LSUFFIX:
case D_LPOSTFIX:
which = LM_LSUFFIX;
break;
default:
return;
}
if (mangle_string_set[which])
return; /* Once set, do not change */
@ -414,6 +418,7 @@ static bool declare_label_lptr(union label *lptr,
} else if (is_extern(oldtype) && is_global(type)) {
/* EXTERN or REQUIRED can be replaced with GLOBAL or COMMON */
lptr->defn.type = type;
lptr->defn.defined = 0;
/* Override special unconditionally */
if (special)
@ -525,12 +530,6 @@ void define_label(const char *label, int32_t segment,
nasm_nonfatal("label `%s' inconsistently redefined", lptr->defn.label);
noteflags = ERR_NONFATAL|ERR_HERE|ERR_NO_SEVERITY;
} else {
/*!
*!label-redef [off] label redefined to an identical value
*! warns if a label is defined more than once, but the
*! value is identical. It is an unconditional error to
*! define the same label more than once to \e{different} values.
*/
nasm_warn(WARN_LABEL_REDEF,
"info: label `%s' redefined to an identical value", lptr->defn.label);
noteflags = ERR_WARNING|ERR_HERE|ERR_NO_SEVERITY|WARN_LABEL_REDEF;
@ -541,19 +540,7 @@ void define_label(const char *label, int32_t segment,
nasm_error(noteflags, "info: label `%s' originally defined", lptr->defn.label);
src_set(saved_line, saved_fname);
} else if (changed && pass_final() && lptr->defn.type != LBL_SPECIAL) {
/*!
*!label-redef-late [err] label (re)defined during code generation
*! the value of a label changed during the final, code-generation
*! pass. This may be the result of strange use of the
*! preprocessor. This is very likely to produce incorrect code and
*! may end up being an unconditional error in a future
*! version of NASM.
*
* WARN_LABEL_LATE defaults to an error, as this should never
* actually happen. Just in case this is a backwards
* compatibility problem, still make it a warning so that the
* user can suppress or demote it.
*
/*
* Note: As a special case, LBL_SPECIAL symbols are allowed
* to be changed even during the last pass.
*/

View file

@ -1,35 +1,5 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 1996-2020 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ----------------------------------------------------------------------- */
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2020 The NASM Authors - All Rights Reserved */
/*
* listing.c listing file generator for the Netwide Assembler
@ -49,11 +19,25 @@
#define LIST_INDENT 40
#define LIST_HEXBIT 18
/*
* The options to enable by increasing levels of -L+ on the command line.
* Each string is inclusive of the previous level; there is no need to
* duplicate characters. "" *is* allowed to mean that a level should have
* no impact, e.g. because an option has been made obsolete or a level is
* reserved for future use.
*/
static const char * const list_plus_options[] = {
"bdefFmps", /* -L+ */
"ct", /* -L++ */
NULL
};
static const char xdigit[] = "0123456789ABCDEF";
#define HEX(a,b) (*(a)=xdigit[((b)>>4)&15],(a)[1]=xdigit[(b)&15]);
#define HEX(a,b) (*(a)=xdigit[((b)>>4)&15],(a)[1]=xdigit[(b)&15])
uint64_t list_options, active_list_options;
uint64_t list_options, active_list_options, cmdline_list_options;
bool user_nolist;
static char listline[LIST_MAX_LEN];
static bool listlinep;
@ -174,6 +158,7 @@ static void list_init(const char *fname)
list_errors = NULL;
listlevel = 0;
suppress = 0;
user_nolist = false;
}
static void list_out(int64_t offset, char *str)
@ -288,7 +273,7 @@ static void list_output(const struct out_data *data)
}
}
static void list_line(int type, int32_t lineno, const char *line)
static void list_line(enum list_type type, int32_t lineno, const char *line)
{
(void)type;
@ -307,20 +292,24 @@ static void list_line(int type, int32_t lineno, const char *line)
listlevel_e = listlevel;
}
static void list_uplevel(int type, int64_t size)
static void list_uplevel(enum list_type type, int64_t size)
{
if (!listfp)
return;
switch (type) {
case LIST_INCBIN:
suppress |= 1;
list_size(listoffset, "bin", size);
if (!list_option('c')) {
suppress |= 1;
list_size(listoffset, "bin", size);
}
break;
case LIST_TIMES:
suppress |= 2;
list_size(listoffset, "rep", size);
if (!list_option('t')) {
suppress |= 2;
list_size(listoffset, "rep", size);
}
break;
case LIST_INCLUDE:
@ -333,7 +322,7 @@ static void list_uplevel(int type, int64_t size)
}
}
static void list_downlevel(int type)
static void list_downlevel(enum list_type type)
{
if (!listfp)
return;
@ -377,36 +366,68 @@ static void list_set_offset(uint64_t offset)
listoffset = offset;
}
static void list_update_options(const char *str)
/*
* from_cmdline has the following effects:
* 1. It treats + as -L+... -> list_plus_options[] as opposed to a modifier;
* 2. It disallows the * modifier (= set to command line default);
* 3. It suppresses setting active_list_options (that will
* be done when list_init() is called.)
*
* As listing options are assumed non-critical, ignore errors
* to help forward compatibility.
*/
void list_update_options(const char *str, bool from_cmdline)
{
bool state = true;
unsigned char c;
uint64_t mask;
uint64_t setmask = LIST_ALL_OPTIONS_MASK;
uint64_t amask = from_cmdline ? 0 : setmask;
const char * const *cmdline_next_plus =
&list_plus_options[from_cmdline ? 0 : ARRAY_SIZE(list_plus_options)-1];
while ((c = *str++)) {
uint64_t mask = 0;
switch (c) {
case '+':
state = true;
if (*cmdline_next_plus)
list_update_options(*cmdline_next_plus++, true);
setmask = LIST_ALL_OPTIONS_MASK;
break;
case '-':
state = false;
setmask = 0;
break;
case '*':
if (!from_cmdline)
setmask = cmdline_list_options;
break;
case '!':
mask = LIST_ALL_OPTIONS_MASK;
break;
default:
mask = list_option_mask(c);
if (state)
list_options |= mask;
else
list_options &= ~mask;
break;
}
if (mask) {
list_options = (list_options & ~mask) | (setmask & mask);
active_list_options =
(active_list_options & ~mask) |
(setmask & amask & mask);
}
}
if (from_cmdline)
cmdline_list_options = list_options;
}
enum directive_result list_pragma(const struct pragma *pragma)
{
switch (pragma->opcode) {
case D_OPTIONS:
list_update_options(pragma->tail);
list_update_options(pragma->tail, false);
return DIRR_OK;
default:

View file

@ -1,35 +1,5 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 1996-2020 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ----------------------------------------------------------------------- */
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2020 The NASM Authors - All Rights Reserved */
/*
* listing.h header file for listing.c
@ -40,6 +10,21 @@
#include "nasm.h"
/* List options implied by -L+ */
#define LIST_PLUS_OPTIONS "bdefFmps"
/* Listing type values flags */
enum list_type {
/* Flags for lfmt->line() */
LIST_READ,
LIST_MACRO,
LIST_INFO,
/* Flags for lfmt->uplevel() */
LIST_INCLUDE,
LIST_INCBIN,
LIST_TIMES
};
/*
* List-file generators should look like this:
*/
@ -76,7 +61,7 @@ struct lfmt {
* If a line number is provided, print it; if the line number is
* -1 then use the same line number as the previous call.
*/
void (*line)(int type, int32_t lineno, const char *line);
void (*line)(enum list_type type, int32_t lineno, const char *line);
/*
* Called to change one of the various levelled mechanisms in the
@ -92,12 +77,12 @@ struct lfmt {
* macro, so anything under that level won't be expanded unless
* it includes another file.
*/
void (*uplevel)(int type, int64_t size);
void (*uplevel)(enum list_type type, int64_t size);
/*
* Reverse the effects of uplevel.
*/
void (*downlevel)(int type);
void (*downlevel)(enum list_type type);
/*
* Called on a warning or error, with the error message.
@ -123,7 +108,7 @@ extern bool user_nolist;
* These are simple bitmasks of ASCII-64 mapping directly to option
* letters.
*/
extern uint64_t list_options, active_list_options;
extern uint64_t list_options, active_list_options, cmdline_list_options;
/*
* This maps the characters a-z, A-Z and 0-9 onto a 64-bit bitmask.
@ -137,13 +122,10 @@ extern uint64_t list_options, active_list_options;
* This isn't particularly efficient code, but just about every
* instance of it should be fed a constant, so the entire function can
* be precomputed at compile time. The only cases where the full
* computation is needed is when parsing the -L option or %pragma list
* options, neither of which is in any way performance critical.
*
* The character + represents ALL listing options except -Lw (flush
* after every line.)
* computation is needed is in list_update_options(), which is not
* performance critical.
*/
static inline const_func uint64_t list_option_mask_val(unsigned char x)
static inline const_func uint64_t list_option_mask(unsigned char x)
{
if (x >= 'a') {
if (x > 'z')
@ -164,13 +146,7 @@ static inline const_func uint64_t list_option_mask_val(unsigned char x)
return UINT64_C(1) << x;
}
static inline const_func uint64_t list_option_mask(unsigned char x)
{
if (x == '+')
return ~(list_option_mask_val('w') | 3);
else
return list_option_mask_val(x);
}
#define LIST_ALL_OPTIONS_MASK (~UINT64_C(3))
/* Return true if the listing engine is active and a certain option is set. */
static inline pure_func bool list_option(unsigned char x)
@ -190,6 +166,9 @@ static inline pure_func bool list_active(void)
return (active_list_options & 1);
}
/* Change listing options */
void list_update_options(const char *str, bool from_cmdline);
/* Pragma handler */
enum directive_result list_pragma(const struct pragma *);

1214
asm/nasm.c

File diff suppressed because it is too large Load diff

View file

@ -1,35 +1,5 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 1996-2025 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ----------------------------------------------------------------------- */
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2025 The NASM Authors - All Rights Reserved */
/*
* parser.c source line parser for the Netwide Assembler
@ -330,14 +300,6 @@ static void mref_set_optype(operand *op)
flag = IP_REL;
if (!(globl.reldef & op->eaflags)) {
static int64_t pass_last_seen;
/*!
*!implicit-abs-deprecated [on] implicit DEFAULT ABS is deprecated
*!
*! warns that in a subsequent version of NASM, the 64-bit default
*! addressing form is likely to change from \c{DEFAULT ABS} to
*! \c{DEFAULT REL}. If absolute addressing is indeed intended, it is
*! strongly recommended to specify \c{DEFAULT ABS} explicitly.
*/
if (pass_count() != pass_last_seen) {
nasm_warn(WARN_IMPLICIT_ABS_DEPRECATED,
"implicit DEFAULT ABS is deprecated");
@ -755,6 +717,7 @@ insn *parse_line(char *buffer, insn *result, const int bits)
int opnum;
bool critical;
bool first;
bool colonless_label;
bool recover;
bool far_jmp_ok;
bool have_prefixes;
@ -764,6 +727,7 @@ insn *parse_line(char *buffer, insn *result, const int bits)
restart_parse:
first = true;
colonless_label = false;
stdscan_reset(buffer);
i = stdscan(NULL, &tokval);
@ -782,21 +746,17 @@ restart_parse:
if (i == TOKEN_ID || (insn_is_label && i == TOKEN_INSN)) {
/* there's a label here */
struct tokenval label = tokval;
first = false;
result->label = tokval.t_charptr;
i = stdscan(NULL, &tokval);
colonless_label = i != ':';
if (i == ':') { /* skip over the optional colon */
i = stdscan(NULL, &tokval);
} else if (i == 0) {
/*!
*!label-orphan [on] labels alone on lines without trailing \c{:}
*!=orphan-labels
*! warns about source lines which contain no instruction but define
*! a label without a trailing colon. This is most likely indicative
*! of a typo, but is technically correct NASM syntax (see \k{syntax}.)
*/
nasm_warn(WARN_LABEL_ORPHAN ,
"label alone on a line without a colon might be in error");
nasm_warn(WARN_LABEL_ORPHAN,
"label `%*s' alone on a line without a colon might be in error",
(int)label.t_len, label.t_start);
}
if (i != TOKEN_INSN || tokval.t_integer != I_EQU) {
/*
@ -864,7 +824,14 @@ restart_parse:
set_imm_flags(&result->oprs[0], result->opt);
}
} else if (!first) {
nasm_nonfatal("instruction expected, found `%.*s'",
/*
* What was meant to be an instruction may very well have
* been mistaken for a label here, so print out both, unless
* it is unambiguous.
*/
nasm_nonfatal("instruction expected, found `%s%s%.*s'",
colonless_label ? result->label : "",
colonless_label ? " " : "",
tokval.t_len, tokval.t_start);
} else if (!result->label) {
nasm_nonfatal("label, instruction or prefix expected at start of line, found `%.*s'",
@ -929,13 +896,6 @@ restart_parse:
/* DB et al */
result->operands = oper_num;
if (oper_num == 0)
/*!
*!db-empty [on] no operand for data declaration
*! warns about a \c{D}\e{x} declaration
*! with no operands, producing no output.
*! This is permitted, but often indicative of an error.
*! See \k{db}.
*/
nasm_warn(WARN_DB_EMPTY, "no operand for data declaration");
}
return result;
@ -1004,8 +964,10 @@ restart_parse:
while (i == TOKEN_SPECIAL || i == TOKEN_SIZE) {
switch (tokval.t_integer) {
case S_BYTE:
if (!setsize) /* we want to use only the first */
if (!setsize) { /* we want to use only the first */
result->opt |= OPTIM_NO_Jcc_RELAX | OPTIM_NO_JMP_RELAX;
op->type |= BITS8;
}
setsize = 1;
break;
case S_WORD:
@ -1054,9 +1016,12 @@ restart_parse:
op->type |= FAR;
break;
case S_NEAR:
/* This is not legacy behavior, even if it perhaps should be */
result->opt |= OPTIM_NO_Jcc_RELAX | OPTIM_NO_JMP_RELAX;
op->type |= NEAR;
break;
case S_SHORT:
result->opt |= OPTIM_NO_Jcc_RELAX | OPTIM_NO_JMP_RELAX;
op->type |= SHORT;
break;
case S_ABS:
@ -1141,7 +1106,7 @@ restart_parse:
* as if it had ended in a comma, but sets the COLON flag
* on the operand further down.
*/
} else if (mref || !far_jmp_ok) {
} else if (mref || (ok_reg && IS_SREG(value->type))) {
/* segment override? */
mref = true;
@ -1244,7 +1209,8 @@ restart_parse:
i = tokval.t_type;
}
if (!recover && i != 0 && i != ',') {
nasm_nonfatal("comma, decorator or end of line expected, got %d", i);
nasm_nonfatal("comma, decorator or end of line expected, got `%*s'",
(int)tokval.t_len, tokval.t_start);
recover = true;
}
} else { /* immediate operand */
@ -1289,6 +1255,7 @@ restart_parse:
if (!(eclass & ~(EC_RELOC | EC_UNKNOWN))) {
/* It is an immediate */
bool size_was_specified = false;
op->offset = reloc_value(value);
op->segment = reloc_seg(value);
op->wrt = reloc_wrt(value);
@ -1302,6 +1269,27 @@ restart_parse:
op->type |= IMM_NORMAL;
set_imm_flags(op, result->opt);
/*
* Catch a missing size specifier when dealing with a label -
* which might result in non-intentional handling of only part
* of the label's address instead of the whole value.
*/
for(int j = 0 ; j <= opnum ; j++)
size_was_specified |= !!(result->oprs[j].xsize & SIZE_MASK);
/*
* Raise a 'label operation missing size specifier' error when:
* 1. No size specifier was mentioned up to this point.
* 2. One of the operands is a memory reference.
* 3. The current operand is a label and not a simple immediate.
*/
if (!size_was_specified && (op->opflags & OPFLAG_FORWARD)) {
for(int j = 0 ; j <= opnum ; j++) {
if ((result->oprs[j].type & OPTYPE_MASK) == MEMORY)
nasm_fatal("size wasn't specified, some data may be omitted");
}
}
/*
* Special hack: if the previous operand was a colon
* immediate operand with an explicit size, and this
@ -1417,21 +1405,6 @@ restart_parse:
if (!opsize) {
op->type |= rs; /* For non-size-specific registers, permit size override */
} else if (opsize != rs) {
/*!
*!regsize [on] register size specification ignored
*!
*! warns about a register with implicit size (such as \c{EAX}, which is always 32 bits)
*! been given an explicit size specification which is inconsistent with the size
*! of the named register, e.g. \c{WORD EAX}. \c{DWORD EAX} or \c{WORD AX} are
*! permitted, and do not trigger this warning. Some registers which \e{do not} imply
*! a specific size, such as \c{K0}, may need this specification unless the instruction
*! itself implies the instruction size:
*!-
*! \c KMOVW K0,[foo] ; Permitted, KMOVW implies 16 bits
*! \c KMOV WORD K0,[foo] ; Permitted, WORD K0 specifies instruction size
*! \c KMOV K0,WORD [foo] ; Permitted, WORD [foo] specifies instruction size
*! \c KMOV K0,[foo] ; Not permitted, instruction size ambiguous
*/
nasm_warn(WARN_REGSIZE, "invalid register size specification ignored");
}
}

View file

@ -1,35 +1,5 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 1996-2009 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ----------------------------------------------------------------------- */
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2009 The NASM Authors - All Rights Reserved */
/*
* parser.h header file for the parser module of the Netwide

View file

@ -1,35 +1,5 @@
## --------------------------------------------------------------------------
##
## Copyright 1996-2025 The NASM Authors - All Rights Reserved
## See the file AUTHORS included with the NASM distribution for
## the specific copyright holders.
##
## Redistribution and use in source and binary forms, with or without
## modification, are permitted provided that the following
## conditions are met:
##
## * Redistributions of source code must retain the above copyright
## notice, this list of conditions and the following disclaimer.
## * Redistributions in binary form must reproduce the above
## copyright notice, this list of conditions and the following
## disclaimer in the documentation and/or other materials provided
## with the distribution.
##
## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
## CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
## INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
## MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
## DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
## NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
## LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
## HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
## EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
##
## --------------------------------------------------------------------------
# SPDX-License-Identifier: BSD-2-Clause
# Copyright 1996-2025 The NASM Authors - All Rights Reserved
#
# A * at the end indicates a condition; the list of conditions are

View file

@ -1,36 +1,6 @@
#!/usr/bin/perl
## --------------------------------------------------------------------------
##
## Copyright 1996-2025 The NASM Authors - All Rights Reserved
## See the file AUTHORS included with the NASM distribution for
## the specific copyright holders.
##
## Redistribution and use in source and binary forms, with or without
## modification, are permitted provided that the following
## conditions are met:
##
## * Redistributions of source code must retain the above copyright
## notice, this list of conditions and the following disclaimer.
## * Redistributions in binary form must reproduce the above
## copyright notice, this list of conditions and the following
## disclaimer in the documentation and/or other materials provided
## with the distribution.
##
## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
## CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
## INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
## MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
## DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
## NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
## LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
## HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
## EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
##
## --------------------------------------------------------------------------
# SPDX-License-Identifier: BSD-2-Clause
# Copyright 1996-2025 The NASM Authors - All Rights Reserved
#
# Produce pptok.c, pptok.h, pptok.ph and pptok.src from pptok.dat

View file

@ -1,35 +1,5 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 1996-2019 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ----------------------------------------------------------------------- */
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2019 The NASM Authors - All Rights Reserved */
/*
* Parse and handle [pragma] directives. The preprocessor handles
@ -192,22 +162,10 @@ found_it:
case DIRR_UNKNOWN:
switch (pragma.opcode) {
case D_none:
/*!
*!pragma-bad [off] malformed \c{%pragma}
*!=bad-pragma
*! warns about a malformed or otherwise unparsable
*! \c{%pragma} directive.
*/
nasm_warn(ERR_PASS2|WARN_PRAGMA_BAD,
"empty %%pragma %s", pragma.facility_name);
break;
default:
/*!
*!pragma-unknown [off] unknown \c{%pragma} facility or directive
*!=unknown-pragma
*! warns about an unknown \c{%pragma} directive.
*! This is not yet implemented for most cases.
*/
nasm_warn(ERR_PASS2|WARN_PRAGMA_UNKNOWN,
"unknown %%pragma %s %s",
pragma.facility_name, pragma.opname);
@ -235,21 +193,7 @@ found_it:
return rv;
}
/* This warning message is intended for future use */
/*!
*!pragma-na [off] \c{%pragma} not applicable to this compilation
*!=not-my-pragma
*! warns about a \c{%pragma} directive which is not applicable to
*! this particular assembly session. This is not yet implemented.
*/
/* Naked %pragma */
/*!
*!pragma-empty [off] empty \c{%pragma} directive
*! warns about a \c{%pragma} directive containing nothing.
*! This is treated identically to \c{%pragma ignore} except
*! for this optional warning.
*/
void process_pragma(char *str)
{
const struct pragma_facility *pf;
@ -272,7 +216,16 @@ void process_pragma(char *str)
else
pragma.opcode = directive_find(pragma.opname);
pragma.tail = nasm_trim_spaces(p);
/*
* This used to use nasm_trim_spaces, but that assumes a single word.
* Instead, strip spaces at either end of the directive, but allow
* interior spaces.
*/
p = nasm_zap_spaces_fwd(p);
pragma.tail = p;
p += strlen(p);
while (p > pragma.tail && nasm_isspace(p[-1]))
*--p = 0;
/*
* Search the global pragma namespaces. This is done
@ -334,17 +287,14 @@ static enum directive_result output_pragma_common(const struct pragma *pragma)
switch (pragma->opcode) {
case D_PREFIX:
case D_GPREFIX:
set_label_mangle(LM_GPREFIX, pragma->tail);
return DIRR_OK;
case D_SUFFIX:
case D_GSUFFIX:
set_label_mangle(LM_GSUFFIX, pragma->tail);
return DIRR_OK;
case D_POSTFIX:
case D_GPOSTFIX:
case D_LPREFIX:
set_label_mangle(LM_LPREFIX, pragma->tail);
return DIRR_OK;
case D_LSUFFIX:
set_label_mangle(LM_LSUFFIX, pragma->tail);
case D_LPOSTFIX:
set_label_mangle(pragma->opcode, pragma->tail);
return DIRR_OK;
default:
return DIRR_UNKNOWN;

View file

@ -1,35 +1,5 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 1996-2025 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ----------------------------------------------------------------------- */
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2025 The NASM Authors - All Rights Reserved */
/*
* preproc.c macro preprocessor for the Netwide Assembler
@ -178,23 +148,33 @@ static bool is_smac_param(enum token_type toktype)
}
/*
* This is tuned so struct Token should be 64 bytes on 64-bit
* systems and 32 bytes on 32-bit systems. It enables them
* to be nicely cache aligned, and the text to still be kept
* inline for nearly all tokens.
* This is tuned so struct Token should be 64 bytes on 64-bit systems
* and 32 bytes on 32-bit systems. It enables them to be nicely cache
* aligned, and the text to still be kept inline for nearly all
* tokens.
*
* We prohibit tokens of length > MAX_TEXT even though
* length here is an unsigned int; this avoids problems
* if the length is passed through an interface with type "int",
* and is absurdly large anyway.
* We prohibit tokens of length > MAX_TEXT even though length here is
* an unsigned int; this avoids problems if the length is passed
* through an interface with type "int", and is absurdly large anyway.
*
* Use INT_MAX >> 2 to try to at least try to avoid risking wraparound
* even in the fairly extreme case when "int" is incorrectly used and
* two lengths are added. That is still 512GB with a 32-bit int...
*
* Earlier versions of the source code incorrectly stated that
* examining the text string alone can be unconditionally valid. This
* is incorrect, as some token types strip parts of the string,
* e.g. indirect tokens.
*
* The pointer for out of line token strings are located at the end of
* the buffer to maximize the likelihood of incorrectly examining
* text.a or text.p.ptr giving a null-terminated empty string or a
* NULL pointer, respectively, rather than something more dangerous.
* It still not something that should happen.
*/
#define INLINE_TEXT (7*sizeof(char *)-sizeof(enum token_type)-sizeof(unsigned int)-1)
#define MAX_TEXT (INT_MAX-2)
#define INLINE_TEXT (7*sizeof(char *)-sizeof(enum token_type) \
-sizeof(unsigned int)-1)
#define MAX_TEXT (INT_MAX >> 2)
struct Token {
Token *next;
@ -965,17 +945,6 @@ static const char *pp_getenv(const Token *t, bool warn)
v = getenv(txt);
if (warn && !v) {
/*!
*!pp-environment [on] nonexistent environment variable
*!=environment
*! warns if a nonexistent environment variable
*! is accessed using the \c{%!} preprocessor
*! construct (see \k{getenv}.) Such environment
*! variables are treated as empty (with this
*! warning issued) starting in NASM 2.15;
*! earlier versions of NASM would treat this as
*! an error.
*/
nasm_warn(WARN_PP_ENVIRONMENT,
"nonexistent environment variable `%s'", txt);
v = "";
@ -1141,6 +1110,19 @@ static Token *cut_tlist(Token *t)
return nt;
}
/*
* Find the pointer to the end of a tlist. If the tlist is empty,
* return the incoming pointer.
*/
static Token **tlist_endptr(Token **tptr)
{
Token *t;
while ((t = *tptr))
tptr = &t->next;
return tptr;
}
/*
* Allocate a new MMacro. This does not claim a refcount; the appropriate
* get_mmacro() calls need to be added.
@ -1590,17 +1572,6 @@ static Token *tokenize(const char *line)
* nasm_skip_string()
*/
if (!*p) {
/*!
*!pp-open-brackets [on] unterminated \c{%[...]}
*! warns that a preprocessor \c{%[...]} construct
*! lacks the terminating \c{]} character.
*/
/*!
*!pp-open-braces [on] unterminated \c{%\{...\}}
*! warns that a preprocessor parameter
*! enclosed in braces \c{%\{...\}} lacks the
*! terminating \c{\}} character.
*/
nasm_warn(firstchar == '}' ?
WARN_PP_OPEN_BRACES : WARN_PP_OPEN_BRACKETS,
"unterminated %%%c...%c construct (missing `%c')",
@ -1660,12 +1631,6 @@ static Token *tokenize(const char *line)
if (toklen < 2) {
type = '%'; /* % operator */
if (unlikely(*line == '{')) {
/*!
*!pp-empty-braces [on] empty \c{%\{\}} construct
*! warns that an empty \c{%\{\}} was encountered.
*! This expands to a single \c{%} character, which
*! is normally the \c{%} arithmetic operator.
*/
nasm_warn(WARN_PP_EMPTY_BRACES,
"empty %%{} construct expands to the %% operator");
}
@ -1771,11 +1736,6 @@ static Token *tokenize(const char *line)
if (*p) {
p++;
} else {
/*!
*!pp-open-string [on] unterminated string
*! warns that a quoted string without a closing quotation
*! mark was encountered during preprocessing.
*/
nasm_warn(WARN_PP_OPEN_STRING,
"unterminated string (missing `%c')", quote);
type = TOKEN_ERRSTR;
@ -2031,6 +1991,9 @@ static Token *free_Token(Token *t)
nasm_assert(t->type != TOKEN_FREE);
next = t->next;
if (t->len > INLINE_TEXT)
nasm_free(t->text.p.ptr);
nasm_zero(*t);
t->type = TOKEN_FREE;
t->next = freeTokens;
@ -2061,6 +2024,8 @@ static inline Token *alloc_Token(void)
static Token *free_Token(Token *t)
{
Token *next = t->next;
if (t->len > INLINE_TEXT)
nasm_free(t->text.p.ptr);
nasm_free(t);
return next;
}
@ -2074,7 +2039,7 @@ static inline void free_Blocks(void)
static Token *do_delete_Token(Token **tp)
{
if (tp)
if (tp && *tp)
return *tp = free_Token(*tp);
else
return NULL;
@ -2319,12 +2284,11 @@ static int ppscan(void *private_data, struct tokenval *tokval)
txt = tok_text(tline);
tokval->t_start = txt;
tokval->t_len = tline->len;
tokval->t_charptr = (char *)txt; /* Fix this */
tokval->t_charptr = (char *)txt; /* Fix needing const removal here */
switch (tline->type) {
default:
break;
return tokval->t_type = tline->type;
case TOKEN_ID:
if (txt[0] == '$') {
@ -2402,13 +2366,6 @@ static bool pp_get_boolean_option(Token *tline, bool defval)
return true;
if (tokval.t_type) {
/*!
*!pp-trailing [on] trailing garbage ignored
*! warns that the preprocessor encountered additional text
*! where no such text was expected. This can
*! sometimes be the result of an incorrectly written expression,
*! or arguments that are inadvertently separated.
*/
nasm_warn(WARN_PP_TRAILING,
"trailing garbage after expression ignored");
}
@ -2812,19 +2769,20 @@ restart:
return false;
}
/* param should be a natural number [0; INT_MAX] */
static int read_param_count(const char *str)
{
int result;
int64_t result;
bool err;
result = readnum(str, &err);
if (result < 0 || result > INT_MAX) {
result = 0;
nasm_nonfatal("parameter count `%s' is out of bounds [%d; %d]",
str, 0, INT_MAX);
} else if (err)
if (err || result < 0) {
nasm_nonfatal("unable to parse parameter count `%s'", str);
return 0;
} else if (result > nasm_limit[LIMIT_PARAMS]) {
nasm_nonfatal("parameter count `%s' is too large (max %"PRId64")",
str, nasm_limit[LIMIT_PARAMS]);
return 0;
}
return result;
}
@ -2883,6 +2841,9 @@ static Token **count_mmac_params(Token *tline, int *nparamp, Token ***paramsp)
}
}
if (!t)
break; /* End of string, no comma */
/* Advance to the next comma */
maybe_comma = &t->next;
while (tok_isnt(t, ',')) {
@ -3220,7 +3181,7 @@ iftype:
t = tline = expand_smacro(tline);
while (tok_white(t) ||
(needtype == TOKEN_NUM && (tok_is(t, '-') | tok_is(t, '+'))))
(needtype == TOKEN_NUM && (tok_is(t, '-') || tok_is(t, '+'))))
t = t->next;
j = tok_is(t, needtype);
@ -3337,12 +3298,13 @@ list_smacro_def(enum preproc_token op, const Context *ctx, const SMacro *m)
if (m->nparam) {
/*
* Space for ( and either , or ) around each
* parameter, plus up to 5 flags + /ux
* Space for "(" at the beginning, then up to 5 flags "=&&!+"
* + "/ux" + terminal "," or ")" per parameter, plus the parameter
* name, if any.
*/
int i;
size += 1 + 8 * m->nparam;
size += 1 + (5+3+1) * m->nparam;
for (i = 0; i < m->nparam; i++)
size += m->params[i].name.len;
}
@ -3514,6 +3476,8 @@ static int parse_smacro_template(Token ***tpp, SMacro *tmpl)
cp = NULL;
break;
}
if (!cp) /* stop on invalid radix specifier */
break;
}
} else {
if (name)
@ -3639,17 +3603,6 @@ static SMacro *define_smacro(const char *mname, bool casesense,
if (casesense ^ smac->casesense) {
/*
*!pp-macro-def-case-single [on] single-line macro defined both case sensitive and insensitive
*!=macro-def-case-single
*! warns when a single-line macro is defined both case
*! sensitive and case insensitive.
*! The new macro
*! definition will override (shadow) the original one,
*! although the original macro is not deleted, and will
*! be re-exposed if the new macro is deleted with
*! \c{%undef}, or, if the original macro is the case
*! insensitive one, the macro call is done with a
*! different case.
*/
nasm_warn(WARN_PP_MACRO_DEF_CASE_SINGLE, "case %ssensitive definition of macro `%s' will shadow %ssensitive macro `%s'",
casesense ? "" : "in",
@ -3659,36 +3612,15 @@ static SMacro *define_smacro(const char *mname, bool casesense,
defined = false;
} else if ((!!nparam) ^ (!!smac->nparam)) {
/*
* Most recent versions of NASM considered this an error,
* so promote this warning to error by default.
*
*!pp-macro-def-param-single [err] single-line macro defined with and without parameters
*!=macro-def-param-single
*! warns if the same single-line macro is defined with and
*! without parameters.
*! The new macro
*! definition will override (shadow) the original one,
*! although the original macro is not deleted, and will
*! be re-exposed if the new macro is deleted with
*! \c{%undef}.
* The immediately previous versions of NASM considered
* this an error, so promote this warning is promoted to
* to error by default.
*/
nasm_warn(WARN_PP_MACRO_DEF_PARAM_SINGLE,
"macro `%s' defined both with and without parameters",
mname);
defined = false;
} else if (smac->nparam < nparam) {
/*
*!pp-macro-def-greedy-single [on] single-line macro
*!=macro-def-greedy-single
*! definition shadows greedy macro warns when a
*! single-line macro is defined which would match a
*! previously existing greedy definition. The new macro
*! definition will override (shadow) the original one,
*! although the original macro is not deleted, and will
*! be re-exposed if the new macro is deleted with
*! \c{%undef}, and will be invoked if called with a
*! parameter count that does not match the new definition.
*/
nasm_warn(WARN_PP_MACRO_DEF_GREEDY_SINGLE,
"defining macro `%s' shadows previous greedy definition",
mname);
@ -3877,12 +3809,6 @@ static bool parse_mmacro_spec(Token *tline, MMacro *def, const char *directive)
if (def->defaults && def->ndefs > def->nparam_max - def->nparam_min &&
!def->plus) {
/*
*!pp-macro-defaults [on] macros with more default than optional parameters
*!=macro-defaults
*! warns when a macro has more default parameters than optional parameters.
*! See \k{mlmacdef} for why might want to disable this warning.
*/
nasm_warn(WARN_PP_MACRO_DEFAULTS,
"too many default macro parameters in macro `%s'", def->name);
}
@ -4356,10 +4282,6 @@ static void user_error(enum preproc_token op, Token **tlinep)
severity = ERR_NOTE;
break;
case PP_WARNING:
/*!
*!user [on] \c{%warning} directives
*! controls output of \c{%warning} directives (see \k{pperror}).
*/
severity = ERR_WARNING|WARN_USER|ERR_PASS2;
break;
case PP_ERROR:
@ -4768,8 +4690,16 @@ static int do_directive(Token *tline, Token **output, bool suppressed)
/* Emulate legacy behavior */
do_clear(CLEAR_DEFINE|CLEAR_MMACRO, false);
} else {
while ((t = skip_white(t)) && t->type == TOKEN_ID) {
while (tok_is(t, TOKEN_ID)) {
const char *txt = tok_text(t);
/*
* Advance to the next token, skipping whitespace
* and optional comma separators.
*/
while ((t = skip_white(t->next)) && tok_is(t, ','))
;
if (!nasm_stricmp(txt, "all")) {
do_clear(CLEAR_ALL, context);
} else if (!nasm_stricmp(txt, "define") ||
@ -4800,6 +4730,7 @@ static int do_directive(Token *tline, Token **output, bool suppressed)
} else {
nasm_nonfatal("invalid option to %s: %s", dname, txt);
t = NULL;
break;
}
}
}
@ -4933,9 +4864,17 @@ static int do_directive(Token *tline, Token **output, bool suppressed)
break;
CASE_PP_IF:
if (istk->conds && !emitting(istk->conds->state))
if (suppressed || (istk->conds && !emitting(istk->conds->state))) {
/*
* Don't evaluate the actual condition inside of a dead
* expansion, because it is entirely valid for it to be
* syntactically broken at this point. There is no point,
* anyway: the output from all branches of this conditionals
* will be suppressed, and the only reason this is being
* processed at all is to look for nested conditionals.
*/
j = COND_NEVER;
else {
} else {
j = if_condition(tline->next, op, dname);
tline->next = NULL; /* it got freed */
}
@ -4963,12 +4902,6 @@ static int do_directive(Token *tline, Token **output, bool suppressed)
case COND_ELSE_TRUE:
case COND_ELSE_FALSE:
/*!
*!pp-else-elif [on] \c{%elif} after \c{%else}
*! warns that an \c{%elif}-type directive was encountered
*! after \c{%else} has already been encounted. As a result, the
*! content of the \c{%elif} will never be expanded.
*/
nasm_warn(WARN_PP_ELSE_ELIF|ERR_PP_PRECOND,
"`%s' after `%%else', ignoring content", dname);
istk->conds->state = COND_NEVER;
@ -5013,12 +4946,6 @@ static int do_directive(Token *tline, Token **output, bool suppressed)
case COND_ELSE_TRUE:
case COND_ELSE_FALSE:
/*!
*!pp-else-else [on] \c{%else} after \c{%else}
*! warns that a second \c{%else} clause was found for
*! the same \c{%if} statement. The content of this \c{%else}
*! clause will never be expanded.
*/
nasm_warn(WARN_PP_ELSE_ELSE|ERR_PP_PRECOND,
"`%s' after `%%else', ignoring content", dname);
istk->conds->state = COND_NEVER;
@ -5043,6 +4970,13 @@ static int do_directive(Token *tline, Token **output, bool suppressed)
break;
case PP_RMACRO:
{
op = PP_MACRO;
nasm_warn(WARN_PP_RESERVED,
"reserved directive `%s', treating as '%s'",
dname, pp_directives[op + !casesense]);
}
/* fall through */
case PP_MACRO:
{
MMacro *def;
@ -5051,8 +4985,10 @@ static int do_directive(Token *tline, Token **output, bool suppressed)
def = new_mmacro();
def->casesense = casesense;
#if 0
if (op == PP_RMACRO)
def->max_depth = nasm_limit[LIMIT_MACRO_LEVELS];
#endif
if (!parse_mmacro_spec(tline, def, dname)) {
free_mmacro(def);
goto done;
@ -5076,12 +5012,6 @@ static int do_directive(Token *tline, Token **output, bool suppressed)
|| defining->plus)
&& (defining->nparam_min <= mmac->nparam_max
|| mmac->plus)) {
/*!
*!pp-macro-redef-multi [on] redefining multi-line macro
*! warns that a multi-line macro is being redefined,
*! without first removing the old definition with
*! \c{%unmacro}.
*/
nasm_warn(WARN_PP_MACRO_REDEF_MULTI,
"redefining multi-line macro `%s'",
defining->name);
@ -5105,7 +5035,7 @@ static int do_directive(Token *tline, Token **output, bool suppressed)
pop_mstk(&defining->dstk, defining->dstk.mstk);
if (defining->refcnt != 1)
nasm_panic("defining->refcnt == %zu", defining->refcnt);
nasm_panic("defining->refcnt == %"PRIzu, defining->refcnt);
mmhead = (MMacro **) hash_findi_add(&mmacros, defining->name);
defining->next = *mmhead;
@ -5229,12 +5159,6 @@ static int do_directive(Token *tline, Token **output, bool suppressed)
dname, count, nasm_limit[LIMIT_REP]);
count = 0;
} else if (count < 0) {
/*!
*!pp-rep-negative [on] regative \c{%rep} count
*!=negative-rep
*! warns about a negative count given to the \c{%rep}
*! preprocessor directive.
*/
nasm_warn(ERR_PASS2|WARN_PP_REP_NEGATIVE,
"negative `%s' count: %"PRId64, dname, count);
count = 0;
@ -5300,7 +5224,8 @@ static int do_directive(Token *tline, Token **output, bool suppressed)
case PP_EXITREP:
{
MMacro *m = do_exit_macro(dname, false);
m->in_progress = 1; /* No more repeats */
if (m)
m->in_progress = 1; /* No more repeats */
break;
}
@ -6366,7 +6291,6 @@ static Token **parse_smacro_args(Token **tp, int *nparamp, const SMacro *m)
int brackets = 0;
int paren;
bool bracketed = false;
bool bad_bracket = false;
int i;
enum sparmflags flags;
const struct smac_param *mparm;
@ -6465,8 +6389,6 @@ static Token **parse_smacro_args(Token **tp, int *nparamp, const SMacro *m)
if (!skip) {
Token *tt;
bad_bracket |= bracketed && !brackets;
if (white) {
*pep = tt = new_White(NULL);
pep = &tt->next;
@ -6576,13 +6498,7 @@ static SMacro *expand_one_smacro(Token ***tpp)
*/
while (1) {
if (!m) {
/*!
*!pp-macro-params-single [on] single-line macro calls with wrong parameter count
*!=macro-params-single
*! warns about \i{single-line macros} being invoked
*! with the wrong number of parameters.
*/
nasm_warn(WARN_PP_MACRO_PARAMS_SINGLE|ERR_HOLD,
nasm_warn(WARN_PP_MACRO_PARAMS_SINGLE,
"single-line macro `%s' exists, "
"but not taking %d parameter%s",
mname, nparam, (nparam == 1) ? "" : "s");
@ -6803,7 +6719,8 @@ static MMacro *use_mmacro(MMacro *m, int *nparamp, Token ***paramsp)
if (m->in_progress > m->max_depth) {
if (m->max_depth > 0) {
/* Document this properly when recursive mmacros re-implemented */
nasm_warn(WARN_OTHER, "reached maximum recursion depth of %i",
nasm_warn(WARN_OTHER,
"reached maximum recursion depth of %"PRId32,
m->max_depth);
}
nasm_free(params);
@ -6971,22 +6888,6 @@ static MMacro *is_mmacro(Token * tline, int *nparamp, Token ***paramsp)
* To disable these insane legacy behaviors, use:
*
* %pragma preproc sane_empty_expansion yes
*
*!pp-macro-params-legacy [on] improperly calling multi-line macro for legacy support
*!=macro-params-legacy
*! warns about \i{multi-line macros} being invoked
*! with the wrong number of parameters, but for bug-compatibility
*! with NASM versions older than 2.15, NASM tried to fix up the
*! parameters to match the legacy behavior and call the macro anyway.
*! This can happen in certain cases where there are empty arguments
*! without braces, sometimes as a result of macro expansion.
*!-
*! The legacy behavior is quite strange and highly context-dependent,
*! and can be disabled with:
*!-
*! \c %pragma preproc sane_empty_expansion true
*!-
*! It is highly recommended to use this option in new code.
*/
if (!ppconf.sane_empty_expansion) {
if (!found) {
@ -7051,12 +6952,6 @@ static MMacro *is_mmacro(Token * tline, int *nparamp, Token ***paramsp)
/*
* After all that, we didn't find one with the right number of
* parameters. Issue a warning, and fail to expand the macro.
*!
*!pp-macro-params-multi [on] multi-line macro calls with wrong parameter count
*!=macro-params-multi
*! warns about \i{multi-line macros} being invoked
*! with the wrong number of parameters. See \k{mlmacover} for an
*! example of why you might want to disable this warning.
*/
if (found)
return found;
@ -7384,7 +7279,7 @@ static int expand_mmacro(Token * tline)
*/
nasm_newn(paramlen, nparam+1);
for (i = 1; (t = params[i]); i++) {
for (i = 1; i < nparam+1 && (t = params[i]); i++) {
bool braced = false;
int brace = 0;
int white = 0;
@ -7890,9 +7785,9 @@ stdmac_tok(const SMacro *s, Token **params, int nparams)
return reverse_tokens(tokenize(unquote_token_cstr(params[0])));
}
/* %cond() or %sel() */
/* %sel() */
static Token *
stdmac_cond_sel(const SMacro *s, Token **params, int nparams)
stdmac_sel(const SMacro *s, Token **params, int nparams)
{
int64_t which;
@ -7901,35 +7796,57 @@ stdmac_cond_sel(const SMacro *s, Token **params, int nparams)
*/
which = get_tok_num(params[0], NULL);
if (s->expandpvt.u) {
/* Booleanize (for %cond): true -> 1, false -> 2 (else) */
which = which ? 1 : 2;
if (which >= nparams) {
/* false, and no else clause */
return NULL;
}
} else {
/*!
*!pp-sel-range [on] \c{%sel()} argument out of range
*! warns that the \c{%sel()} preprocessor function was passed
*! a value less than 1 or larger than the number of available
*! arguments.
*/
if (unlikely(which < 1)) {
nasm_warn(WARN_PP_SEL_RANGE,
"%s(%"PRId64") is not a valid selector", s->name, which);
return NULL;
} else if (unlikely(which >= nparams)) {
nasm_warn(WARN_PP_SEL_RANGE,
"%s(%"PRId64") exceeds the number of arguments",
s->name, which);
return NULL;
}
if (unlikely(which < 1)) {
nasm_warn(WARN_PP_SEL_RANGE,
"%s(%"PRId64") is not a valid selector", s->name, which);
return NULL;
} else if (unlikely(which >= nparams)) {
nasm_warn(WARN_PP_SEL_RANGE,
"%s(%"PRId64") exceeds the number of arguments",
s->name, which);
return NULL;
}
return new_Token(NULL, tok_smac_param(which), "", 0);
}
/* %cond() */
static Token *
stdmac_cond(const SMacro *s, Token **params, int nparams)
{
int64_t which;
(void)s;
(void)params;
/*
* params[0] will have been generated by make_tok_num.
*/
which = get_tok_num(params[0], NULL);
/* Booleanize: true -> 1, false -> 2 (else) */
which = which ? 1 : 2;
if (which >= nparams) {
/* false, and no else clause */
return NULL;
}
return new_Token(NULL, tok_smac_param(which), "", 0);
}
/* %selbits() */
static Token *
stdmac_selbits(const SMacro *s, Token **params, int nparams)
{
int which = ilog2_32(globl.bits)-4;
(void)s;
(void)params;
if (nparams <= which)
which = nparams - 1;
return new_Token(NULL, tok_smac_param(which), "", 0);
}
/* %count() function */
static Token *
stdmac_count(const SMacro *s, Token **params, int nparams)
@ -8283,6 +8200,94 @@ stdmac_find(const SMacro *s, Token **params, int nparam)
return make_tok_num(NULL, found);
}
static Token *
stdmac_env(const SMacro *s, Token **params, int nparam)
{
const char *env;
(void)s;
env = pp_getenv(params[0], false);
if (!env) {
if (nparam > 1)
return new_Token(NULL, tok_smac_param(1), "", 0);
env = ""; /* No fallback argument */
}
return make_tok_qstr(NULL, env);
}
static Token *
stdmac_limit(const SMacro *s, Token **params, int nparam)
{
const char *which_str, *limit;
enum get_limit_which which;
int64_t val = 0;
(void)s;
(void)nparam;
which_str = unquote_token(params[1]);
if (!*which_str || !nasm_stricmp(which_str, "current")) {
which = GET_LIMIT_CURRENT;
} else if (!strcmp(which_str, "*") ||
!nasm_stricmp(which_str, "reset") ||
!nasm_stricmp(which_str, "init")) {
which = GET_LIMIT_INIT;
} else if (!nasm_stricmp(which_str, "default")) {
which = GET_LIMIT_DEFAULT;
} else if (!nasm_stricmp(which_str, "unlimited") ||
!nasm_stricmp(which_str, "maximum") ||
!nasm_stricmp(which_str, "max")) {
which = GET_LIMIT_MAX;
} else {
nasm_nonfatal("invalid second argument `%s' to %s()",
which_str, s->name);
goto err;
}
limit = unquote_token(params[0]);
if (!*limit || !nasm_stricmp(limit, "unlimited"))
val = LIMIT_MAX_VAL;
else
val = nasm_get_limit(limit, which);
err:
return make_tok_num(NULL, val);
}
/*
* Given the currently default or command-line default listing options
*/
static Token *
get_list_options(uint64_t optmask)
{
static const char optchars[63] =
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
char optbuf[65], *p;
unsigned int i;
p = optbuf;
for (i = 0; i < 62; i++) {
if (optmask & 4)
*p++ = optchars[i];
optmask >>= 1;
}
*p = '\0';
return make_tok_qstr_len(NULL, optbuf, p-optbuf);
}
static Token *
stdmac_list_options(const SMacro *s, Token **params, int nparam)
{
(void)s;
(void)params;
(void)nparam;
return get_list_options(active_list_options);
}
/*
* Wrapper around define_smacro() which also checks to see if it is
* a preprocessor directive, so that pp_op_may_be_function[] needs to
@ -8321,6 +8326,7 @@ static void pp_add_magic_simple(void)
{ "__?BITS?__", true, 0, 0, stdmac_bits },
{ "__?PTR?__", true, 0, 0, stdmac_ptr },
{ "__?DEFAULT?__", true, 0, 0, stdmac_default },
{ "__?LIST_OPTIONS?__", true, 0, 0, stdmac_list_options },
{ "%abs", false, 1, SPARM_EVAL, stdmac_abs },
{ "%chr", false, 1, SPARM_EVAL|SPARM_OPTIONAL|SPARM_VARADIC, stdmac_chr },
{ "%count", false, 1, SPARM_VARADIC, stdmac_count },
@ -8331,6 +8337,7 @@ static void pp_add_magic_simple(void)
{ "%null", false, 1, SPARM_GREEDY, stdmac_null },
{ "%pathsearch", false, 1, SPARM_PLAIN, stdmac_pathsearch },
{ "%realpath", false, 1, SPARM_PLAIN, stdmac_realpath },
{ "%selbits", false, 1, SPARM_PLAIN|SPARM_VARADIC, stdmac_selbits },
{ "%str", false, 1, SPARM_GREEDY|SPARM_STR, stdmac_join },
{ "%strcat", false, 1, SPARM_STR|SPARM_CONDQUOTE|SPARM_VARADIC, stdmac_strcat },
{ "%strlen", false, 1, SPARM_STR|SPARM_CONDQUOTE, stdmac_strlen },
@ -8426,15 +8433,16 @@ static void pp_add_magic_miscfunc(void)
/* %sel() function */
nasm_zero(tmpl);
tmpl.nparam = 2;
tmpl.expand = stdmac_cond_sel;
tmpl.expand = stdmac_sel;
nasm_newn(tmpl.params, tmpl.nparam);
tmpl.params[0].flags = SPARM_EVAL;
tmpl.params[1].flags = SPARM_VARADIC;
define_magic("%sel", false, &tmpl);
/* %cond() function, a variation on %sel */
/* %cond() function */
nasm_zero(tmpl);
tmpl.nparam = 3;
tmpl.expandpvt.u = 1; /* Booleanize */
tmpl.expand = stdmac_cond;
nasm_newn(tmpl.params, tmpl.nparam);
tmpl.params[0].flags = SPARM_EVAL;
tmpl.params[1].flags = 0;
@ -8490,6 +8498,29 @@ static void pp_add_magic_miscfunc(void)
tmpl.params[1].def = make_tok_qstr_len(NULL, "", 0);
define_magic("%b2hs", false, &tmpl);
/* %limit() function */
nasm_zero(tmpl);
tmpl.nparam = 2;
tmpl.expand = stdmac_limit;
tmpl.recursive = true;
nasm_newn(tmpl.params, tmpl.nparam);
tmpl.params[0].flags = SPARM_STR|SPARM_CONDQUOTE;
tmpl.params[1].flags = SPARM_STR|SPARM_CONDQUOTE|SPARM_OPTIONAL;
define_magic("%limit", false, &tmpl);
/* %env() function */
for (i = 1; i <= 2; i++) {
nasm_zero(tmpl);
tmpl.nparam = i;
tmpl.expand = stdmac_env;
tmpl.recursive = true;
nasm_newn(tmpl.params, tmpl.nparam);
tmpl.params[0].flags = SPARM_STR|SPARM_CONDQUOTE;
if (i > 1)
tmpl.params[1].flags = SPARM_GREEDY;
define_magic("%env", false, &tmpl);
}
/* %find[i]() functions */
for (i = 0; i < 2; i++) {
static const char * const names[] = { "%findi", "%find" };
@ -8539,6 +8570,26 @@ static void pp_start_stdmac(void)
}
}
static void pp_add_limits_stdmac(void)
{
int i;
Token *t = NULL;
for (i = LIMIT_MAX-1; i > 0; i--) {
t = make_tok_qstr(t, nasm_limit_name(i));
t = make_tok_char(t, ',');
}
t = make_tok_qstr(t, nasm_limit_name(0));
define_smacro("__?NASM_LIMITS?__", true, t, NULL);
}
static void pp_add_list_options_default_stdmac(void)
{
define_smacro("__?LIST_OPTIONS_DEFAULT?__", true,
get_list_options(cmdline_list_options), NULL);
}
static void pp_reset_stdmac(enum preproc_mode mode)
{
int apass;
@ -8554,6 +8605,9 @@ static void pp_reset_stdmac(enum preproc_mode mode)
pp_add_stdmac(&nasm_stdmac_version);
pp_add_stdmac(ofmt->stdmac);
pp_add_limits_stdmac();
pp_add_list_options_default_stdmac();
do_predef = true;
/*
@ -8584,7 +8638,7 @@ static void pp_reset_stdmac(enum preproc_mode mode)
define_smacro("__?PASS?__", true, make_tok_num(NULL, apass), NULL);
}
void pp_reset(const char *file, enum preproc_mode mode,
void pp_reset(const char *file, char const* mapped_fname, enum preproc_mode mode,
struct strlist *dep_list)
{
cstk = NULL;
@ -8623,7 +8677,7 @@ void pp_reset(const char *file, enum preproc_mode mode,
nasm_fatalf(ERR_NOFILE, "unable to open input file `%s'%s%s",
file, errno ? " " : "", errno ? strerror(errno) : "");
}
src_set(0, file);
src_set(0, mapped_fname);
istk->where = src_where();
istk->lineinc = 1;
@ -8646,6 +8700,36 @@ void pp_init(enum preproc_opt opt)
nasm_newn(use_loaded, use_package_count);
}
static Include *pop_include_stack(void)
{
Include *i = istk;
if (i->fp)
fclose(i->fp);
if (i->conds) {
/*
* This should never happen for a builtin macro package,
* but if it does, at least get an error message out...
*/
nasm_fatal("expected `%%endif' before end of %s",
i->fp ? "file" : "macro package");
}
istk = i->next;
if (!i->nolist)
lfmt->downlevel(LIST_INCLUDE);
if (!i->noline) {
struct src_location whereto
= istk ? istk->where : src_nowhere();
if (ppdbg & PDBG_INCLUDE)
dfmt->debug_include(false, whereto, i->where);
src_update(whereto);
}
return i;
}
/*
* Get a line of tokens. If we popped the macro expansion/include stack,
* we return a pointer to the dummy token tok_pop; at that point if
@ -8813,25 +8897,8 @@ static Token *pp_tokline(void)
/*
* The current file/input has ended; work down the istk
*/
Include *i = istk;
Include *i = pop_include_stack();
if (i->fp)
fclose(i->fp);
if (i->conds)
nasm_fatal("expected `%%endif' before end of file");
istk = i->next;
if (!i->nolist)
lfmt->downlevel(LIST_INCLUDE);
if (!i->noline) {
struct src_location whereto
= istk ? istk->where : src_nowhere();
if (ppdbg & PDBG_INCLUDE)
dfmt->debug_include(false, whereto, i->where);
if (istk)
src_update(istk->where);
}
put_mmacro(&i->mstk.mstk);
put_mmacro(&i->mstk.mmac);
@ -8946,10 +9013,19 @@ void pp_cleanup_pass(void)
{
if (defining) {
if (defining->name) {
nasm_nonfatal("end of file while still defining macro `%s'",
nasm_nonfatal("end of input while still defining macro `%s'",
defining->name);
} else {
nasm_nonfatal("end of file while still in %%rep");
nasm_nonfatal("end of input while still in %%rep");
}
if (defining->refcnt != 0)
{
/* This can happen if a macro is ill formed without a correct ending
* and the macro is still referenced.
* In this case, we just set the refcnt to 0 to avoid a memory leak.
*/
defining->refcnt = 0;
}
free_mmacro(defining);
@ -8959,19 +9035,8 @@ void pp_cleanup_pass(void)
while (cstk)
ctx_pop();
free_macros();
while (istk) {
Include *i = istk;
istk = istk->next;
fclose(i->fp);
if (!istk && (ppdbg & PDBG_INCLUDE)) {
/* Signal closing the top-level input file */
dfmt->debug_include(false, src_nowhere(), i->where);
}
nasm_free(i);
}
while (cstk)
ctx_pop();
src_set_fname(NULL);
while (istk)
nasm_free(pop_include_stack());
if (ppdbg & PDBG_MMACROS)
debug_macro_output();
@ -9048,13 +9113,17 @@ void pp_pre_undefine(char *definition)
/* Insert an early preprocessor command that doesn't need special handling */
void pp_pre_command(const char *what, char *string)
{
Token *def, *space;
Token *def;
Line *l;
def = tokenize(string);
if (what) {
space = new_White(def);
def = new_Token(space, TOKEN_PREPROC_ID, what, 0);
Token *wt = tokenize(what);
Token **tailp = tlist_endptr(&wt);
*tailp = new_White(def);
def = wt;
}
nasm_new(l);
@ -9126,7 +9195,7 @@ make_tok_num_radix(Token *next, int64_t val, char radix, bool uns)
upper = !(radix & 0x20);
}
p += numstr(p, 64, uval, -1, base, upper);
p += numstr(p, sizeof(numbuf)-2, uval, -1, base, upper);
next = new_Token(next, TOKEN_NUM, numbuf, p - numbuf);
if (minus)

View file

@ -1,35 +1,5 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 1996-2025 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ----------------------------------------------------------------------- */
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2025 The NASM Authors - All Rights Reserved */
/*
* preproc.h header file for preproc.c

View file

@ -1,35 +1,5 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 1996-2020 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ----------------------------------------------------------------------- */
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2020 The NASM Authors - All Rights Reserved */
/*
* quote.c
@ -299,36 +269,35 @@ char *nasm_quote_cstr(const char *str, size_t *lenp)
* to indicate the lead marker of a quoted string. If it is '\"', then
* '`' is not a special character at all.
*/
enum unq_state {
st_start,
st_backslash,
st_byte, /* Byte numeric sequence */
st_ucs, /* \u or \U */
st_ctrl, /* \c */
st_done
};
size_t nasm_unquote_anystr(char *str, char **ep, const uint32_t badctl,
const char qstart)
{
unsigned char bq;
const unsigned char *p;
const unsigned char *escp = NULL;
unsigned char *q;
const unsigned char bq = *str;
const unsigned char *p = (unsigned char *)str;
unsigned char *q = (unsigned char *)str;
unsigned char c;
uint32_t ctlmask = 0; /* Mask of control characters seen */
enum unq_state {
st_start,
st_backslash,
st_hex,
st_oct,
st_ucs,
st_done
} state;
int ndig = 0;
uint32_t nval = 0;
p = q = (unsigned char *)str;
bq = *p++;
if (!bq)
return 0;
if (bq == (unsigned char)qstart) {
/* `...` string */
state = st_start;
/* `...` string or "..." with C unquoting */
enum unq_state state = st_start;
unsigned int base = 0; /* Base of numeric escape sequence */
uint64_t nval = 0; /* Accumulated value of numeric sequence */
unsigned int v;
int ndig = 0; /* Max digits of numeric sequence */
/* ndig < 0 means braced sequence */
const unsigned char *escp = NULL; /* Pointer to immediately after \ */
p++; /* Skip initial quote */
while (state != st_done) {
c = *p++;
@ -336,17 +305,18 @@ size_t nasm_unquote_anystr(char *str, char **ep, const uint32_t badctl,
case st_start:
if (c == '\\') {
state = st_backslash;
} else if ((c == '\0') | (c == bq)) {
} else if (c == '\0' || c == bq) {
state = st_done;
} else {
EMIT(c);
}
break;
break;
case st_backslash:
state = st_start;
escp = p; /* Beginning of argument sequence */
escp = p-1;
nval = 0;
switch (c) {
case 'a':
nval = 7;
@ -369,22 +339,33 @@ size_t nasm_unquote_anystr(char *str, char **ep, const uint32_t badctl,
case 't':
nval = 9;
break;
case '^':
state = st_ctrl;
break;
case 'u':
state = st_ucs;
base = 16;
ndig = 4;
break;
goto check_brace;
case 'U':
state = st_ucs;
base = 16;
ndig = 8;
break;
goto check_brace;
case 'v':
nval = 11;
break;
case 'x':
case 'X':
state = st_hex;
state = st_byte;
base = 16;
ndig = 2;
break;
goto check_brace;
case 'd': /* NASM extension: \d = decimal */
state = st_byte;
base = 10;
ndig = 3;
goto check_brace;
case '0':
case '1':
case '2':
@ -393,10 +374,19 @@ size_t nasm_unquote_anystr(char *str, char **ep, const uint32_t badctl,
case '5':
case '6':
case '7':
state = st_oct;
ndig = 2; /* Up to two more digits */
nval = c - '0';
break;
/* Back up both p and escp, as if there had been an "o" */
p = escp--;
/* fall through */
case 'o':
state = st_byte;
ndig = 3;
base = 8;
check_brace: /* Is this the start of a braced sequence? */
if (*p == '{') {
p++; /* Skip brace */
ndig = -1;
}
break;
case '\0':
nval = '\\';
p--; /* Reprocess; terminates string */
@ -409,31 +399,24 @@ size_t nasm_unquote_anystr(char *str, char **ep, const uint32_t badctl,
EMIT(nval);
break;
case st_oct:
if (c >= '0' && c <= '7') {
nval = (nval << 3) + (c - '0');
if (--ndig)
break; /* Might have more digits */
} else {
p--; /* Process this character again */
}
EMIT(nval);
state = st_start;
break;
case st_hex:
case st_byte:
case st_ucs:
if (nasm_isxdigit(c)) {
nval = (nval << 4) + numvalue(c);
if ((v = numvalue_chk(c)) < base) {
nval = (nval * base) + v;
if (--ndig)
break; /* Might have more digits */
break; /* Continue processing number, no output */
} else if (ndig < 0) {
/* End of braced sequence */
if (unlikely(c != '}'))
goto rewind;
} else {
p--; /* Process this character again */
p--; /* Reprocess terminating character */
if (unlikely(p == escp+1))
goto rewind; /* No digits at all received */
}
if (unlikely(p <= escp))
EMIT(escp[-1]);
else if (state == st_ucs)
/* Emit the output */
if (state == st_ucs)
EMIT_UTF8(nval);
else
EMIT(nval);
@ -441,6 +424,23 @@ size_t nasm_unquote_anystr(char *str, char **ep, const uint32_t badctl,
state = st_start;
break;
case st_ctrl:
if (!c)
goto rewind;
else if (c == '?')
c = 0177; /* DEL */
else
c &= 0x9f; /* Any thing else */
EMIT(c);
state = st_start;
break;
/* Rewind an entire sequence as invalid */
rewind:
p = escp; /* Start over at character following \ */
state = st_start;
break;
default:
panic();
}
@ -451,10 +451,11 @@ size_t nasm_unquote_anystr(char *str, char **ep, const uint32_t badctl,
* * any kind, including collapsing double quote marks.)
* We obviously can't get here if qstart == '\"'.
*/
while ((c = *p++) && (c != bq))
p++; /* Skip initial quote */
while ((c = *p++) && c != bq)
EMIT(c);
} else {
/* Not a quoted string, just return the input... */
/* Not a quoted string, just return the input */
while ((c = *p++))
EMIT(c);
}
@ -465,8 +466,11 @@ size_t nasm_unquote_anystr(char *str, char **ep, const uint32_t badctl,
if (ctlmask & badctl)
nasm_nonfatal("control character in string not allowed here");
if (ep)
if (ep) {
/* Point at the terminating character */
*ep = (char *)p - 1;
}
return (char *)q - str;
}
#undef EMIT
@ -501,11 +505,7 @@ char *nasm_skip_string(const char *str)
char bq;
const char *p;
char c;
enum unq_state {
st_start,
st_backslash,
st_done
} state;
enum unq_state state;
bq = str[0];
p = str+1;
@ -539,13 +539,20 @@ char *nasm_skip_string(const char *str)
case st_backslash:
/*
* Note: for the purpose of finding the end of the string,
* all successor states to st_backslash are functionally
* equivalent to st_start, since either a backslash or
* a backquote will force a return to the st_start state,
* and any possible multi-character state will terminate
* for any non-alphanumeric character.
* Note: for the purpose of finding the end of the
* string, all successor states to st_backslash except
* st_ctrl are functionally equivalent to st_start,
* since either a backslash or a backquote will force
* a return to the st_start state, and any possible
* multi-character state will terminate for any
* non-alphanumeric character.
*
* This state is necessary to prevent \` and \^` from
* being treated as a terminator, or \^\ from being treated
* as an escape (\^\` *is* an end of string terminator.)
*/
if (c == '^')
c = *p++;
state = c ? st_start : st_done;
break;

View file

@ -1,35 +1,5 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 1996-2009 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ----------------------------------------------------------------------- */
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2009 The NASM Authors - All Rights Reserved */
#ifndef NASM_QUOTE_H
#define NASM_QUOTE_H
@ -58,4 +28,3 @@ char *nasm_skip_string(const char *str);
#define STR_NASM '`'
#endif /* NASM_QUOTE_H */

View file

@ -1,35 +1,5 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 1996-2016 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ----------------------------------------------------------------------- */
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2016 The NASM Authors - All Rights Reserved */
/*
* rdstrnum.c

View file

@ -1,35 +1,5 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 1996-2018 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ----------------------------------------------------------------------- */
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2018 The NASM Authors - All Rights Reserved */
/*
* nasmlib.c library routines for the Netwide Assembler

View file

@ -1,35 +1,5 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 1996-2020 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ----------------------------------------------------------------------- */
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2020 The NASM Authors - All Rights Reserved */
/*
* srcfile.c - keep track of the current position in the input stream.

View file

@ -1,35 +1,5 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 1996-2020 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ----------------------------------------------------------------------- */
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2020 The NASM Authors - All Rights Reserved */
/*
* These functions are used to keep track of the source code file and name.

View file

@ -1,35 +1,5 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 1996-2024 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ----------------------------------------------------------------------- */
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2024 The NASM Authors - All Rights Reserved */
#include "compiler.h"
@ -348,15 +318,6 @@ static int stdscan_token(struct tokenval *tv)
int token_type = nasm_token_hash(tv->t_charptr, tv);
if (unlikely(tv->t_flag & TFLAG_WARN)) {
/*! ptr [on] non-NASM keyword used in other assemblers
*! warns about keywords used in other assemblers that
*! might indicate a mistake in the source code.
*! Currently only the MASM \c{PTR} keyword is
*! recognized. If (limited) MASM compatibility is
*! desired, the \c{%use masm} macro package is
*! available, see \k{pkg_masm}; however, carefully note
*! the caveats listed.
*/
nasm_warn(WARN_PTR, "`%s' is not a NASM keyword",
tv->t_charptr);
}

View file

@ -1,35 +1,5 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 1996-2009 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ----------------------------------------------------------------------- */
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2009 The NASM Authors - All Rights Reserved */
/*
* stdscan.h header file for stdscan.c

View file

@ -1,35 +1,5 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 1996-2009 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ----------------------------------------------------------------------- */
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2009 The NASM Authors - All Rights Reserved */
/*
* strfunc.c

View file

@ -1,35 +1,5 @@
## --------------------------------------------------------------------------
##
## Copyright 1996-2025 The NASM Authors - All Rights Reserved
## See the file AUTHORS included with the NASM distribution for
## the specific copyright holders.
##
## Redistribution and use in source and binary forms, with or without
## modification, are permitted provided that the following
## conditions are met:
##
## * Redistributions of source code must retain the above copyright
## notice, this list of conditions and the following disclaimer.
## * Redistributions in binary form must reproduce the above
## copyright notice, this list of conditions and the following
## disclaimer in the documentation and/or other materials provided
## with the distribution.
##
## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
## CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
## INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
## MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
## DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
## NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
## LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
## HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
## EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
##
## --------------------------------------------------------------------------
# SPDX-License-Identifier: BSD-2-Clause
# Copyright 1996-2025 The NASM Authors - All Rights Reserved
# The token parameters are in the order:
# TOKEN_TYPE, t_inttwo, t_flags, t_integer
@ -190,6 +160,10 @@ dfv=zf
dfv=sf
dfv=of
# cf == pf
% TOKEN_BRCCONST, IF_DFV, TFLAG_BRC | TFLAG_ORBIT, DFV_CF
dfv=pf
# Multi-character operators. Used in ppscan().
% TOKEN_SHR, 0, 0, 0
>>

View file

@ -1,36 +1,6 @@
#!/usr/bin/perl
## --------------------------------------------------------------------------
##
## Copyright 1996-2020 The NASM Authors - All Rights Reserved
## See the file AUTHORS included with the NASM distribution for
## the specific copyright holders.
##
## Redistribution and use in source and binary forms, with or without
## modification, are permitted provided that the following
## conditions are met:
##
## * Redistributions of source code must retain the above copyright
## notice, this list of conditions and the following disclaimer.
## * Redistributions in binary form must reproduce the above
## copyright notice, this list of conditions and the following
## disclaimer in the documentation and/or other materials provided
## with the distribution.
##
## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
## CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
## INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
## MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
## DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
## NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
## LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
## HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
## EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
##
## --------------------------------------------------------------------------
# SPDX-License-Identifier: BSD-2-Clause
# Copyright 1996-2020 The NASM Authors - All Rights Reserved
#
# Generate a perfect hash for token parsing

View file

@ -1,35 +1,5 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 2025 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ----------------------------------------------------------------------- */
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 2025 The NASM Authors - All Rights Reserved */
/*
* This needs to be in a separate file because zlib.h conflicts
@ -57,7 +27,7 @@ static void nasm_z_free(void *opaque, void *ptr)
nasm_free(ptr);
}
char *uncompress_stdmac(const macros_t *sm)
char *uncompress_stdmac(macros_t *sm)
{
z_stream zs;
void *buf = nasm_malloc(sm->dsize);
@ -70,7 +40,7 @@ char *uncompress_stdmac(const macros_t *sm)
zs.zalloc = nasm_z_alloc;
zs.zfree = nasm_z_free;
if (inflateInit2(&zs, 0) != Z_OK)
if (inflateInit2(&zs, 15) != Z_OK)
panic();
if (inflate(&zs, Z_FINISH) != Z_STREAM_END)

445
asm/warnings.dat Normal file
View file

@ -0,0 +1,445 @@
all [group] all possible warnings
\c{all} is an group alias for \e{all} warning classes. Thus, \c{-w+all}
enables all available warnings, and \c{-w-all} disables warnings
entirely (since NASM 2.13).
db-empty [on] no operand for data declaration
Warns about a \c{D}\e{x} declaration
with no operands, producing no output.
This is permitted, but often indicative of an error.
See \k{db}.
directive-garbage-eol [err] garbage after directive
Text was found after a directive. This is a warning so it can be
suppressed, because previous versions of NASM did not check for
this condition.
ea-absolute [on] absolute address cannot be RIP-relative
Warns that an address that is inherently absolute cannot
be generated with RIP-relative encoding using \c{REL},
see \k{default-rel}.
ea-dispsize [on] displacement size ignored on absolute address
Warns that NASM does not support generating displacements for
inherently absolute addresses that do not match the address size
of the instruction.
float-denorm [off] floating point denormal
Warns about denormal floating point constants.
float-overflow [on] floating point overflow
Warns about floating point underflow.
float-toolong [on] too many digits in floating-point number
Warns about too many digits in floating-point numbers.
float-underflow [off] floating point underflow
Warns about floating point underflow (a nonzero
constant rounded to zero.)
forward [on] forward reference may have unpredictable results
Warns that a forward reference is used which may have
unpredictable results, notably in a \c{RESB}-type
pseudo-instruction. These would be \i\e{critical
expressions} (see \k{crit}) but are permitted in a
handful of cases for compatibility with older
versions of NASM. This warning should be treated as a
severe programming error as the code could break at
any time for any number of reasons.
implicit-abs-deprecated [on] implicit DEFAULT ABS is deprecated
Warns that in a future version of NASM, the 64-bit default
addressing form is likely to change from \c{DEFAULT ABS} to
\c{DEFAULT REL}. If absolute addressing is indeed intended, it is
strongly recommended to specify \c{DEFAULT ABS} explicitly.
label-orphan [on] labels alone on lines without trailing \c{:}
=orphan-labels
Warns about source lines which contain no instruction but define
a label without a trailing colon. This is most likely indicative
of a typo, but is technically correct NASM syntax (see \k{syntax}.)
label-redef [off] label redefined to an identical value
Warns if a label is defined more than once, but the
value is identical. It is an unconditional error to
define the same label more than once to \e{different} values.
#
# label-redef-late defaults to an error, as this should never
# actually happen. Just in case this is a backwards
# compatibility problem, still make it a warning so that the
# user can suppress or demote it.
#
label-redef-late [err] label (re)defined during code generation
The value of a label changed during the final, code-generation
pass. This may be the result of strange use of the
preprocessor. This is very likely to produce incorrect code and
may end up being an unconditional error in a future
version of NASM.
number-deprecated-hex [on] $ prefix for hexadecimal is deprecated
Warns that the \c{$} prefix for hexadecimal numbers is
deprecated, due to the syntactic conflict with \c{$} used
as a symbol escape prefix. This syntax may be disabled by
default in a future version of NASM. Replace \c{$} with \c{0x}
to ensure compatibility with future versions.
number-overflow [on] numeric constant does not fit
Covers warnings about numeric constants which
don't fit in 64 bits.
obsolete-nop [on] instruction obsolete and is a noop on the target CPU
Warns for an instruction which has been removed
from the architecture, but has been architecturally
defined to be a noop for future CPUs.
obsolete-removed [on] instruction obsolete and removed on the target CPU
Warns for an instruction which has been removed
from the architecture, and is no longer included
in the CPU definition given in the \c{[CPU]}
directive, for example \c{POP CS}, the opcode for
which, \c{0Fh}, instead is an opcode prefix on
CPUs newer than the first generation 8086.
obsolete-valid [on] instruction obsolete but valid on the target CPU
Warns for an instruction which has been removed
from the architecture, but is still valid on the
specific CPU given in the \c{CPU} directive. Code
using these instructions is most likely not
forward compatible.
other [on] any warning not assigned to a specific warning class
Specifies any warning not included in any specific warning class.
phase [off] phase error during stabilization
Warns about symbols having changed values during
the second-to-last assembly pass. This is not
inherently fatal, but may be a source of bugs.
pp-else-elif [on] \c{%elif} after \c{%else}
Warns that an \c{%elif}-type directive was encountered
after \c{%else} has already been encounted. As a result, the
content of the \c{%elif} will never be expanded.
pp-else-else [on] \c{%else} after \c{%else}
Warns that a second \c{%else} clause was found for
the same \c{%if} statement. The content of this \c{%else}
clause will never be expanded.
pp-empty-braces [on] empty \c{%\{\}} construct
Warns that an empty \c{%\{\}} was encountered.
This expands to a single \c{%} character, which
is normally the \c{%} arithmetic operator.
pp-environment [on] nonexistent environment variable
=environment
Warns if a nonexistent environment variable
is accessed using the \c{%!} preprocessor
construct (see \k{getenv}.) Such environment
variables are treated as empty (with this
warning issued) starting in NASM 2.15;
earlier versions of NASM would treat this as
an error.
pp-macro-def-case-single [on] single-line macro defined both case sensitive and insensitive
=macro-def-case-single
Warns when a single-line macro is defined both case
sensitive and case insensitive.
The new macro
definition will override (shadow) the original one,
although the original macro is not deleted, and will
be re-exposed if the new macro is deleted with
\c{%undef}, or, if the original macro is the case
insensitive one, the macro call is done with a
different case.
pp-macro-def-greedy-single [on] single-line macro
=macro-def-greedy-single
Warns that a single-line macro is defined which would match a
previously existing greedy definition. The new macro definition
will override (shadow) the original one, although the original
macro is not deleted, and will be re-exposed if the new macro is
deleted with \c{%undef}, and will be invoked if called with a
parameter count that does not match the new definition.
# The immediately previous versions of NASM considered
# this an error, so promote this warning is promoted to
# to error by default.
pp-macro-def-param-single [err] single-line macro defined with and without parameters
=macro-def-param-single
Warns if the same single-line macro is defined with and without
parameters. The new macro definition will override (shadow) the
original one, although the original macro is not deleted, and will
be re-exposed if the new macro is deleted with \c{%undef}.
pp-macro-defaults [on] macros with more default than optional parameters
=macro-defaults
Warns when a macro has more default parameters than optional parameters.
See \k{mlmacdef} for why one might want to disable this warning.
pp-macro-params-legacy [on] improperly calling multi-line macro for legacy support
=macro-params-legacy
Warns about \i{multi-line macros} being invoked
with the wrong number of parameters, but for bug-compatibility
with NASM versions older than 2.15, NASM tried to fix up the
parameters to match the legacy behavior and call the macro anyway.
This can happen in certain cases where there are empty arguments
without braces, sometimes as a result of macro expansion.
The legacy behavior is quite strange and highly context-dependent,
and can be disabled with:
\c %pragma preproc sane_empty_expansion true
It is highly recommended to use this option in new code.
pp-macro-params-multi [on] multi-line macro calls with wrong parameter count
=macro-params-multi
Warns about \i{multi-line macros} being invoked
with the wrong number of parameters. See \k{mlmacover} for an
example of why you might want to disable this warning.
pp-macro-params-single [on] single-line macro calls with wrong parameter count
=macro-params-single
Warns about \i{single-line macros} being invoked
with the wrong number of parameters.
pp-macro-redef-multi [on] redefining multi-line macro
Warns that a multi-line macro is being redefined,
without first removing the old definition with
\c{%unmacro}.
pp-open-braces [on] unterminated \c{%\{...\}}
Warns that a preprocessor parameter
enclosed in braces \c{%\{...\}} lacks the
terminating \c{\}} character.
pp-open-brackets [on] unterminated \c{%[...]}
Warns that a preprocessor \c{%[...]} construct
lacks the terminating \c{]} character.
pp-open-string [on] unterminated string
Warns that a quoted string without a closing quotation
mark was encountered during preprocessing.
pp-rep-negative [on] negative \c{%rep} count
=negative-rep
Warns about a negative count given to the \c{%rep}
preprocessor directive.
pp-reserved [on] reserved unimplemented preprocessor directive
Warns that a preprocessor directive which was inadvertently
permitted in earlier versions of NASM without having been properly
implemented was seen in the source code. This currently applies to
the \i\c{%rmacro} (treated as \c{%macro}) and \i\c{%irmacro}
(treated as \c{%imacro}) directives. These directive names are
reserved and may be properly implemented in the future, changing
the meaning of the source code. directive is
pp-sel-range [on] \c{%sel()} argument out of range
Warns that the \c{%sel()} preprocessor function was passed
a value less than 1 or larger than the number of available
arguments.
pp-trailing [on] trailing garbage ignored
Warns that the preprocessor encountered additional text
where no such text was expected. This can
sometimes be the result of an incorrectly written expression,
or arguments that are inadvertently separated.
pragma-bad [off] malformed \c{%pragma}
=bad-pragma
Warns about a malformed or otherwise unparsable
\c{%pragma} directive.
pragma-empty [off] empty \c{%pragma} directive
Warns about a \c{%pragma} directive containing nothing.
This is treated identically to \c{%pragma ignore} except
for this optional warning.
# Not implemented yet
pragma-na [off] \c{%pragma} not applicable to this compilation
=not-my-pragma
Warns about a \c{%pragma} directive which is not applicable to
this particular assembly session. This is not yet implemented.
pragma-unknown [off] unknown \c{%pragma} facility or directive
=unknown-pragma
Warns about an unknown \c{%pragma} directive.
This is not yet implemented for most cases.
prefix-badmode-o64 [err] o64 prefix invalid in 16/32-bit mode
Warns that an \c{a64} prefix was specified in 16- or 32-bit
mode. If the error is demoted to a warning or suppressed, the
prefix is ignored by the assembler, but is likely to trigger
futher errors.
prefix-bnd [on] invalid \c{BND} prefix
=bnd
Warns about ineffective use of the \c{BND} prefix when the
\c{JMP} instruction is converted to the \c{SHORT} form.
This should be extremely rare since the short \c{JMP} only
is applicable to jumps inside the same module, but if
it is legitimate, it may be necessary to use
\c{bnd jmp dword}.
prefix-hint-dropped [on] invalid branch hint prefix dropped
Warns that the \c{{PT}} (predict taken) or \c{{PN}}
(predict not taken) branch prediction hint prefixes
are specified on an instruction that does not take
these prefixes. As these prefixes alias the segment
override prefixes, this may be a very serious error,
and therefore NASM will not generate these prefixes.
To force these prefixes to be emitted, use \c{DS} or
\c{CS}, instead, respectively.
prefix-hle [on] invalid HLE prefix
=hle
Warns about invalid use of the HLE \c{XACQUIRE} or \c{XRELEASE}
prefixes.
prefix-invalid [on] invalid prefix for instruction
Warns about an instruction which is only valid with certain
combinations of prefixes. The prefix will still be generated as
requested, but the result may be a completely different
instruction or result in a \c{#UD} trap.
prefix-lock-error [on] \c{LOCK} prefix on unlockable instruction
=lock
Warns about \c{LOCK} prefixes specified on unlockable instructions.
prefix-lock-xchg [on] superfluous \c{LOCK} prefix on \c{XCHG} instruction
Warns about a \c{LOCK} prefix added to an \c{XCHG} instruction.
The \c{XCHG} instruction is \e{always} locking, and so this
prefix is not necessary; however, NASM will generate it if
explicitly provided by the user, so this warning indicates that
suboptimal code is being generated.
prefix-opsize [on] invalid operand size prefix
Warns that an operand prefix (\c{o16}, \c{o32}, \c{o64},
\c{osp}) is invalid for the specified instruction has been specified.
The operand prefix will be ignored by the assembler.
prefix-seg [on] segment prefix ignored in 64-bit mode
Warns that an \c{es}, \c{cs}, \c{ss} or \c{ds} segment override
prefix has no effect in 64-bit mode. The prefix will still be
generated as requested.
ptr [on] non-NASM keyword used in other assemblers
Warns about keywords used in other assemblers that
might indicate a mistake in the source code.
Currently only the MASM \c{PTR} keyword is
recognized. If (limited) MASM compatibility is
desired, the \c{%use masm} macro package is
available, see \k{pkg_masm}; however, carefully note
the caveats listed.
regsize [on] register size specification ignored
Warns about a register with implicit size (such as \c{EAX}, which
is always 32 bits) been given an explicit size specification which
is inconsistent with the size of the named register, e.g. \c{WORD
EAX}. \c{DWORD EAX} or \c{WORD AX} are permitted, and do not
trigger this warning. Some registers which \e{do not} imply a
specific size, such as \c{K0}, may need this specification unless
the instruction itself implies the instruction size:
\c KMOVW K0,[foo] ; OK: KMOVW = 16 bits
\c KMOV WORD K0,[foo] ; OK: WORD K0 = 16 bits
\c KMOV K0,WORD [foo] ; OK: WORD [foo] = 16 bits
\c KMOV K0,[foo] ; Error: unknown size
reloc-abs-byte [off] 8-bit absolute section-crossing relocation
Warns that an 8-bit absolute relocation that could
not be resolved at assembly time was generated in
the output format.
This is usually normal, but may not be handled by all
possible target environments
reloc-abs-dword [off] 32-bit absolute section-crossing relocation
Warns that a 32-bit absolute relocation that could
not be resolved at assembly time was generated in
the output format.
This is usually normal, but may not be handled by all
possible target environments
reloc-abs-qword [off] 64-bit absolute section-crossing relocation
Warns that a 64-bit absolute relocation that could
not be resolved at assembly time was generated in
the output format.
This is usually normal, but may not be handled by all
possible target environments
reloc-abs-word [off] 16-bit absolute section-crossing relocation
Warns that a 16-bit absolute relocation that could
not be resolved at assembly time was generated in
the output format.
This is usually normal, but may not be handled by all
possible target environments
reloc-rel-byte [off] 8-bit relative section-crossing relocation
Warns that an 8-bit relative relocation that could
not be resolved at assembly time was generated in
the output format.
This is usually normal, but may not be handled by all
possible target environments
reloc-rel-dword [off] 32-bit relative section-crossing relocation
Warns that a 32-bit relative relocation that could
not be resolved at assembly time was generated in
the output format.
This is usually normal, but may not be handled by all
possible target environments
reloc-rel-qword [off] 64-bit relative section-crossing relocation
Warns that an 64-bit relative relocation that could
not be resolved at assembly time was generated in
the output format.
This is usually normal, but may not be handled by all
possible target environments
reloc-rel-word [off] 16-bit relative section-crossing relocation
Warns that a 16-bit relative relocation that could
not be resolved at assembly time was generated in
the output format.
This is usually normal, but may not be handled by all
possible target environments
section-alignment-rounded [on] section alignment rounded up
Warn if a section alignment is specified which is
not supported by the underlying object format, but
can be rounded up to a supported value.
unknown-warning [off] unknown warning in \c{-W}/\c{-w} or warning directive
Warns about a \c{-w} or \c{-W} option or a \c{[WARNING]} directive
that contains an unknown warning name or is otherwise not possible
to process.
user [on] \c{%warning} directives
Controls output of \c{%warning} directives (see \k{pperror}).
warn-stack-empty [on] warning stack empty
A \c{[WARNING POP]} directive was executed when
the warning stack is empty. This is treated
as a \c{[WARNING *all]} directive.
#
# This warning is currently issued by backends, but in the future
# that code should be centralized.
#
zeroing [on] \c{RES}\e{x} in initialized section becomes zero
A \c{RES}\e{x} directive was used in a section which contains
initialized data, and the output format does not support
this. Instead, this will be replaced with explicit zero
content, which may produce a large output file.
zext-reloc [on] relocation zero-extended to match output format
Warns that a relocation has been zero-extended due
to limitations in the output format.

View file

@ -43,93 +43,73 @@ sub add_alias($$) {
}
}
sub find_warnings {
my $infile = $_;
sub read_warnings($) {
my($infile) = @_;
return unless (basename($infile) =~ /^\w.*\.[ch]$/i);
open(my $in, '<', $infile)
or die "$0: cannot open input file $infile: $!\n";
open(my $in, '<', $infile) or die "$0:$infile: $!\n";
my $in_comment = 0;
my $nline = 0;
my $this;
my @doc;
while (defined(my $l = <$in>)) {
$nline++;
chomp $l;
if (!$in_comment) {
$l =~ s/^.*?\/\*.*?\*\///g; # Remove single-line comments
if ($l =~ /^.*?(\/\*.*)$/) {
# Begin block comment
$l = $1;
$in_comment = 1;
}
$l =~ s/\s+$//;
if ($l ne '') {
$l =~ s/^\s*\#(\s.*)?$//;
$l =~ s/\s+\\\#(\s.*)?$//;
next if ($l eq '');
}
if ($in_comment) {
if ($l =~ /\*\//) {
# End block comment
$in_comment = 0;
undef $this;
} elsif ($l =~ /^\s*\/?\*\!(\-|\=|\s*)(.*?)\s*$/) {
my $opr = $1;
my $str = $2;
if ($l =~ /^([\w\-]+)\s+\[(\w+)\]\s+(.*)$/) {
my $name = $1;
my $def = $2;
my $help = $3;
if ($opr eq '' && $str eq '') {
next;
} elsif ((!defined($this) || ($opr eq '')) &&
($str =~ /^([\w\-]+)\s+\[(\w+)\]\s(.*\S)\s*$/)) {
my $name = $1;
my $def = $2;
my $help = $3;
my $cname = uc($name);
$cname =~ s/[^A-Z0-9_]+/_/g;
my $cname = uc($name);
$cname =~ s/[^A-Z0-9_]+/_/g;
$this = {name => $name, cname => $cname,
def => $def, help => $help,
doc => [], file => $infile, line => $nline};
$this = {name => $name, cname => $cname,
def => $def, help => $help,
doc => [], file => $infile, line => $nline};
if (defined(my $that = $aliases{$name})) {
# Duplicate definition?!
printf STDERR "%s:%s: warning %s previously defined at %s:%s\n",
$infile, $nline, $name, $that->{file}, $that->{line};
} else {
push(@warnings, $this);
# Every warning name is also a valid warning alias
add_alias($name, $this);
$nwarn++;
}
} elsif ($opr eq '=') {
# Alias names for warnings
for my $a (split(/,+/, $str)) {
add_alias($a, $this);
}
} elsif ($opr =~ /^[\-\s]/) {
push(@{$this->{doc}}, "$str\n");
} else {
print STDERR "$infile:$nline: malformed warning definition\n";
print STDERR " $l\n";
$err++;
}
if (defined(my $that = $aliases{$name})) {
# Duplicate definition?!
printf STDERR "%s:%s: warning %s previously defined at %s:%s\n",
$infile, $nline, $name, $that->{file}, $that->{line};
} else {
undef $this;
push(@warnings, $this);
# Every warning name is also a valid warning alias
add_alias($name, $this);
$nwarn++;
}
} elsif ($l =~ /^\=([\w\-,]+)$/) {
# Alias names for warnings
die unless (defined($this));
map { add_alias($_,$this) } split(/,+/, $1);
} elsif ($l =~ /^(\s+(.*))?$/) {
my $str = $2;
die unless (defined($this));
next if ($str eq '' && !scalar(@{$this->{doc}}));
push(@{$this->{doc}}, "$str\n");
} else {
print STDERR "$infile:$nline: malformed warning definition\n";
print STDERR " $l\n";
$err++;
}
}
close($in);
}
my($what, $outfile, @indirs) = @ARGV;
my($what, $outfile, @infiles) = @ARGV;
if (!defined($outfile)) {
die "$0: usage: [c|h|doc] outfile indir...\n";
die "$0: usage: [c|h|doc] outfile infiles...\n";
}
find({ wanted => \&find_warnings, no_chdir => 1, follow => 1 }, @indirs);
foreach my $file (@infiles) {
read_warnings($file);
}
exit(1) if ($err);
@ -141,8 +121,7 @@ sub sort_warnings {
}
@warnings = sort sort_warnings @warnings;
my @warn_noall = @warnings;
pop @warn_noall if ($warn_noall[$#warn_noall]->{name} eq 'all');
my @warn_noall = grep { !($_->{name} eq 'all') } @warnings;
my $outdata;
open(my $out, '>', \$outdata)
@ -152,16 +131,16 @@ if ($what eq 'c') {
print $out "#include \"error.h\"\n\n";
printf $out "const char * const warning_name[%d] = {\n",
$#warnings + 2;
print $out "\tNULL";
print $out " NULL";
foreach my $warn (@warnings) {
print $out ",\n\t\"", $warn->{name}, "\"";
print $out ",\n \"", $warn->{name}, "\"";
}
print $out "\n};\n\n";
printf $out "const struct warning_alias warning_alias[%d] = {",
scalar(keys %aliases);
my $sep = '';
foreach my $alias (sort { $a cmp $b } keys(%aliases)) {
printf $out "%s\n\t{ %-27s WARN_IDX_%s }",
printf $out "%s\n { %-39s WARN_IDX_%-31s }",
$sep, "\"$alias\",", $aliases{$alias}->{cname};
$sep = ',';
}
@ -169,20 +148,20 @@ if ($what eq 'c') {
printf $out "const char * const warning_help[%d] = {\n",
$#warnings + 2;
print $out "\tNULL";
print $out " NULL";
foreach my $warn (@warnings) {
my $help = quote_for_c(remove_markup($warn->{help}));
print $out ",\n\t\"", $help, "\"";
print $out ",\n \"", $help, "\"";
}
print $out "\n};\n\n";
printf $out "const uint8_t warning_default[%d] = {\n",
$#warn_noall + 2;
print $out "\tWARN_INIT_ON"; # for entry 0
print $out " WARN_INIT_ON"; # for entry 0
foreach my $warn (@warn_noall) {
print $out ",\n\tWARN_INIT_", uc($warn->{def});
print $out ",\n WARN_INIT_", uc($warn->{def});
}
print $out "\n};\n\n";
printf $out "uint8_t warning_state[%d];\t/* Current state */\n",
printf $out "uint8_t warning_state[%d]; /* Current state */\n",
$#warn_noall + 2;
} elsif ($what eq 'h') {
my $filename = basename($outfile);
@ -197,29 +176,30 @@ if ($what eq 'c') {
print $out "# error \"$filename should only be included from within error.h\"\n";
print $out "#endif\n\n";
print $out "enum warn_index {\n";
printf $out "\tWARN_IDX_%-23s = %3d, /* not suppressible */\n", 'NONE', 0;
printf $out " WARN_IDX_%-31s = %3d, /* not suppressible */\n", 'NONE', 0;
my $n = 1;
foreach my $warn (@warnings) {
printf $out "\tWARN_IDX_%-23s = %3d%s /* %s */\n",
printf $out " WARN_IDX_%-31s = %3d%s /* %s */\n",
$warn->{cname}, $n,
($n == $#warnings + 1) ? " " : ",",
$warn->{help};
remove_markup($warn->{help});
$n++;
}
print $out "};\n\n";
print $out "enum warn_const {\n";
printf $out "\tWARN_%-27s = %3d << WARN_SHR", 'NONE', 0;
printf $out " WARN_%-35s = %3d << WARN_SHR", 'NONE', 0;
$n = 1;
foreach my $warn (@warn_noall) {
printf $out ",\n\tWARN_%-27s = %3d << WARN_SHR", $warn->{cname}, $n++;
printf $out ",\n WARN_%-35s = %3d << WARN_SHR", $warn->{cname}, $n++;
}
print $out "\n};\n\n";
print $out "struct warning_alias {\n";
print $out "\tconst char *name;\n";
print $out "\tenum warn_index warning;\n";
print $out " const char *name;\n";
print $out " enum warn_index warning;\n";
print $out "};\n\n";
printf $out "#define NUM_WARNINGS %d\n", $#warn_noall + 2;
printf $out "#define NUM_WARNING_ALIAS %d\n", scalar(keys %aliases);
printf $out "extern const char * const warning_name[%d];\n",
@ -227,46 +207,36 @@ if ($what eq 'c') {
printf $out "extern const char * const warning_help[%d];\n",
$#warnings + 2;
print $out "extern const struct warning_alias warning_alias[NUM_WARNING_ALIAS];\n";
printf $out "extern const uint8_t warning_default[%d];\n",
$#warn_noall + 2;
printf $out "extern uint8_t warning_state[%d];\n",
$#warn_noall + 2;
printf $out "extern const uint8_t warning_default[NUM_WARNINGS];\n",
printf $out "extern uint8_t warning_state[NUM_WARNINGS];\n",
print $out "\n#endif /* $guard */\n";
} elsif ($what eq 'doc') {
my %whatdef = ( 'on' => 'Enabled',
'off' => 'Disabled',
'err' => 'Enabled and promoted to error' );
my %wsec = ('on' => [], 'off' => [], 'err' => [],
'group' => [], 'legacy' => []);
my @indexinfo = ();
my @outtxt = ();
foreach my $pfx (sort { $a cmp $b } keys(%prefixes)) {
my $warn = $aliases{$pfx};
my @doc;
my $wtxt;
if (!defined($warn)) {
my @plist = sort { $a cmp $b } @{$prefixes{$pfx}};
next if ( $#plist < 1 );
@doc = ("all \\c{$pfx-} warnings\n\n",
"\\> \\c{$pfx} is a group alias for all warning classes\n",
"prefixed by \\c{$pfx-}; currently\n");
# Just commas is bad grammar to be sure, but it is more
# legible than the alternative.
push(@doc, join(scalar(@plist) < 3 ? ' and ' : ', ',
map { "\\c{$_}" } @plist).".\n");
@doc = ("group alias for:\n\n");
push(@doc, map { "\\c $_\n" } @plist);
$wtxt = $wsec{'group'};
} elsif ($pfx ne $warn->{name}) {
my $awarn = $aliases{$warn->{name}};
@doc = ($awarn->{help}."\n\n",
"\\> \\c{$pfx} is a backwards compatibility alias for \\c{".
$warn->{name}."}.\n");
"\\> Alias for \\c{".$warn->{name}."}.\n");
$wtxt = $wsec{'legacy'};
} else {
my $docdef = $whatdef{$warn->{def}};
@doc = ($warn->{help}."\n\n");
@doc = ($warn->{help}."\n\n",
"\\> \\c{".$warn->{name}."} ");
my $newpara = 0;
my $newpara = 1;
foreach my $l (@{$warn->{doc}}) {
if ($l =~ /^\s*$/) {
$newpara = 1;
@ -278,33 +248,45 @@ if ($what eq 'c') {
}
push(@doc, $l);
}
if (defined($docdef)) {
push(@doc, "\n", "\\> $docdef by default.\n");
}
$wtxt = $wsec{$warn->{def}};
}
push(@indexinfo, "\\IR{w-$pfx} warning class, \\c{$pfx}\n");
push(@outtxt, "\\b \\I{w-$pfx} \\c{$pfx}: ", @doc, "\n");
push(@$wtxt, "\\b \\I{w-$pfx} \\c{$pfx}: ", @doc, "\n");
}
print $out "\n", @indexinfo, "\n", @outtxt;
print $out "\n", @indexinfo, "\n";
print $out "\n\\H{warning-classes} Warning Classes\n\n";
print $out "This list shows each warning class that can be\n";
print $out "enabled or disabled individually. Each warning containing\n";
print $out "a \\c{-} character in the name can also be enabled or\n";
print $out "disabled as part of a group, named by removing one or more\n";
print $out "\\c{-}-delimited suffixes.\n";
print $out "\n\\S{warnings-classes-on} Enabled by default\n\n";
print $out @{$wsec{'on'}};
print $out "\n\\S{warnings-classes-err} Enabled and promoted to error by default\n\n";
print $out @{$wsec{'err'}};
print $out "\n\\S{warnings-classes-off} Disabled by default\n\n";
print $out @{$wsec{'off'}};
print $out "\n\\H{warning-groups} Warning Class Groups\n\n";
print $out "Warning class groups are aliases for all warning classes with a common\n";
print $out "prefix. This list shows the warnings that are currently\n";
print $out "included in specific warning groups.\n\n";
print $out @{$wsec{'group'}};
print $out "\n\\H{warning-legacy} Warning Class Aliases for Backward Compatiblity\n\n";
print $out "These aliases are defined for compatibility with earlier\n";
print $out "versions of NASM.\n\n";
print $out @{$wsec{'legacy'}};
}
close($out);
# Write data to file if and only if it has changed
# For some systems, even if we don't write, opening for append
# apparently touches the timestamp, so we need to read and write
# as separate operations.
if (open(my $out, '<', $outfile)) {
my $datalen = length($outdata);
my $oldlen = read($out, my $oldoutdata, $datalen+1);
close($out);
exit 0 if (defined($oldlen) && $oldlen == $datalen &&
($oldoutdata eq $outdata));
}
# Data changed, must rewrite
open(my $out, '>', $outfile)
or die "$0: cannot open output file $outfile: $!\n";

View file

@ -5,9 +5,10 @@ dnl Set debug flags and optimization flags depending on if
dnl --enable-debug is set or not. Some flags are set regardless...
dnl --------------------------------------------------------------------------
AC_DEFUN([PA_OPTION_DEBUG],
[PA_ARG_DISABLED([gdb], [disable gdb debug extensions],
[PA_ADD_LANGFLAGS([-g3])], [PA_ADD_LANGFLAGS([-ggdb3],[-g3])])
[PA_ADD_LANGFLAGS([-g3])
PA_ARG_DISABLED([gdb], [disable gdb debug extensions],,
[PA_ADD_LANGFLAGS([-ggdb])])
PA_ARG_ENABLED([debug], [optimize for debugging],
[PA_ADD_LANGFLAGS([-Og],[-O0])
[PA_ADD_LANGFLAGS([-Og],[-O0])
$1],
[$2])])

View file

@ -7,15 +7,24 @@ dnl but that could change in the future -- to force disabled by default,
dnl set to "no".
dnl --------------------------------------------------------------------------
AC_DEFUN([PA_OPTION_LTO],
[AC_BEFORE([$0],[AC_PROG_AR])dnl
AC_BEFORE([$0],[AC_PROG_RANLIB])dnl
PA_ARG_BOOL([lto],
[
dnl Careful here: AR or RANLIB may already have already been probed for.
dnl If not, do it now to prevent it from getting down further down.
dnl Do it unconditionally to avoid inconsistent behavior with or
dnl without --enable-lto.
AS_IF([test -z "$AR"], [AC_CHECK_TOOL(AR, ar)])
AS_IF([test -z "$RANLIB"], [AC_CHECK_TOOL(RANLIB, ranlib, :)])
PA_ARG_BOOL([lto],
[Try to enable link-time optimization for this compiler],
[m4_default([$1],[no])],
[PA_FIND_FLAGS([-flto=auto],[-flto])
PA_FIND_FLAGS([-ffat-lto-objects])
PA_FIND_FLAGS([-fuse-linker-plugin])
dnl Add here if there are any other toolchains that need special magic
AS_IF([test x$ac_compiler_gnu = xyes],
[AC_CHECK_TOOL(AR, [gcc-ar], [ar], [:])
AC_CHECK_TOOL(RANLIB, [gcc-ranlib], [ranlib], [:])])])])
[AC_CHECK_TOOL(CC_AR, gcc-ar)
AR="${CC_AR:-$AR}"
AC_CHECK_TOOL(CC_RANLIB, gcc-ranlib)
RANLIB="${CC_RANLIB:-$RANLIB}"])])])

View file

@ -46,7 +46,14 @@ fi
mv -f autoconf/aclocal.m4 autoconf/aclocal.m4.old
mkdir -p autoconf/m4.old autoconf/m4
mv -f autoconf/m4/*.m4 autoconf/m4.old/ 2>/dev/null || true
ACLOCAL_PATH="${ACLOCAL_PATH}${ACLOCAL_PATH:+:}`pwd`/autoconf/m4.old"
if ${PATH_SEPARATOR+false} :; then
PATH_SEPARATOR=:
(PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && {
(PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 ||
PATH_SEPARATOR=';'
}
fi
ACLOCAL_PATH="${ACLOCAL_PATH}${ACLOCAL_PATH:+${PATH_SEPARATOR}}`pwd`/autoconf/m4.old"
export ACLOCAL_PATH
"$ACLOCAL" --install --output=autoconf/aclocal.m4 -I autoconf/m4
if test ! -f autoconf/aclocal.m4; then

View file

@ -1,35 +1,5 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 1996-2025 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ----------------------------------------------------------------------- */
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2025 The NASM Authors - All Rights Reserved */
/*
* common.c - code common to nasm and ndisasm
@ -45,6 +15,15 @@
*/
struct globalopt globl;
void reset_global_defaults(int bits)
{
globl.bits = bits;
globl.bnd = false;
globl.rel = 0;
globl.reldef = EAF_FS|EAF_GS;
globl.dollarhex = true;
}
/*
* Name of a register token, if applicable; otherwise NULL
*/

109
common/errstubs.c Normal file
View file

@ -0,0 +1,109 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2025 The NASM Authors - All Rights Reserved */
#include "compiler.h"
#include "nasmlib.h"
#include "error.h"
struct errinfo erropt;
/* Common function body */
#define nasm_do_error(_sev,_flags) \
do { \
const errflags nde_severity = (_sev); \
const errflags nde_flags = nde_severity | (_flags); \
va_list ap; \
va_start(ap, fmt); \
if (nde_severity >= ERR_CRITICAL) { \
nasm_verror_critical(nde_flags, fmt, ap); \
unreachable(); \
} else { \
nasm_verror(nde_flags, fmt, ap); \
if (nde_severity >= ERR_FATAL) \
unreachable(); \
} \
va_end(ap); \
} while (0)
/*
* This is the generic function to use when the error type is not
* known a priori. For ERR_DEBUG and ERR_INFO the level can be
* included by
*/
void nasm_error(errflags flags, const char *fmt, ...)
{
nasm_do_error(flags & ERR_MASK, flags);
}
#define nasm_err_helpers(_type, _name, _sev) \
_type nasm_ ## _name ## f (errflags flags, const char *fmt, ...) \
{ \
nasm_do_error(_sev, flags); \
} \
_type nasm_ ## _name (const char *fmt, ...) \
{ \
nasm_do_error(_sev, 0); \
}
nasm_err_helpers(void, listmsg, ERR_LISTMSG)
nasm_err_helpers(void, note, ERR_NOTE)
nasm_err_helpers(void, nonfatal, ERR_NONFATAL)
nasm_err_helpers(fatal_func, fatal, ERR_FATAL)
nasm_err_helpers(fatal_func, critical, ERR_CRITICAL)
nasm_err_helpers(fatal_func, panic, ERR_PANIC)
/*
* Strongly discourage warnings without level by require flags on warnings.
* This means nasm_warn() is the equivalent of the -f variants of the
* other ones.
*
* This is wrapped in a macro to be able to elide it if the warning is
* disabled, hence the extra underscore.
*/
void nasm_warn_(errflags flags, const char *fmt, ...)
{
nasm_do_error(ERR_WARNING, flags);
}
/*
* nasm_info() and nasm_debug() takes mandatory enabling levels.
*/
void nasm_info_(unsigned int level, const char *fmt, ...)
{
if (info_level(level))
nasm_do_error(ERR_INFO, LEVEL(level));
}
void nasm_debug_(unsigned int level, const char *fmt, ...)
{
if (debug_level(level))
nasm_do_error(ERR_DEBUG, LEVEL(level));
}
/*
* Convenience function for nasm_nonfatal(ERR_HOLD, ...)
*/
void nasm_holderr(const char *fmt, ...)
{
nasm_do_error(ERR_NONFATAL, ERR_NONFATAL|ERR_HOLD);
}
/*
* panic() and nasm_assert()
*/
fatal_func nasm_panic_from_macro(const char *func, const char *file, int line)
{
if (!func)
func = "<unknown>";
nasm_panic("internal error in %s at %s:%d\n", func, file, line);
}
fatal_func nasm_assert_failed(const char *msg, const char *func,
const char *file, int line)
{
if (!func)
func = "<unknown>";
nasm_panic("assertion %s failed in %s at %s:%d", msg, func, file, line);
}

76
common/files.c Normal file
View file

@ -0,0 +1,76 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 2026 The NASM Authors - All Rights Reserved */
#include "compiler.h"
#include "nasmlib.h"
#include "files.h"
#include "error.h"
/* These must match the constants in "files.h" */
static const char * const filename_names[FN_NFILES] = {
"input",
"output",
"error",
"list",
"dependency",
"map",
NULL, /* End of "real" filenames */
"debug mapped input",
"make mapped output"
};
const char *_filenames[FN_NFILES];
const char *copy_filename(enum filenames fn, const char *src)
{
return set_filename(fn, nasm_strdup(src));
}
const char *set_filename(enum filenames fn, char *src)
{
const char **dstp, *dst;
nasm_assert((size_t)fn < ARRAY_SIZE(_filenames));
dstp = &_filenames[fn];
dst = *dstp;
if (dst) {
nasm_fatal("more than one %s file specified: %s and %s",
filename_names[fn], dst, src);
}
return *dstp = src;
}
void check_overwrite_files(void)
{
enum filenames fi, fo; /* No fie or fum */
for (fi = FN_INFILE; fi < FN_OUTFILE; fi++) {
const char *inname = get_filename(fi);
if (!inname)
continue;
for (fo = FN_OUTFILE; fo < FN_NFILES_REAL; fo++) {
const char *outname = get_filename(fo);
if (outname && !nasm_compare_paths(inname, outname)) {
nasm_nonfatal("%s file would overwrite %s file `%s'",
filename_names[fo], filename_names[fi], inname);
}
}
}
}
void cleanup_filenames(void)
{
enum filenames fn;
for (fn = 0; fn < FN_NFILES; fn++) {
nasm_free((char *)_filenames[fn]);
_filenames[fn] = NULL;
}
}

View file

@ -1,35 +1,5 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 2016 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ----------------------------------------------------------------------- */
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 2016 The NASM Authors - All Rights Reserved */
/*
* config/msvc.h
@ -55,6 +25,12 @@
#ifndef NASM_CONFIG_MSVC_H
#define NASM_CONFIG_MSVC_H
/* Needed for the _BitScanReverse()/_BitScanReverse64() intrinsics below;
not available prior to Visual Studio 2005. */
#if _MSC_VER >= 1400
# include <intrin.h>
#endif
/* Define to 1 if you have the <fcntl.h> header file. */
#define HAVE_FCNTL_H 1
@ -63,9 +39,25 @@
# define HAVE_INTTYPES_H 1
#endif
/* Define to 1 if you have the <intrin.h> header file. */
#if _MSC_VER >= 1400
# define HAVE_INTRIN_H 1
#endif
/* Define to 1 if you have the <io.h> header file. */
#define HAVE_IO_H 1
/* Define to 1 if you have the <stdarg.h> header file. */
#define HAVE_STDARG_H 1
/* Define to 1 if you have the <stdint.h> header file. */
#if _MSC_VER >= 1600
# define HAVE_STDINT_H 1
#endif
/* Define to 1 if you have the <stdio.h> header file. */
#define HAVE_STDIO_H 1
/* Define to 1 if you have the <stdlib.h> header file. */
#define HAVE_STDLIB_H 1
@ -78,6 +70,9 @@
/* Define to 1 if you have the <sys/types.h> header file. */
#define HAVE_SYS_TYPES_H 1
/* Define to 1 if you have the <wchar.h> header file. */
#define HAVE_WCHAR_H 1
/* Define to 1 if you have the `access' function. */
#define HAVE_ACCESS 1
#if _MSC_VER < 1400
@ -90,6 +85,13 @@
# define fileno _fileno
#endif
/* Define to 1 if you have the `isascii' function. */
#define HAVE_ISASCII 1
#define isascii __isascii
/* Define to 1 if you have the `iscntrl' function. */
#define HAVE_ISCNTRL 1
/* Define to 1 if you have the `snprintf' function. */
#define HAVE_SNPRINTF 1
#if _MSC_VER < 1900
@ -107,6 +109,25 @@
/* Define to 1 if you have the `_filelengthi64' function. */
#define HAVE__FILELENGTHI64 1
/* Define to 1 if you have the `_byteswap_ushort' intrinsic function. */
#define HAVE__BYTESWAP_USHORT 1
/* Define to 1 if you have the `_byteswap_ulong' intrinsic function. */
#define HAVE__BYTESWAP_ULONG 1
/* Define to 1 if you have the `_byteswap_uint64' intrinsic function. */
#define HAVE__BYTESWAP_UINT64 1
/* Define to 1 if you have the `_BitScanReverse' intrinsic function. */
#if _MSC_VER >= 1400
# define HAVE__BITSCANREVERSE 1
#endif
/* Define to 1 if you have the `_BitScanReverse64' intrinsic function. */
#if (defined(_M_X64) || defined(_M_ARM64)) && _MSC_VER >= 1400
# define HAVE__BITSCANREVERSE64 1
#endif
/* Define to 1 if you have the `_fseeki64' function. */
#define HAVE__FSEEKI64 1
@ -162,6 +183,18 @@
# define uintptr_t size_t
#endif
/* Define to 1 if the system has the type `uintmax_t'. */
#ifdef HAVE_STDINT_H
# define HAVE_UINTMAX_T 1
#else
/* Define to the widest unsigned integer type if <stdint.h> and <inttypes.h>
do not define. */
# define uintmax_t unsigned long long
#endif
/* Define to 1 if the system has the type `unsigned long long int'. */
#define HAVE_UNSIGNED_LONG_LONG_INT 1
/* Define to 1 if you have the `vsnprintf' function. */
#define HAVE_VSNPRINTF 1
#if _MSC_VER < 1400

View file

@ -1,35 +1,5 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 2016 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ----------------------------------------------------------------------- */
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 2016 The NASM Authors - All Rights Reserved */
/*
* config/unknown.h

View file

@ -1,35 +1,5 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 2016 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ----------------------------------------------------------------------- */
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 2016 The NASM Authors - All Rights Reserved */
/*
* config/watcom.h

View file

@ -1,7 +1,8 @@
dnl Process this file with autoconf 2.71 or later to produce
dnl a configure script.
AC_PREREQ([2.71])
AC_INIT
m4_define([VERSION],m4_normalize(m4_include([version])))
AC_INIT([nasm],VERSION,[https://bugs.nasm.us/],[nasm],[https://www.nasm.us/])
AC_CONFIG_SRCDIR([config/config.h.in])
AC_CONFIG_HEADERS([config/config.h])
AC_PREFIX_PROGRAM(nasm)
@ -90,10 +91,10 @@ AC_PROG_MAKE_SET
AC_PROG_INSTALL
AC_PROG_MKDIR_P
AC_CHECK_PROGS([NROFF], nroff, false)
AC_CHECK_PROGS([ASCIIDOC], asciidoc, false)
AC_CHECK_PROGS([XMLTO], xmlto, false)
AC_CHECK_PROGS([XZ], xz, false)
AC_CHECK_PROGS([PYTHON3], [python3 python], false)
dnl Check for progs needed for manpage generation
MANPAGES=manpages
@ -147,7 +148,7 @@ AC_SUBST([NSIS])
dnl Check for host compiler tools
AC_CHECK_TOOL(AR, ar)
AC_CHECK_TOOL(RANLIB, ranlib, :)
AC_CHECK_TOOL(STRIP, strip)
AC_CHECK_TOOL(STRIP, strip, :)
dnl
dnl NOTE: the tests for header files and library functions use constructs
@ -195,7 +196,6 @@ AC_CHECK_FUNCS(strcasecmp stricmp)
AC_CHECK_FUNCS(strncasecmp strnicmp)
AC_CHECK_FUNCS(strsep)
AC_CHECK_FUNCS(strnlen)
AC_CHECK_FUNCS(strrchrnul)
AC_CHECK_FUNCS(iscntrl)
AC_CHECK_FUNCS(isascii)
AC_CHECK_FUNCS(mempcpy)
@ -222,11 +222,11 @@ AC_CHECK_FUNCS(sysconf)
AC_CHECK_FUNCS([access _access faccessat])
PA_HAVE_FUNC(__builtin_expect,(1,1))
PA_HAVE_FUNC(__builtin_unreachable,())
PA_FUNC_SNPRINTF
PA_FUNC_VSNPRINTF
AC_CHECK_FUNCS([strlcpy])
AC_CHECK_FUNCS([strrchrnul])
dnl These types are POSIX-specific, and Windows does it differently...
AC_CHECK_TYPES([struct stat], [AC_CHECK_FUNCS([stat fstat])])
@ -243,7 +243,6 @@ AC_CHECK_DECLS(strnicmp)
AC_CHECK_DECLS(strsep)
AC_CHECK_DECLS(strlcpy)
AC_CHECK_DECLS(strnlen)
AC_CHECK_DECLS(strrchrnul)
dnl Check for missing types
AC_TYPE_UINTMAX_T
@ -277,6 +276,7 @@ dnl Some rather useful gcc extensions...
dnl
PA_HAVE_FUNC(__builtin_constant_p, (0))
PA_HAVE_FUNC(__builtin_choose_expr, (0,1,2))
PA_HAVE_FUNC(__builtin_prefetch, (NULL))
dnl
dnl Check for supported gcc attributes; some compilers (e.g. Sun CC)
@ -371,5 +371,5 @@ dnl
PA_CHECK_BAD_STDC_INLINE
PA_C_TYPEOF
AC_CONFIG_FILES([Makefile doc/Makefile misc/Makefile test/Makefile])
AC_CONFIG_FILES([Makefile doc/Makefile misc/Makefile test/Makefile travis.mak])
AC_OUTPUT

View file

@ -1,35 +1,5 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 1996-2025 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ----------------------------------------------------------------------- */
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2025 The NASM Authors - All Rights Reserved */
/*
* disasm.c where all the _work_ gets done in the Netwide Disassembler
@ -139,35 +109,48 @@ static enum reg_enum whichreg(opflags_t regflags, int regval, uint32_t rex)
}
/*
* An implicit register operand
* An implicit register operand.
*/
/* Deal with OpenWatcom 64-bit switch() braindamage */
#ifdef __WATCOMC__
# define imp(op,rn) if (regflags == op) return rn
# define impdef(rn) return rn
#else
# define imp(op,rn) case op: return rn
# define impdef(rn) default: return rn
#endif
static enum reg_enum implicit_reg(opflags_t regflags)
{
switch (regflags) {
case REG_AL: return R_AL;
case REG_AX: return R_AX;
case REG_EAX: return R_EAX;
case REG_RAX: return R_RAX;
case REG_DL: return R_DL;
case REG_DX: return R_DX;
case REG_EDX: return R_EDX;
case REG_RDX: return R_RDX;
case REG_CL: return R_CL;
case REG_CX: return R_CX;
case REG_ECX: return R_ECX;
case REG_RCX: return R_RCX;
case FPU0: return R_ST0;
case XMM0: return R_XMM0;
case YMM0: return R_YMM0;
case ZMM0: return R_ZMM0;
case REG_ES: return R_ES;
case REG_CS: return R_CS;
case REG_SS: return R_SS;
case REG_DS: return R_DS;
case REG_FS: return R_FS;
case REG_GS: return R_GS;
case OPMASK0: return R_K0;
default: return 0;
#ifndef __WATCOMC__
switch (regflags)
#endif
{
imp(REG_AL,R_AL);
imp(REG_AX,R_AX);
imp(REG_EAX,R_EAX);
imp(REG_RAX,R_RAX);
imp(REG_DL,R_DL);
imp(REG_DX,R_DX);
imp(REG_EDX,R_EDX);
imp(REG_RDX,R_RDX);
imp(REG_CL,R_CL);
imp(REG_CX,R_CX);
imp(REG_ECX,R_ECX);
imp(REG_RCX,R_RCX);
imp(FPU0,R_ST0);
imp(XMM0,R_XMM0);
imp(YMM0,R_YMM0);
imp(ZMM0,R_ZMM0);
imp(REG_ES,R_ES);
imp(REG_CS,R_CS);
imp(REG_SS,R_SS);
imp(REG_DS,R_DS);
imp(REG_FS,R_FS);
imp(REG_GS,R_GS);
imp(OPMASK0,R_K0);
impdef(0);
}
}
@ -580,11 +563,14 @@ static int matches(const uint8_t *data, const struct prefix_info *prefix,
opx->segment |= SEG_SIGNED;
break;
case4(020):
case4(0300):
if (!is_hint_nop(*data))
return 0;
opx->offset = *data++;
opx->disp_size = 8;
break;
case4(020):
case4(024):
opx->offset = *data++;
opx->disp_size = 8;
@ -1530,7 +1516,7 @@ int32_t disasm(const uint8_t *dp, int32_t data_size,
slen += append_evex_reg_deco(output + slen, outbufsize - slen,
deco, &prefix);
} else if (t & IMMEDIATE) {
if (is_class(t, UNITY)) {
if (is_class(UNITY, t)) {
output[slen++] = '1';
} else if (o->segment & SEG_DFV) {
int fl;

View file

@ -1,35 +1,5 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 1996-2025 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ----------------------------------------------------------------------- */
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2025 The NASM Authors - All Rights Reserved */
/*
* disasm.h header file for disasm.c
@ -117,4 +87,8 @@ const uint8_t *parse_prefixes(struct prefix_info *pf, const uint8_t *data,
_op; \
} while (0)
/* Error module */
void usage(void);
#endif

46
disasm/diserror.c Normal file
View file

@ -0,0 +1,46 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2025 The NASM Authors - All Rights Reserved */
/*
* diserror.c - stubs for the error functions for the disassembler
*/
#include "compiler.h"
#include "error.h"
#include "disasm.h"
void usage(void)
{
const char help[] =
"usage: ndisasm [-aihlruvw] [-b bits] [-o origin] [-s sync...]\n"
" [-e bytes] [-k start,bytes] [-p vendor] file\n"
" -a or -i activates auto (intelligent) sync\n"
" -b 16, -b 32 or -b 64 sets the processor mode\n"
" -u same as -b 32\n"
" -l same as -b 64\n"
" -w wide output (avoids continuation lines)\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";
fputs(help, stderr);
}
void nasm_verror(errflags severity, const char *fmt, va_list val)
{
severity &= ERR_MASK;
vfprintf(stderr, fmt, val);
if (severity >= ERR_FATAL)
exit(severity - ERR_FATAL + 1);
}
fatal_func nasm_verror_critical(errflags severity, const char *fmt, va_list val)
{
nasm_verror(severity, fmt, val);
abort();
}
uint8_t warning_state[NUM_WARNINGS];

View file

@ -1,35 +1,5 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 1996-2025 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ----------------------------------------------------------------------- */
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2025 The NASM Authors - All Rights Reserved */
/*
* ndisasm.c the Netwide Disassembler main module
@ -48,41 +18,12 @@
#include "sync.h"
#include "disasm.h"
const char *_progname;
static int bpl = 8; /* bytes per line of hex dump */
static const char *help =
"usage: ndisasm [-aihlruvw] [-b bits] [-o origin] [-s sync...]\n"
" [-e bytes] [-k start,bytes] [-p vendor] file\n"
" -a or -i activates auto (intelligent) sync\n"
" -b 16, -b 32 or -b 64 sets the processor mode\n"
" -u same as -b 32\n"
" -l same as -b 64\n"
" -w wide output (avoids continuation lines)\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(uint64_t, const uint8_t *, int, const char *);
static void skip(uint32_t dist, FILE * fp);
void nasm_verror(errflags severity, const char *fmt, va_list val)
{
severity &= ERR_MASK;
vfprintf(stderr, fmt, val);
if (severity >= ERR_FATAL)
exit(severity - ERR_FATAL + 1);
}
fatal_func nasm_verror_critical(errflags severity, const char *fmt, va_list val)
{
nasm_verror(severity, fmt, val);
abort();
}
errflags errflags_never = 0;
static bool skip(off_t *posp, off_t dist, FILE *fp);
int main(int argc, char **argv)
{
@ -91,21 +32,27 @@ int main(int argc, char **argv)
char outbuf[256];
char *pname = *argv;
char *filename = NULL;
uint32_t nextsync, synclen, initskip = 0L;
int lenread;
int32_t lendis;
uint64_t nextsync, synclen;
size_t lenread;
bool autosync = false;
int bits = 16, b;
bool eof = false;
bool eof;
iflag_t prefer;
bool rn_error;
int64_t offset;
uint64_t offset, dataread, datamax;
off_t fileoffs, initskip;
FILE *fp;
_progname = argv[0];
reset_global_defaults(0);
nasm_ctype_init();
iflag_clear_all(&prefer);
offset = 0;
offset = 0;
datamax = UINT64_C(-1);
initskip = 0;
init_sync();
while (--argc) {
@ -120,7 +67,7 @@ int main(int argc, char **argv)
p++;
break;
case 'h':
fputs(help, stderr);
usage();
return 0;
case 'r':
case 'v':
@ -141,6 +88,23 @@ int main(int argc, char **argv)
bpl = 16;
p++;
break;
case 'z': /* max number of bytes to read */
v = p[1] ? p + 1 : --argc ? *++argv : NULL;
if (!v) {
fprintf(stderr, "%s: `-z' requires an argument\n",
pname);
return 1;
}
datamax = readnum(v, &rn_error);
if (rn_error) {
fprintf(stderr,
"%s: `-z' requires a numeric argument\n",
pname);
return 1;
}
p = ""; /* force to next argument */
break;
case 'b': /* bits */
v = p[1] ? p + 1 : --argc ? *++argv : NULL;
if (!v) {
@ -283,8 +247,8 @@ int main(int argc, char **argv)
}
if (!filename) {
fprintf(stderr, help, pname);
return 0;
usage();
return 1;
}
if (strcmp(filename, "-")) {
@ -299,8 +263,12 @@ int main(int argc, char **argv)
fp = stdin;
}
if (initskip > 0)
skip(initskip, fp);
reset_global_defaults(bits);
fileoffs = 0;
dataread = 0;
if (!skip(&fileoffs, initskip, fp))
return 1; /* EOF before header */
/*
* This main loop is really horrible, and wants rewriting with
@ -310,35 +278,42 @@ int main(int argc, char **argv)
q = p = buffer;
nextsync = next_sync(offset, &synclen);
do {
int32_t to_read = buffer + sizeof(buffer) - p;
lenread = 0;
eof = false;
while (lenread > 0 || (dataread < datamax && !eof && !feof(fp))) {
size_t to_read = buffer + sizeof(buffer) - p;
if ((nextsync || synclen) &&
to_read > nextsync - offset - (p - q))
to_read = nextsync - offset - (p - q);
if (to_read > datamax - dataread)
to_read = datamax - dataread;
lenread = 0;
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 ((nextsync || synclen) &&
(uint32_t)offset == nextsync) {
dataread += lenread;
fileoffs += lenread;
p += lenread;
eof |= !lenread; /* help along systems with bad feof */
}
if ((nextsync || synclen) && offset == nextsync) {
if (synclen) {
fprintf(stdout, "%08"PRIX64" skipping 0x%"PRIX32" bytes\n",
fprintf(stdout, "%08"PRIX64" skipping 0x%"PRIX64" bytes\n",
offset, synclen);
offset += synclen;
skip(synclen, fp);
dataread += synclen;
eof |= skip(&fileoffs, synclen, fp);
}
q = p = buffer;
nextsync = next_sync(offset, &synclen);
}
while (p > q && (p - q >= INSN_MAX || lenread == 0)) {
lendis = disasm(q, INSN_MAX, outbuf, sizeof(outbuf),
bits, offset, autosync, &prefer);
if (!lendis || lendis > (p - q)
|| ((nextsync || synclen) &&
(uint32_t)lendis > nextsync - offset))
size_t lendis = disasm(q, INSN_MAX, outbuf, sizeof(outbuf),
bits, offset, autosync, &prefer);
if (!lendis || q + lendis > p ||
((nextsync || synclen) && lendis > nextsync - offset))
lendis = eatbyte(*q, outbuf, sizeof(outbuf), bits);
output_ins(offset, q, lendis, outbuf);
q += lendis;
@ -350,7 +325,7 @@ int main(int argc, char **argv)
p -= (q - buffer);
q = buffer;
}
} while (lenread > 0 || !(eof || feof(fp)));
}
if (fp != stdin)
fclose(fp);
@ -362,7 +337,8 @@ static void output_ins(uint64_t offset, const uint8_t *data,
int datalen, const char *insn)
{
int bytes;
fprintf(stdout, "%08"PRIX64" ", offset);
int addrwidth;
addrwidth = fprintf(stdout, "%08"PRIX64" ", offset);
bytes = 0;
while (datalen > 0 && bytes < bpl) {
@ -371,42 +347,57 @@ static void output_ins(uint64_t offset, const uint8_t *data,
datalen--;
}
fprintf(stdout, "%*s%s\n", (bpl + 1 - bytes) * 2, "", insn);
fprintf(stdout, "%*s %s\n", (bpl - bytes) << 1, "", insn);
while (datalen > 0) {
fprintf(stdout, " -");
fprintf(stdout, "%*s", addrwidth, "-");
bytes = 0;
while (datalen > 0 && bytes < bpl) {
fprintf(stdout, "%02X", *data++);
bytes++;
datalen--;
}
fprintf(stdout, "\n");
putchar('\n');
}
}
/*
* Skip a certain amount of data in a file, either by seeking if
* possible, or if that fails then by reading and discarding.
* Returns true if successful, false on EOF; updates posp.
*/
static void skip(uint32_t dist, FILE * fp)
static bool skip(off_t *posp, off_t dist, FILE *fp)
{
char buffer[256]; /* should fit on most stacks :-) */
if (!dist)
return true;
/*
* 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.
* doesn't approve of SEEK_CUR (WHICH ONE?). Weird...
*/
if (fseek(fp, dist + ftell(fp), SEEK_SET)) {
if (!fseeko(fp, *posp + dist, SEEK_SET)) {
*posp += dist;
} else {
off_t pos = ftello(fp);
if (pos != (off_t)-1) {
/* Possibly a partial seek? */
dist -= (pos - *posp);
*posp = pos;
}
while (dist > 0) {
uint32_t len = (dist < sizeof(buffer) ?
dist : sizeof(buffer));
if (fread(buffer, 1, len, fp) < len) {
perror("fread");
exit(1);
}
dist -= len;
static char junk_buf[BUFSIZ];
size_t len = sizeof junk_buf;
size_t skipped;
if (dist < (off_t)len)
len = dist;
skipped = fread(junk_buf, 1, len, fp);
dist -= skipped;
*posp += skipped;
if (skipped < len)
return false; /* EOF */
}
}
return true;
}

View file

@ -1,35 +1,5 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 2025 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ----------------------------------------------------------------------- */
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 2025 The NASM Authors - All Rights Reserved */
#include "disasm.h"
#include "nasmlib.h"

View file

@ -1,35 +1,5 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 1996-2009 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ----------------------------------------------------------------------- */
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2009 The NASM Authors - All Rights Reserved */
/*
* sync.c the Netwide Disassembler synchronisation processing module
@ -41,9 +11,6 @@
#include "nasmlib.h"
#include "sync.h"
#define SYNC_MAX_SHIFT 31
#define SYNC_MAX_SIZE (1U << SYNC_MAX_SHIFT)
/* initial # of sync points (*must* be power of two)*/
#define SYNC_INITIAL_CHUNK (1U << 12)
@ -54,12 +21,12 @@
static struct Sync {
uint64_t pos;
uint32_t length;
uint64_t length;
} *synx;
static uint32_t max_synx, nsynx;
static size_t max_synx, nsynx;
static inline void swap_sync(uint32_t dst, uint32_t src)
static inline void swap_sync(size_t dst, size_t src)
{
struct Sync t = synx[dst];
synx[dst] = synx[src];
@ -73,31 +40,35 @@ void init_sync(void)
nsynx = 0;
}
void add_sync(uint64_t pos, uint32_t length)
void add_sync(uint64_t pos, uint64_t length)
{
uint32_t i;
size_t i;
static bool synx_oom = false;
if (nsynx >= max_synx) {
if (max_synx >= SYNC_MAX_SIZE) /* too many sync points! */
struct Sync *xsynx;
size_t xmaxsynx = max_synx << 1;
if (synx_oom || xmaxsynx < max_synx ||
!(xsynx = realloc(synx, (xmaxsynx + 1) * sizeof(*synx)))) {
synx_oom = true;
return;
max_synx = (max_synx << 1);
synx = nasm_realloc(synx, (max_synx + 1) * sizeof(*synx));
}
}
nsynx++;
synx[nsynx].pos = pos;
synx[nsynx].length = length;
for (i = nsynx; i > 1; i /= 2) {
if (synx[i / 2].pos > synx[i].pos)
swap_sync(i / 2, i);
for (i = nsynx; i > 1; i >>= 1) {
if (synx[i >> 1].pos > synx[i].pos)
swap_sync(i >> 1, i);
}
}
uint64_t next_sync(uint64_t position, uint32_t *length)
uint64_t next_sync(uint64_t position, uint64_t *length)
{
while (nsynx > 0 && synx[1].pos + synx[1].length <= position) {
uint32_t i, j;
size_t i, j;
swap_sync(nsynx, 1);
nsynx--;

View file

@ -1,37 +1,7 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 1996-2009 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ----------------------------------------------------------------------- */
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2009 The NASM Authors - All Rights Reserved */
/*
/*
* sync.h header file for sync.c
*/
@ -39,7 +9,7 @@
#define NASM_SYNC_H
void init_sync(void);
void add_sync(uint64_t position, uint32_t length);
uint64_t next_sync(uint64_t position, uint32_t *length);
void add_sync(uint64_t position, uint64_t length);
uint64_t next_sync(uint64_t position, uint64_t *length);
#endif

View file

@ -1,7 +1,7 @@
\C{16bit} Writing 16-bit Code (DOS, Windows 3/3.1)
This chapter attempts to cover some of the common issues encountered
when writing 16-bit code to run under \c{MS-DOS} or \c{Windows 3.x}. It
when writing 16-bit code to run under \i{MS-DOS} or \i{Windows 3.x}. It
covers how to link programs to produce \c{.EXE} or \c{.COM} files,
how to write \c{.SYS} device drivers, and how to interface assembly
language code with 16-bit C compilers and with Borland Pascal.
@ -835,5 +835,3 @@ and the contents of the pointer. The only difference between this
code and the large-model C version is that \c{PASCAL} is defined
instead of \c{FARCODE}, and that the arguments are declared in
reverse order.

View file

@ -466,13 +466,13 @@ function lives. Either address is a valid way to call the function.
\S{picproc} Calling Procedures Outside the Library
Calling procedures outside your shared library has to be done by
means of a \I\e{procedure linkage table}, or \i{PLT}. The PLT is
placed at a known offset from where the library is loaded, so the
library code can make calls to the PLT in a position-independent
way. Within the PLT there is code to jump to offsets contained in
the GOT, so function calls to other shared libraries or to routines
in the main program can be transparently passed off to their real
Calling procedures outside your shared library has to be done by means
of a \I{PLT relocations}\e{procedure linkage table}, or \i{PLT}. The
PLT is placed at a known offset from where the library is loaded, so
the library code can make calls to the PLT in a position-independent
way. Within the PLT there is code to jump to offsets contained in the
GOT, so function calls to other shared libraries or to routines in the
main program can be transparently passed off to their real
destinations.
To call an external routine, you must use another special PIC

View file

@ -29,9 +29,9 @@ specific size data type is desired, it is probably best to use the
types defined in the standard C header \c{<inttypes.h>}.
All known 64-bit platforms except some embedded platforms require that
the stack is 16-byte aligned at the entry to a function. In order to
enforce that, the stack pointer (\c{RSP}) needs to be aligned on an
\c{odd} multiple of 8 bytes before the \c{CALL} instruction.
the stack is 16-byte aligned at the entry to a function. Specifically,
the stack pointer (\c{RSP}) needs to be 16-byte aligned just before the
\c{CALL} instruction.
In 64-bit mode, the default instruction size is still 32 bits. When
loading a value into a 32-bit register (but not an 8- or 16-bit
@ -51,7 +51,7 @@ mode, for 8-, 16-, 32- and 64-bit references, respectively:
This is consistent with the AMD documentation and most other
assemblers. The Intel documentation, however, uses the names
\c{R8L-R15L} for 8-bit references to the higher registers. It is
possible to use those names by definiting them as macros; similarly,
possible to use those names by defining them as macros; similarly,
if one wants to use numeric names for the low 8 registers, define them
as macros. The standard macro package \c{altreg} (see \k{pkg_altreg})
can be used for this purpose.
@ -62,6 +62,8 @@ In 64-bit mode, immediates and displacements are generally only 32
bits wide. NASM will therefore truncate most displacements and
immediates to 32 bits.
\S{id64imm} Immediate 64-bit Operands
The only instruction which takes a full \i{64-bit immediate} is:
\c MOV reg64,imm64
@ -95,7 +97,9 @@ Note that \c{lea rax,[rel symbol]} is position-independent, whereas
position-independent code in 64-bit mode. However, the \c{MOV}
instruction is able to reference a symbol anywhere in the 64-bit
address space, whereas \c{LEA} is only able to access a symbol within
within 2 GB of the instruction itself (see below.)
within 2 GB of the instruction itself (see below).
\S{id64disp} 64-bit Displacements
The only instructions which take a full \I{64-bit displacement}64-bit
\e{displacement} is loading or storing, using \c{MOV}, \c{AL}, \c{AX},
@ -182,3 +186,16 @@ Integer and SSE register arguments are counted together, so for the case of
\c void foo(long long a, double b, int c)
\c{a} is passed in \c{RCX}, \c{b} in \c{XMM1}, and \c{c} in \c{R8D}.
There is a requirement for functions to allocate a "shadow space" for callees,
prior to calling them, that is owned by the callee. This is for the callee to
(optionally) store the arguments that are passed in via registers (e.g. for
debugging purposes), or in fact any other desired values. This 32-byte shadow
space must be allocated just before the stack space used for non-register
arguments (5th and beyond, if any).
Before a function call, 16-byte stack alignment is required.
Regarding shadow space and stack alignment, an exception is made for leaf
functions, which in Win64 terms means no modification to \c{RSP} at all
(not just having no function calls).

View file

@ -1,20 +1,31 @@
# -*- makefile -*-
# SPDX-License-Identifier: BSD-2-Clause
# Copyright 1996-20xx The NASM Authors - All Rights Reserved
#
# UNIX Makefile for NASM documentation
#
@SET_MAKE@
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
top_srcdir = @top_srcdir@
srcdir = @srcdir@
objdir = @builddir@
VPATH = @srcdir@
prefix = @prefix@
exec_prefix = @exec_prefix@
bindir = @bindir@
mandir = @mandir@
docdir = @docdir@
htmldir = @htmldir@
infodir = @infodir@
datarootdir = @datarootdir@
datadir = @datadir@
mydatadir = $(datadir)/$(PACKAGE_TARNAME)
docdir = @docdir@
htmldir = @htmldir@
pdfdir = @pdfdir@
psdir = @psdir@
emacsdir = $(datarootdir)/emacs/site-lisp
jsondir = $(mydatadir)
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
@ -52,6 +63,9 @@ ALLSRCS = $(SRCS) $(GENSRC)
OUT = html nasmdoc.txt nasmdoc.pdf $(XZFILES)
XZOUT = nasmdoc.pdf.xz
# Use "make install PDFZ=.xz" to install pdf.xz
PDF =
# Don't delete intermediate files
.SECONDARY:
@ -70,14 +84,17 @@ xzfiles: $(XZOUT)
insns.src: inslist.pl ../x86/insns.xda
$(RUNPERL) $^ $@
# A representative HTML file
htmltarget=html/nasm00.html
html: $(HTMLAUX)
$(MKDIR_P) html
for f in $(HTMLAUX); do $(CP_UF) "$(srcdir)/$$f" html/; done
$(MAKE) html/nasmdoc0.html
for f in $(HTMLAUX); do $(CP_F) "$(srcdir)/$$f" html/; done
$(MAKE) $(htmltarget)
RDSRC = $(RUNPERL) $(srcdir)/rdsrc.pl -I$(srcdir) -M$(@F).dep
html/nasmdoc0.html: $(ALLSRCS) rdsrc.pl
$(htmltarget): $(ALLSRCS) rdsrc.pl
$(RM_F) html/*.html
$(RDSRC) -ohtml html $<
@ -118,20 +135,28 @@ nasmdoc.pdf.xz: nasmdoc-raw.pdf
$(XZ) -9e < $< > $@
clean:
-$(RM_F) *.rtf *.hpj *.texi *.gid *.ipf *.dip
-$(RM_F) *.rtf *.hpj *.texi *.gid *.ipf *.dip *.dep
-$(RM_F) *.aux *.cp *.fn *.ky *.pg *.log *.toc *.tp *.vr
-$(RM_F) $(GENSRC)fontpath Fontmap
-$(RM_F) $(GENSRC) fontpath Fontmap
-$(RM_F) nasmdoc*.ps nasmdoc-raw.pdf
spotless: clean
-$(RM_RF) html info
-$(RM_F) *.hlp nasmdoc.txt *.inf *.pdf *.pdf.xz *.dvi
install: all
$(MKDIR_P) $(DESTDIR)$(htmldir)
$(INSTALL_DATA) html/* $(DESTDIR)$(htmldir)
$(MKDIR_P) $(DESTDIR)$(docdir)
$(INSTALL_DATA) nasmdoc.pdf nasmdoc.txt $(DESTDIR)$(docdir)
install_html: html
html='$(htmldir)' ; \
if [ x"$$html" = x'$(docdir)' ]; then \
html="$$html/html" ; \
fi ; \
$(MKDIR_P) $(DESTDIR)"$$html" ; \
$(INSTALL_DATA) html/* $(DESTDIR)"$$html"
install_pdf: nasmdoc.pdf$(PDFZ)
$(MKDIR_P) $(DESTDIR)$(pdfdir)
$(INSTALL_DATA) nasmdoc.pdf$(PDFZ) $(DESTDIR)$(pdfdir)
install: install_html install_pdf
#
# Dummy rules that changes make behavior

View file

@ -15,6 +15,5 @@ To build the entire documentation, the following tools are needed:
Of these, Ghostscript is the most tested, although Acrobat has
been claimed to generate smaller files.
6. For best results, the Adobe fonts Source Sans Pro and Source Code
Pro, available for free at:
https://github.com/adobe-fonts
6. For best results, the Google Roboto and Roboto Mono fonts,
available for free at: https://github.com/googlefonts/

View file

@ -1,36 +1,6 @@
#!/usr/bin/perl
## --------------------------------------------------------------------------
##
## Copyright 1996-2017 The NASM Authors - All Rights Reserved
## See the file AUTHORS included with the NASM distribution for
## the specific copyright holders.
##
## Redistribution and use in source and binary forms, with or without
## modification, are permitted provided that the following
## conditions are met:
##
## * Redistributions of source code must retain the above copyright
## notice, this list of conditions and the following disclaimer.
## * Redistributions in binary form must reproduce the above
## copyright notice, this list of conditions and the following
## disclaimer in the documentation and/or other materials provided
## with the distribution.
##
## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
## CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
## INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
## MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
## DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
## NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
## LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
## HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
## EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
##
## --------------------------------------------------------------------------
# SPDX-License-Identifier: BSD-2-Clause
# Copyright 1996-2017 The NASM Authors - All Rights Reserved
#
# Parse AFM metric file, returns a reference to fontdata

View file

@ -10,6 +10,195 @@ evolving code simpler.
It is the production version of NASM since 2025.
\S{cl-3.02} Version 3.02
\b Fix build problems on C23 compilers using a pre-C23 version of
\c{<stdbool.h>} which defines \c{bool} as a macro in violation of the
C23 specification.
\b The immediate form of the \c{JMPE} instruction (opcode \c{0F B8})
has been changed to an absolute address, as in
the Itanium Architecture Software Developer's Manual, version 2.3,
Volume 4, page 4:249. Hopefully this won't break whatever virtual
environments use \c{JMPE}, but it is the closest thing there is to
an official specification for this opcode.
\> Being an \e{absolute} address, treat it equivalent to a \c{FAR}
jump and do not default to 64 bits in 64-bit mode.
\> That \c{JMPE} has apparently been wrong all these years is probably
as good of a hint as any how much it has been actually used, but it
\e{does} have the possibility of breaking virtual environments. In
that case, please file a bug report to
\W{https://bugs.nasm.us/}\c{https://bugs.nasm.us} with details about the
virtual environment, and we will figure out a suitable solution.
\b Various build fixes. Fix the documentation not building on MacOS
because of the \c{cp} utility lacking \c{-u} there. Also fix not
building generally due to wrong link formatting. Another fix was a
typo in \c{compiler.h} related to a C++ check.
\b Corrections to assembling encodings:
\> Fix \c{CMP} allowing \c{LOCK} which is illegal.
\> Correct multiple \c{AVX512} instructions such as \c{VCVTSD2SI},
\c{VCVTSD2USI}, \c{VCVTSS2SI}, \c{VCVTSS2USI}, \c{VCVTTSD2SI},
\c{VCVTTSD2USI}, \c{VCVTTSS2SI}, \c{VCVTTSS2USI}, \c{VGETEXPSH},
\c{VGETMANTSH}, \c{MOVDDUP}, \c{VMOVDDUP}.
\> Fixed other encodings or instruction formats for instructions \c{UWRMSR},
\c{CMPSD}, \c{VCMPSS}, \c{V4FMADDSS}, \c{V4FNMADDSS}, \c{VCVTDQ2PH},
\c{VCVTPD2PH}, \c{VCVTPH2UDQ}, \c{VCVTQQ2PH}, \c{VCVTUDQ2PH}, \c{VCVTUQQ2PH},
\c{VGETEXPSH}, \c{VGETMANTSH}, \c{VRCPPH}, \c{VRSQRTPH}, \c{VCVTPH2BF8},
\c{VCVTPH2BF8S}, \c{VCVTPH2HF8}, \c{VCVTPH2HF8S}.
\> Fixed typos in \c{VP4DPWSSD} mnemonic.
\> Fixed \c{BYTE} and \c{WORD} operands getting the same encoding on
arithmetic instructions such as \c{CMP}.
\> Fixed \c{PUSH} not assembling when used with a \c{DWORD} in 64-bit
mode. This is not a recommended syntax as the operand size is still
64 bits, but was permitted by earlier versions of NASM.
\> Fix parsing of \c{$}-escaped symbols in directives (\c{GLOBAL},
\c{STATIC}, \c{EXTERN}, \c{REQUIRED}, \c{COMMON}).
\b Corrections to disassembling:
\> Shift instructions with the unity operand were getting disassembled to a zero
operand instead of one.
\> \c{JMP}, \c{CALL} and \c{JMPE} disassembled incorrectly with the
register operands.
\b Whole bunch of minor fixes to operand sizes, operand size prefixes. Changes
mostly return the behavior known from 2.16.03.
\> \c{MOV [mem], label} would be accepted without size specifiers
which could cause unintended consequences. Raise an error if no
size was specified and one of the operands is a memory reference
and another operands is a label.
\> \c{JMP NEAR} is now the same as \c{JMP STRICT NEAR} as the
\c{STRICT} is redundant here. \c{JMP WORD} on the other hand is
up for optimization as \c{NEAR} and \c{WORD} relate to different
things - jump lengths and operation sizes respectively.
\> Using redundant (or not) but valid operands size prefixes was fixed on
instructions such as \c{IRET}, \c{PUSHF}, \c{POPF}, \c{PUSH} and \c{POP}.
\> Using an operand size prefix on a \c{JMP} or \c{CALL} instruction
could generate an invalid instruction. This appears to have been a
long-standing bug. Specifying the operand size by specifying the
size of the immediate explicitly (e.g. \c{JMP DWORD label}) has
always worked correctly, however.
\b Add support for C2y-style \c{\\o} escape sequences, braced escape
sequences, and as NASM extensions, decimal escape sequences
(\c{\\d}) and control-character escape sequences (\c{\\^}). See
\k{strings}.
\b Fix generation of the short opcodes for \c{ADD}, \c{OR}, \c{ADC},
\c{SBB}, \c{AND}, \c{SUB}, \c{XOR}, and \c{CMP AL,imm8}.
\b Fix truncation of the generated constant to 63 bits when invoking a
single-line macro when an argument is defined as \c{=/b} or
\c{=/ub}.
\b Add an \c{%env()} preprocessor function as a more robust and
flexible alternative to the \c{%!} construct. See \k{f_env}.
\b The maximum number of multi-line macro parameters is now a
configurable limit. See \k{opt-limit}.
\b The \c{--limit-} options and \c{%pragma limit} now accept the
keywords \c{default}, \c{maximum}, and \c{reset}. See
\k{opt-limit}.
\b Fix parsing of \c{seg:offs}-style \c{FAR} pointers in \c{EQU}.
\b Fix the \c{%clear} preprocessor directive hanging when given parameters.
\b The never properly implemented (or documented) preprocessor
directives \c{%rmacro} and \c{%irmacro} are now properly disabled; to
avoid breaking existing code, they fall back to \c{%macro} and
\c{%imacro} with a suitable warning.
\> Programmers should \e{not} rely on this behavior: in the future,
these directives might actually be (properly) implemented.
\b Fix a crash when \c{-M} directives were used in response files.
\b New listing option \c{-Lc} to include the contents of \c{INCBIN}
files, see \k{opt-L}.
\b New listing option \c{-Lt} to include the output from every
iteration of \c{TIMES} and \c{ALIGN} directives, see \k{opt-L}.
\b The \c{%pragma list options} directive now support resetting
options to their command-line default, see \k{opt-L}.
\b New predefined macros \c{__?LIST_OPTIONS?__} and
\c{__?LIST_OPTIONS_DEFAULT?__} to query the active and command-line
default listing options. See \k{opt-L}.
\S{cl-3.01} Version 3.01
\b A new \c{obj2} version of the \c{obj} output format, intended for
use on OS/2. See \k{obj2fmt}.
\b The condition after \c{%if} or \c{%elif} would be evaluated while
output is suppressed after \c{%exitrep} or \c{%exitmacro}. Although
no output would be generated in either case, assembly would fail if
evaluating the expression triggered an error.
\b Fix encoding of \c{TCVTROWPS2PHL}, correct multiple AVX512-BF16
instructions' operand formats and typoed mnemonics.
\b The unofficial but obvious alternate form \c{TEST reg,mem} was not
accepted by NASM 3.00; corrected.
\b For the \c{obj} output format, multiple \c{GROUP} directives can
now be specified for the same group; the resulting group includes
all sections specified in all \c{GROUP} directives for the group.
\b A new \c{%selbits()} preprocessor function. See \k{f_selbits}.
\b A new \c{--bits} option as convenience shorthand for \c{--before
"BITS ..."}. See \k{opt-bits}.
\b The options and pragmas for configuring external label mangling
were inconsistent, the former using the spelling \c{postfix} and
the latter \c{suffix}. Furthermore, these were also documented as
\e{directives} in addition to pragmas. Implement the already
documented directives (bracketed forms only) and allow both
\c{postfix} and \c{suffix} in all cases.
\> See \k{opt-pfix} and \k{mangling}.
\b Define additional permissive patterns and fix several opcode bugs.
\b Fix parsing of two-operand forms of x87 instructions.
\b Fix bogus "absolute address can not be RIP-relative" warning.
\b Hopefully fix building with OpenWatcom.
\b Generate a warning, promoted to error by default, on the use of
\c{o64} prefixes in 16- or 32-bit mode. If demoted to a warning or
suppressed the prefix is ignored, but likely will trigger
subsequent, harder to debug, error messages.
\b More consistent handling of jump and call instructions with
specified operand sizes.
\b Fix an operand size handling bug in the \c{CMPXCHG} instruction.
\S{cl-3.00} Version 3.00
\b Improve the documentation for building from source (\k{source}).
@ -67,6 +256,28 @@ It is the production version of NASM since 2025.
implemented conditional directive, and tries to match it with a
corresponding \c{%endif}. See \k{if_caveat}.
\b The \c{masm} macro package now defines a macro for x87 register
syntax. See \k{pkg_masm}.
\b A new macro package, \c{vtern}, to simplify generation of the
control immediates for the \c{VPTERNLOGD} and \c{VPTERNLOGQ}
instructions. See \k{pkg_vtern}.
\b A new command line option \c{-LF} allows overriding \c{[LIST -]}
directives.
\b In the \c{obj} output format, allow a segment in the \c{FLAT}
pseudo-group to also belong to another (real) group. Used on OS/2.
\b Add a new \c{build_version} directive to the Mach-O backend. See
\k{macho-bver}.
\b Fix a spec violation in the generation of DWARF debugging
information on ELF.
\b Response files can now be nested.
\b Many documentation improvements.
\H{cl-2.xx} NASM 2 Series
@ -2717,7 +2928,7 @@ an error.
specification warning when sizes agree).
\H{cl-0.9x} NASM 0.9 Series
\H{cl-0.9x} NASM 0.90-0.97
Revisions before 0.98.

View file

@ -71,7 +71,7 @@ necessary.
When the \c{REX} prefix is used, the processor does not know how to
address the AH, BH, CH or DH (high 8-bit legacy) registers. Instead,
it is possible to access the the low 8-bits of the SP, BP SI and DI
it is possible to access the the low 8-bits of the SP, BP, SI and DI
registers as SPL, BPL, SIL and DIL, respectively; but only when the
REX prefix is used.
@ -402,26 +402,38 @@ global variables).
Unlike \c{GLOBAL}, \c{STATIC} does not allow object formats to accept
private extensions mentioned in \k{global}.
\H{mangling} \i\c{(G|L)PREFIX}, \i\c{(G|L)POSTFIX}: Mangling Symbols
\IR{PREFIX} \c{[PREFIX]}
\IC{PREFIX}{GPREFIX} \c{[GPREFIX]}
\IC{PREFIX}{LPREFIX} \c{[LPREFIX]}
\IC{PREFIX}{SUFFIX} \c{[SUFFIX]}
\IC{PREFIX}{GSUFFIX} \c{[GSUFFIX]}
\IC{PREFIX}{LSUFFIX} \c{[LSUFFIX]}
\IC{PREFIX}{POSTFIX} \c{[POSTFIX]}
\IC{PREFIX}{GPOSTFIX} \c{[GPOSTFIX]}
\IC{PREFIX}{LPOSTFIX} \c{[LPOSTFIX]}
\c{PREFIX}, \c{GPREFIX}, \c{LPREFIX}, \c{POSTFIX}, \c{GPOSTFIX}, and
\c{LPOSTFIX} directives can prepend or append a string to a certain
\H{mangling} \I{PREFIX}\c{[[GL]PREFIX]}, \c{[[GL]SUFFIX]}: Mangling Symbols
\c{[PREFIX]}, \c{[GPREFIX]}, \c{[LPREFIX]}, \c{[SUFFIX]}, \c{[GSUFFIX]}, and
\c{[LSUFFIX]} directives can prepend or append a string to a certain
type of symbols, normally to fit specific ABI conventions
\b\c{PREFIX}|\c{GPREFIX}: Prepend the argument to all \c{EXTERN},
\b\c{[PREFIX]}, \c{[GPREFIX]}: Prepend the argument to all \c{EXTERN},
\c{COMMON}, \c{STATIC}, and \c{GLOBAL} symbols.
\b\c{LPREFIX}: Prepend the argument to all other symbols
\b\c{[LPREFIX}: Prepend the argument to all other symbols
such as local labels and backend defined symbols.
\b\c{POSTFIX}|\c{GPOSTFIX}: Append the argument to all \c{EXTERN},
\c{COMMON}, \c{STATIC}, and \c{GLOBAL} symbols.
\b\c{[SUFFIX]}, \c{[GSUFFIX]}, \c{[POSTFIX]}, \c{[GPOSTFIX]}: Append
the argument to all \c{EXTERN}, \c{COMMON}, \c{STATIC}, and
\c{GLOBAL} symbols.
\b\c{LPOSTFIX}: Append the argument to all other symbols
\b\c{[LSUFFIX]}, \c{[LPOSTFIX]}: Append the argument to all other symbols
such as local labels and backend defined symbols.
These are macros implemented as pragmas, and using \c{%pragma} syntax
can be restricted to specific backends (see \k{pragma}):
These directives are also implemented as pragmas, and using
\c{%pragma} syntax can be restricted to specific backends (see
\k{pragma}):
\c %pragma macho lprefix L_
@ -443,13 +455,19 @@ naming scheme to chunk up sections into smaller subsections, each of
which may be eliminated. When the \c{subsections_via_symbols}
directive (\k{macho-ssvs}) is declared, each symbol is the start of a
separate block. The subsection is, then, defined to include sections
before the one that starts with a 'L'. \c{LPREFIX} is useful here to
before the one that starts with a 'L'. \c{[LPREFIX]} is useful here to
mark all local symbols with the 'L' prefix to be excluded to the meta
section. It converts local symbols compatible with the particular
toolchain. Note that local symbols declared with \c{STATIC}
(\k{static}) are excluded from the symbol mangling and also not marked
as global.
Earlier versions of NASM called the pragmas \i\c{suffix} and the
options \i\c{--postfix}, and did not implement directives at all
despite being so documented. Since NASM 3.01, the directive forms are
implemented, and directives, pragmas and options all support all
spellings.
\H{CPU} \i\c{CPU}: Defining CPU Dependencies
@ -549,6 +567,8 @@ it completely:
When disabled, symbols beginning with digits can be escaped as well,
e.g. \c{$3} would define a symbol \c{3}.
No "user form" (without the brackets) currently exists.
\H{FLOAT} \i\c{FLOAT}: Handling of \I{floating-point, constants}floating-point constants
@ -572,7 +592,7 @@ this behaviour:
The standard macros \i\c{__?FLOAT_DAZ?__}, \i\c{__?FLOAT_ROUND?__}, and
\i\c{__?FLOAT?__} contain the current state, as long as the programmer
has avoided the use of the brackeded primitive form, (\c{[FLOAT]}).
has avoided the use of the bracketed primitive form, (\c{[FLOAT]}).
\c{__?FLOAT?__} contains the full set of floating-point settings; this
value can be saved away and invoked later to restore the setting.
@ -602,3 +622,15 @@ The \c{[WARNING]} directive also accepts the \c{all}, \c{error} and
\c{error=}\e{warning-class} specifiers, see \k{opt-w}.
No "user form" (without the brackets) currently exists.
\H{LIST} \i\c{[LIST]}: Locally disable list file output
The \c{[LIST]} directive disables or re-enables list file output.
\b \c{[list -]} disables list file output.
\b \c{[list +]} re-enables list file output.
The \c{[LIST]} directive can be overridden with the \c{-LF}
command-line option, see \k{opt-L}.

View file

@ -1,36 +1,6 @@
#!/usr/bin/perl
## --------------------------------------------------------------------------
##
## Copyright 1996-2017 The NASM Authors - All Rights Reserved
## See the file AUTHORS included with the NASM distribution for
## the specific copyright holders.
##
## Redistribution and use in source and binary forms, with or without
## modification, are permitted provided that the following
## conditions are met:
##
## * Redistributions of source code must retain the above copyright
## notice, this list of conditions and the following disclaimer.
## * Redistributions in binary form must reproduce the above
## copyright notice, this list of conditions and the following
## disclaimer in the documentation and/or other materials provided
## with the distribution.
##
## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
## CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
## INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
## MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
## DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
## NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
## LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
## HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
## EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
##
## --------------------------------------------------------------------------
# SPDX-License-Identifier: BSD-2-Clause
# Copyright 1996-2017 The NASM Authors - All Rights Reserved
#
# Try our best to find a specific PostScipt font in the system.
@ -71,7 +41,7 @@ sub add_file_to_font_hash($) {
return unless (defined($fontdata));
$fontdata->{filename} = $filename;
my $oldinfo = $font_info_hash{$fontdata->{name}};
if (!defined($oldinfo) ||

View file

@ -1,36 +1,6 @@
#!/usr/bin/perl
## --------------------------------------------------------------------------
##
## Copyright 1996-2020 The NASM Authors - All Rights Reserved
## See the file AUTHORS included with the NASM distribution for
## the specific copyright holders.
##
## Redistribution and use in source and binary forms, with or without
## modification, are permitted provided that the following
## conditions are met:
##
## * Redistributions of source code must retain the above copyright
## notice, this list of conditions and the following disclaimer.
## * Redistributions in binary form must reproduce the above
## copyright notice, this list of conditions and the following
## disclaimer in the documentation and/or other materials provided
## with the distribution.
##
## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
## CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
## INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
## MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
## DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
## NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
## LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
## HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
## EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
##
## --------------------------------------------------------------------------
# SPDX-License-Identifier: BSD-2-Clause
# Copyright 1996-2020 The NASM Authors - All Rights Reserved
#
# Format the documentation as PostScript

View file

@ -26,8 +26,9 @@
\IR{-p} \c{-p} option
\IR{-s} \c{-s} option
\IR{-u} \c{-u} option
\IR{-v} \c{-v} option
\IR{-W} \c{-W} option
\IR{-t} \c{-t} option
\IR{-soname} \c{-soname}, linker option
\IR{-Werror} \c{-Werror} option
\IR{-Wno-error} \c{-Wno-error} option
\IR{-w} \c{-w} option
@ -115,8 +116,7 @@
\IA{case-insensitive}{case sensitive}
\IA{character constants}{character constant}
\IR{codeview debugging format} CodeView debugging format
\IR{continuation line} continuation line
\IC{continuation line}{preprocessor, continuation line}
\IR{continuation} continuation line
\IR{common object file format} Common Object File Format
\IR{common variables, alignment in elf} common variables, alignment in ELF
\IR{common, elf extensions to} \c{COMMON}, ELF extensions to
@ -124,6 +124,7 @@
\IR{declaring structure} declaring structures
\IR{default-wrt mechanism} default-\c{WRT} mechanism
\IR{devpac} DevPac
\IR{dfv} DFV
\IR{djgpp} DJGPP
\IR{dll symbols, exporting} DLL symbols, exporting
\IR{dll symbols, importing} DLL symbols, importing
@ -194,6 +195,8 @@
\IR{boolean or} boolean, OR
\IR{boolean xor} boolean, XOR
\IR{netbsd} NetBSD
\IA{.nolist}{nolist}
\IR{nolist} \c{.nolist}
\IR{nsis} NSIS
\IR{nullsoft scriptable installer} Nullsoft Scriptable Installer
\IA{.OBJ}{.obj}
@ -251,10 +254,14 @@
\IR{thread local storage in mach-o} thread local storage, in Mach-O
\IR{macho} Mach-O
\IR{tlink} \c{TLINK}
\IR{tls} \c{TLS}
\IA{tls}{thread local storage}
\IR{unconditionally importing symbols} importing symbols, unconditionally
\IR{underscore, in c symbols} underscore, in C symbols
\IA{uninitialized}{uninitialized storage}
\IR{uninitialized} uninitialized storage
\IC{uninitialized storage}{storage, uninitialized}
\IC{RESB}{uninitialized, resb} uninitialized storage, \c{RES}\e{x}
\IC{?db}{uninitialized, db} uninitialized storage, \c{D}\e{x}\e{ ?}
\IR{unicode} Unicode
\IR{unix} Unix
\IR{utf-8} Unicode, UTF-8
@ -287,8 +294,24 @@
\IC{unknown %if}{unknown %elif} \c{%elif}, backwards compatibility
\IC{unknown %if}{unknown %ifn} \c{%ifn}, backwards compatibility
\IC{unknown %if}{unknown %elifn} \c{%elifn}, backwards compatibility
\IR{apx} APX
\IR{advanced programming extensions} Advanced Programming Extensions
\IA{egprs}{egpr}
\IR{egpr} EGPR
\IC{egpr}{extended general purpose register}
\IA{extended general purpose registers}{egpr}
\IR{apx syntax} APX, syntax
\IC{apx syntax}{syntax, apx} syntax, APX
\IR{scc} S\e{cc}
\IR{apx optimizer} APX, optimizer
\# \IC{program entry point}{entry point, program}
\# \IC{program entry point}{start point, program}
\# \IC{MS-DOS device drivers}{device drivers, MS-DOS}
\# \IC{16-bit mode, versus 32-bit mode}{32-bit mode, versus 16-bit mode}
\# \IC{c symbol names}{symbol names, in C}
\IR{WRT ..got} \c{WRT}, \c{..got}
\IR{WRT ..gotoff} \c{WRT}, \c{..gotoff}
\IR{WRT ..gotpc} \c{WRT}, \c{..gotpc}
\IR{WRT ..plt} \c{WRT}, \c{..plt}
\IR{WRT ..sym} \c{WRT}, \c{..sym}
\IR{rex2} REX2 prefix

View file

@ -1,36 +1,6 @@
#!/usr/bin/perl
## --------------------------------------------------------------------------
##
## Copyright 1996-2024 The NASM Authors - All Rights Reserved
## See the file AUTHORS included with the NASM distribution for
## the specific copyright holders.
##
## Redistribution and use in source and binary forms, with or without
## modification, are permitted provided that the following
## conditions are met:
##
## * Redistributions of source code must retain the above copyright
## notice, this list of conditions and the following disclaimer.
## * Redistributions in binary form must reproduce the above
## copyright notice, this list of conditions and the following
## disclaimer in the documentation and/or other materials provided
## with the distribution.
##
## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
## CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
## INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
## MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
## DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
## NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
## LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
## HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
## EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
##
## --------------------------------------------------------------------------
# SPDX-License-Identifier: BSD-2-Clause
# Copyright 1996-2024 The NASM Authors - All Rights Reserved
#
# inslist.pl produce inslist.src

View file

@ -93,11 +93,10 @@ Pseudo-instructions are things which, though not real x86 machine
instructions, are used in the instruction field anyway because that's
the most convenient place to put them. The current pseudo-instructions
are \i\c{DB}, \i\c{DW}, \i\c{DD}, \i\c{DQ}, \i\c{DT}, \i\c{DO},
\i\c{DY} and \i\c\{DZ}; their \I{storage,
uninitialized}\i{uninitialized} counterparts \i\c{RESB}, \i\c{RESW},
\i\c{RESD}, \i\c{RESQ}, \i\c{REST}, \i\c{RESO}, \i\c{RESY} and
\i\c\{RESZ}; the \i\c{INCBIN} command, the \i\c{EQU} command, and the
\i\c{TIMES} prefix.
\i\c{DY} and \i\c\{DZ}; their \i{uninitialized} counterparts
\i\c{RESB}, \i\c{RESW}, \i\c{RESD}, \i\c{RESQ}, \i\c{REST},
\i\c{RESO}, \i\c{RESY} and \i\c\{RESZ}; the \i\c{INCBIN} command, the
\i\c{EQU} command, and the \i\c{TIMES} prefix.
In this documentation, the notation "\c{D}\e{x}" and "\c{RES}\e{x}" is
used to indicate all the \c{DB} and \c{RESB} type directives,
@ -132,7 +131,7 @@ can be invoked in a wide range of ways:
\I{masmdb} Starting in NASM 2.15, a the following \i{MASM}-like features
have been implemented:
\b A \I{?db}\c{?} argument to declare \i{uninitialized storage}:
\b A \I{?db}\c{?} argument to declare \i{uninitialized} storage:
\c db ? ; uninitialized
@ -371,24 +370,9 @@ In 64-bit mode, NASM will by default generate absolute addresses. The
this is frequently the normally desired behaviour, see the \c{DEFAULT}
directive (\k{default}). The keyword \i\c{ABS} overrides \i\c{REL}.
A new form of split effective address syntax is also supported. This is
mainly intended for mib operands as used by MPX instructions, but can
be used for any memory reference. The basic concept of this form is
splitting base and index.
\c mov eax,[ebx+8,ecx*4] ; ebx=base, ecx=index, 4=scale, 8=disp
For mib operands, there are several ways of writing effective address depending
on the tools. NASM supports all currently possible ways of mib syntax:
\c ; bndstx
\c ; next 5 lines are parsed same
\c ; base=rax, index=rbx, scale=1, displacement=3
\c bndstx [rax+0x3,rbx], bnd0 ; NASM - split EA
\c bndstx [rbx*1+rax+0x3], bnd0 ; GAS - '*1' indecates an index reg
\c bndstx [rax+rbx+3], bnd0 ; GAS - without hints
\c bndstx [rax+0x3], bnd0, rbx ; ICC-1
\c bndstx [rax+0x3], rbx, bnd0 ; ICC-2
A new syntax for split EA (effective addressing) is also supported in NASM. It's
mainly intended for MPX instructions that use the MIB operands, but it can be
used for any memory reference. It's described in more detail in \k{spliteas}.
When broadcasting decorator is used, the opsize keyword should match
the size of each element.
@ -410,7 +394,7 @@ numbers in a variety of number bases, in a variety of ways: you can
suffix \c{H} or \c{X}, \c{D} or \c{T}, \c{Q} or \c{O}, and \c{B} or
\c{Y} for \i{hexadecimal}, \i{decimal}, \i{octal} and \i{binary}
respectively, or you can prefix \c{0h} or \c{0x}, \c{0d} or \c{0t},
\c{0q} or \c{0o}, and \c{0b} or \c{0y) in the style of C. Please note
\c{0q} or \c{0o}, and \c{0b} or \c{0y}) in the style of C. Please note
that unlike C, a \c{0} prefix by itself does \e{not} imply an octal
constant (this is deprecated in C23.)
@ -452,13 +436,12 @@ Some examples (all producing exactly the same code):
A character string consists of up to eight characters enclosed in
either single quotes (\c{'...'}), double quotes (\c{"..."}) or
backquotes (\c{`...`}). Single or double quotes are equivalent to
backquotes (\c{`...`}). Single or double quotes are equivalent in
NASM (except of course that surrounding the constant with single
quotes allows double quotes to appear within it and vice versa); the
contents of those are represented verbatim. Strings enclosed in
backquotes support C-style \c{\\}-escapes for special characters.
The following \i{escape sequences} are recognized by backquoted strings:
\c \' single quote (')
@ -479,6 +462,24 @@ The following \i{escape sequences} are recognized by backquoted strings:
\c \u1234 4 hexadecimal digits - Unicode character
\c \U12345678 8 hexadecimal digits - Unicode character
NASM 3.02 added the following additional sequences:
\c \o377 Up to 3 octal digits - literal byte (from C2y)
\c \d255 Up to 3 decimal digits - literal byte (NASM extension)
\c \^? ASCII DEL (\d127, \177)
\c \^X Convert X to a control character (e.g. \cA = \ca = \001)
Since NASM 3.02, the numeric escape sequences starting with \c{\\x},
\c{\\o}, \c{\\d} or \c{\\u} can have their argument enclosed in curly
braces to delimit their length, instead of terminating after a certain
number of digits or a non-digit another character:
\c \x{FF} Hexadecimal, literal byte
\c \o{377} Octal, literal byte
\c \d{255} Decimal, literal byte
\c \u{1234} Unicode character
\c \u{12345} Unicode character
All other escape sequences are reserved. Note that \c{\\0}, meaning a
\c{NUL} character (ASCII 0), is a special case of the octal escape
sequence.
@ -487,6 +488,8 @@ sequence.
\i{UTF-8}. For example, the following lines are all equivalent:
\c db `\u263a` ; UTF-8 smiley face
\c db `\U0000263a` ; UTF-8 smiley face
\c db `\u{263a}` ; UTF-8 smiley face
\c db `\xe2\x98\xba` ; UTF-8 smiley face
\c db 0E2h, 098h, 0BAh ; UTF-8 smiley face
@ -513,7 +516,7 @@ the sense of character constants understood by the Pentium's
String constants are character strings used in the context of some
pseudo-instructions, namely the
\I\c{DW}\I\c{DD}\I\c{DQ}\I\c{DT}\I\c{DO}\I\c{DY}\i\c{DB} family and
\i\c{INCBIN} (where it represents a filename.) They are also used in
\i\c{INCBIN} (where it represents a filename). They are also used in
certain preprocessor directives.
A string constant looks like a character constant, only longer. It
@ -536,14 +539,14 @@ effect as \c{db 'a'}, which would be silly. Similarly, three-character
or four-character constants are treated as strings when they are
operands to \c{DW}, and so forth.
\S{unicode} \I{UTF-8}I{UTF-16}\I{UTF-32}\i{Unicode} Strings
\S{unicode} \I{UTF-8}\I{UTF-16}\I{UTF-32}\i{Unicode} Strings
The special operators \i\c{__?utf16?__}, \i\c{__?utf16le?__},
\i\c{__?utf16be?__}, \i\c{__?utf32?__}, \i\c{__?utf32le?__} and
\i\c{__?utf32be?__} allows definition of Unicode strings. They take a
string in UTF-8 format and converts it to UTF-16 or UTF-32,
respectively. Unless the \c{be} forms are specified, the output is
littleendian.
little endian.
For example:
@ -707,13 +710,13 @@ characters.
\S{expbor}: \i\c{||}: \i{Boolean OR} Operator
The \c{||} operator gives a boolean OR: it evaluates to 1 if both sides of
the expression are nonzero, otherwise 0.
The \c{||} operator gives a boolean OR: it evaluates to 1 if either side of
the expression is nonzero, otherwise 0.
\S{expbxor}: \i\c{^^}: \i{Boolean XOR} Operator
The \c{^^} operator gives a boolean XOR: it evaluates to 1 if any one side of
The \c{^^} operator gives a boolean XOR: it evaluates to 1 if exactly one side of
the expression is nonzero, otherwise 0.
@ -861,30 +864,12 @@ preferred one. NASM lets you do this, by the use of the \c{WRT}
to load \c{ES:BX} with a different, but functionally equivalent,
pointer to the symbol \c{symbol}.
NASM supports far (inter-segment) calls and jumps by means of the
syntax \c{call segment:offset}, where \c{segment} and \c{offset}
both represent immediate values. So to call a far procedure, you
could code either of
The \c{WRT} keyword is also used in far (inter-segment) calls and jumps. It's
synonymous to the
\c call (seg procedure):procedure
\c call weird_seg:(procedure wrt weird_seg)
(The parentheses are included for clarity, to show the intended
parsing of the above instructions. They are not necessary in
practice.)
NASM supports the syntax \I\c{CALL FAR}\c{call far procedure} as a
synonym for the first of the above usages. \c{JMP} works identically
to \c{CALL} in these examples.
To declare a \i{far pointer} to a data item in a data segment, you
must code
\c dw symbol, seg symbol
NASM supports no convenient synonym for this, though you can always
invent one using the macro processor.
\c call far procedure
syntax which is documented in \k{farcall}.
\H{strict} \i\c{STRICT}: Inhibiting Optimization
@ -1007,6 +992,7 @@ NASM has the capacity to define other special symbols beginning with
a double period: for example, \c{..start} is used to specify the
entry point in the \c{obj} output format (see \k{dotdotstart}),
\c{..imagebase} is used to find out the offset from a base address
of the current image in the \c{win64} output format (see \k{win64pic}).
of the current image in the \c{win64} output format (see \k{win64pic}),
\c{..symtab} is used to emit the COFF symbol table index (see \k{win32wrt}).
So just keep in mind that symbols beginning with a double period are
special.

View file

@ -17,9 +17,9 @@ NASM (\c{%ifusable}) or a particular package already loaded (\c{%ifusing}).
The \c{altreg} standard macro package provides alternate register
names. It provides numeric register names for all registers (not just
\c{R8}-\c{R15}), the Intel-defined aliases \c{R8L}-\c{R15L} for the
low bytes of register (as opposed to the NASM/AMD standard names
\c{R8B}-\c{R15B}), and the names \c{R0H}-\c{R3H} (by analogy with
\c{R8}-\c{R31}), the Intel-defined aliases \c{R8L}-\c{R31L} for the
low bytes of registers (as opposed to the NASM/AMD standard names
\c{R8B}-\c{R31B}), and the names \c{R0H}-\c{R3H} (by analogy with
\c{R0L}-\c{R3L}) for \c{AH}, \c{CH}, \c{DH}, and \c{BH}.
Example use:
@ -30,12 +30,12 @@ Example use:
\c mov r0l,r3h ; mov al,bh
\c ret
See also \k{reg64}.
See also \k{reg64} and \k{egprs}.
\H{pkg_smartalign} \i\c{smartalign}\I{align, smart}: Smart \c{ALIGN} Macro
The \c{smartalign} standard macro package provides for an \i\c{ALIGN}
The \c{smartalign} standard macro package provides an \i\c{ALIGN}
macro which is more powerful than the default (and
backwards-compatible) one (see \k{align}). When the \c{smartalign}
package is enabled, when \c{ALIGN} is used without a second argument,
@ -144,24 +144,24 @@ To enable the package, use the directive:
Currently, the MASM compatibility package emulates:
\b The \c{FLAT} and \c{OFFSET} keywords are recognized and ignored.
\b The \i\c{FLAT} and \i\c{OFFSET} keywords are recognized and ignored.
\b The \c{PTR} keyword signifies a memory reference, as if the
\b The \i\c{PTR} keyword signifies a memory reference, as if the
argument had been put in square brackets:
\c mov eax,[foo] ; memory reference
\c mov eax,dword ptr foo ; memory reference
\c mov eax,dowrd ptr flat:foo ; memory reference
\c mov eax,dword ptr flat:foo ; memory reference
\c mov eax,offset foo ; address
\c mov eax,foo ; address (ambiguous syntax in MASM)
\b The \c{SEGMENT} ... \c{ENDS} syntax:
\b The \i\c{SEGMENT} ... \i\c{ENDS} syntax:
\c segname SEGMENT
\c ...
\c segname ENDS
\b The \c{PROC} ... \c{ENDP} syntax:
\b The \i\c{PROC} ... \i\c{ENDP} syntax:
\c procname PROC [FAR]
\c ...
@ -171,13 +171,16 @@ argument had been put in square brackets:
\c{RETF} if \c{FAR} is specified and \c{RETN} otherwise. Any keyword
after \c{PROC} other than \c{FAR} is ignored.
\b The \c{TBYTE} keyword as an alias for \c{TWORD} (see \k{qsother}).
\b The \i\c{TBYTE} keyword as an alias for \c{TWORD} (see \k{qsother}).
\b The \c{END} directive is ignored.
\b The \i\c{END} directive is ignored.
\b In 64-bit mode relative addressing is the default (\c{DEFAULT REL},
see \k{default-rel}).
\b A macro is defined to allow using the syntax \c{ST(0)} instead of
\c{ST0} (and so on) for the x87 stack registers.
In addition, NASM now natively supports, regardless of whether this
package is used or not:
@ -193,3 +196,9 @@ of \c{[base+index+displacement]}.
\c lea rax,[foo] ; standard syntax
\c lea rax,foo ; also accepted
\H{pkg_vtern} \i\c{vtern}: Ternary Logic Assist
The \c{vtern} macro package allows for a simple and clear way of
defining the immediate operand to the \i\c{VPTERNLOGD} and
\i\c{VPTERNLOGQ} instructions. See \k{ternarylogic} for a description.

View file

@ -1,119 +1,174 @@
body {
font-family: "source sans pro", "clear sans", "liberation sans",
font-family: "roboto", "source sans pro", "clear sans", "liberation sans",
"arial", "sans-serif";
background: white;
}
div.title {
text-align: center;
font-weight: bold;
margin: 0.67em 0;
}
h1 {
font-size: 2em;
margin: 0;
font-size: 250%;
font-weight: bold;
}
h2 {
font-size: 200%;
font-weight: bold;
}
div.contents h2 {
text-decoration: underline;
}
.title h1 {
margin-bottom: 0;
}
.title h2 {
font-size: 128%;
font-style: italic;
margin-top: 0;
}
h3 {
font-size: 160%;
font-weight: bold;
}
h4 {
font-size: 128%;
font-weight: bold;
}
h5 {
font-size: 100%;
font-weight: bold;
}
h6 {
font-size: 100%;
text-decoration: underline;
}
span.subtitle {
font-size: 1.25em;
font-style: italic;
}
code, pre {
font-family: "source code pro", "liberation mono", "monospace";
font-size: 80%;
font-family: "roboto mono", "source code pro", "liberation mono", "monospace";
font-size: 90%;
}
pre {
background: #f0f0f0;
}
#appendix-F ~ pre {
font-size: 75%;
background: white;
}
code {
font-weight: bolder;
}
pre, blockquote {
margin-left: 4em;
margin-right: 4em;
padding: 0.25em 0.4em;
}
code {
display: inline;
white-space: nowrap;
/* Extra padding due to monospaced font */
padding-left: 0.2em;
padding-right: 0.2em;
}
a {
text-decoration: none;
}
div.toc {
padding-left: 0;
font-size: 195%;
}
div.toc li {
list-style-type: none;
padding-left: 0;
}
div.toc ol {
padding-left: 2em;
font-size: 80%;
list-style-type: none;
}
li.toc1 {
div.toc ol.toc1 {
/* Compensate for the size reduction for each level */
font-size: 150%;
}
/* -- TOC numbering using data-name attribute -- */
ol li[data-name]::marker {
content: attr(data-name) '.';
}
ol.toc1 > li {
padding-left: 1em;
padding-top: 0.7em;
font-weight: bold;
}
li.toc2 {
ol.toc2 > li {
padding-top: 0.3em;
}
.index li {
ol.toc2 li {
padding-left: 0.4em;
font-weight: normal;
}
div.toc span.node {
display: none;
}
div.index li {
list-style-type: none;
display: flex;
flex-direction: row;
justify-content: space-between;
}
.index .term {
div.index .term {
display: inline-block;
text-align: left;
vertical-align: top;
flex: 3 3 0;
}
.index .ref {
div.index .ref {
width: 30%;
display: inline-block;
text-align: right;
vertical-align: top;
flex: 1 1 0;
}
div.toc, div.chapter, div.appendix {
column-width: 42em;
}
div.index {
column-width: 20em;
margin-right: 3em;
}
div.index li {
padding-left: 1em;
padding-right: 1em;
}
div.index > ul {
padding-left: 0;
}
/* This is overridden for @media screen */
ul.navbar {
nav {
display: none;
}
@media print {
a {
color: inherit;
}
ul.navbar div.title {
nav {
display: none !important;
}
div.index {
-webkit-column-gap: 2em;
-moz-column-gap: 2em;
column-gap: 2em;
-webkit-column-count: 2;
-moz-column-count: 2;
column-count: 2;
}
}
@media screen {
div.contents {
-webkit-column-gap: 4em;
-webkit-column-rule: 1px dotted black;
-moz-column-gap: 4em;
-moz-column-rule: 1px dotted black;
column-gap: 4em;
column-rule: 1px dotted black;
}
}
@media only screen and (min-width: 90em) {
/* For a very wide screen, go to a columnar layout */
div.contents {
-webkit-column-count: 2;
-moz-column-count: 2;
column-count: 2;
div.toc, div.chapter, div.appendix {
-webkit-column-gap: 4em;
-moz-column-gap: 4em;
column-gap: 4em;
}
}
@media only screen and (min-width: 135em) {
div.contents {
-webkit-column-count: 3;
-moz-column-count: 3;
column-count: 3;
div.index {
-webkit-column-gap: 1em;
-moz-column-gap: 1em;
column-gap: 1em;
}
}
@media screen {
/* Setting an explicit margin to keep the navbar from moving */
body {
padding: 0;
@ -143,39 +198,53 @@ ul.navbar {
background-clip: content-box;
}
ul.navbar {
nav {
display: block;
position: sticky;
top: 8px;
width: 100%;
margin: 0;
padding: 0;
overflow: hidden;
white-space: nowrap;
list-style-type: none;
background: #336 url("nasmlogw.png") no-repeat right center;
background: #336 url("nasmlogw.png") no-repeat right center;
background-size: contain;
}
ul.navbar li {
float: left;
white-space: collapse;
}
ul.navbar li.last {
border-right: none;
nav ul {
margin: 0;
padding: 0;
display: inline-block;
list-style-type: none;
}
ul.navbar a {
nav li {
margin: 0;
padding: 0;
display: inline-block;
}
nav li a {
margin: 0;
border-right: 1px solid #bbb;
display: block;
color: white;
text-align: center;
padding: 1em 1.5em;
padding: 0.75em 0.75em;
text-decoration: none;
color: white;
white-space: nowrap;
background-color: #336;
}
ul.navbar a:hover {
nav li.navthis a {
background-color: #55c;
}
nav li a:hover {
background-color: #448;
}
.index li:hover {
nav li.navthis a:hover {
background-color: #55c;
}
nav li a:link, nav li a:visited, nav li a:hover {
color: white;
}
div.index li:hover {
background: #eef;
}
}

View file

@ -1,36 +1,9 @@
\# SPDX-License-Identifier: BSD-2-Clause
\# Copyright 1996-2025 The NASM Authors - All Rights Reserved
\# --------------------------------------------------------------------------
\#
\# Copyright 1996-2025 The NASM Authors - All Rights Reserved
\M{year}{1996-2025}
\# See the file AUTHORS included with the NASM distribution for
\# the specific copyright holders.
\#
\# Redistribution and use in source and binary forms, with or without
\# modification, are permitted provided that the following
\# conditions are met:
\#
\# * Redistributions of source code must retain the above copyright
\# notice, this list of conditions and the following disclaimer.
\# * Redistributions in binary form must reproduce the above
\# copyright notice, this list of conditions and the following
\# disclaimer in the documentation and/or other materials provided
\# with the distribution.
\#
\# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
\# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
\# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
\# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
\# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
\# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
\# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
\# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
\# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
\# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
\# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
\# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
\# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\#
\# --------------------------------------------------------------------------
\#
\# Source code to NASM documentation
\#
@ -66,6 +39,8 @@ source.}
\& lang.src
\& syntax.src
\& preproc.src
\& stdmac.src
@ -92,12 +67,22 @@ source.}
\& ndisasm.src
\# Keep the changelog as Appendix C if at all possible, otherwise
\# the website machinery needs to be changed.
\# --- Begin directly referenced appendices
\# The following three appendices are linked to directly from the
\# website. Please keep them in their current position as appendices
\# C, D and E if at all possible. If they are reorganized, the website
\# will need to be updated.
\# Appendix C: changelog/release notes
\& changelog.src
\# Appendix D: building from source
\& source.src
\# Appendix E: contact information
\& contact.src
\# --- End directly referenced appendices
\& inslist.src

View file

@ -14,11 +14,11 @@ instruction table (and some other bits of code) with NASM.
The Netwide Disassembler does nothing except to produce
disassemblies of \e{binary} source files. NDISASM does not have any
understanding of object file formats, like \c{objdump}, and it will
not understand \c{DOS .EXE} files like \c{debug} will. It just
not understand DOS \c{.EXE} files like \c{debug} will. It just
disassembles.
\H{ndisrun} Running NDISASM
\H{ndisrun} \I{options, disassembler}Running NDISASM
To disassemble a file, you will typically use a command of the form
@ -26,11 +26,11 @@ To disassemble a file, you will typically use a command of the form
NDISASM can disassemble 16-, 32- or 64-bit code equally easily,
provided of course that you remember to specify which it is to work
with. If no \i\c{-b} switch is present, NDISASM works in 16-bit mode
by default. The \i\c{-u} switch (for USE32) also invokes 32-bit mode.
with. If no \c{-b} switch is present, NDISASM works in 16-bit mode
by default. The \c{-u} switch (for USE32) also invokes 32-bit mode.
Two more command line options are \i\c{-r} which reports the version
number of NDISASM you are running, and \i\c{-h} which gives a short
Two more command line options are \c{-r} which reports the version
number of NDISASM you are running, and \c{-h} which gives a short
summary of command line options.
@ -42,7 +42,7 @@ rather than at zero. NDISASM, which assumes by default that any file
you give it is loaded at zero, will therefore need to be informed of
this.
The \i\c{-o} option allows you to declare a different origin for the
The \c{-o} option allows you to declare a different origin for the
file you are disassembling. Its argument may be expressed in any of
the NASM numeric formats: decimal by default, if it begins with `\c{$}'
or `\c{0x}' or ends in `\c{H}' it's \c{hex}, if it ends in `\c{Q}' it's
@ -84,7 +84,7 @@ instruction and output a `\c{db}' instead. So it \e{will} start
disassembly exactly from the sync point, and so you \e{will} see all
the instructions in your code section.
Sync points are specified using the \i\c{-s} option: they are measured
Sync points are specified using the \c{-s} option: they are measured
in terms of the program origin, not the file position. So if you
want to synchronize after 32 bytes of a \c{.COM} file, you would have to
do
@ -116,7 +116,7 @@ be, surely, would be to read the \c{JMP} instruction, and then to use
its target address as a sync point. So can NDISASM do that for you?
The answer, of course, is yes: using either of the synonymous
switches \i\c{-a} (for automatic sync) or \i\c{-i} (for intelligent
switches \c{-a} (for automatic sync) or \c{-i} (for intelligent
sync) will enable \c{auto-sync} mode. Auto-sync mode automatically
generates a sync point for any forward-referring PC-relative jump or
call instruction that NDISASM encounters. (Since NDISASM is one-pass,
@ -153,16 +153,14 @@ suppress disassembly of the data area.
\S{ndisother} Other Options
The \i\c{-e} option skips a header on the file, by ignoring the first N
The \c{-e} option skips a header on the file, by ignoring the first N
bytes. This means that the header is \e{not} counted towards the
disassembly offset: if you give \c{-e10 -o10}, disassembly will start
at byte 10 in the file, and this will be given offset 10, not 20.
The \i\c{-k} option is provided with two comma-separated numeric
The \c{-k} option is provided with two comma-separated numeric
arguments, the first of which is an assembly offset and the second
is a number of bytes to skip. This \e{will} count the skipped bytes
towards the assembly offset: its use is to suppress disassembly of a
data section which wouldn't contain anything you wanted to see
anyway.

View file

@ -109,8 +109,9 @@ with \i\c{vstart=}.
start address.
\b Arguments to \c{org}, \c{start}, \c{vstart}, and \c{align=} are
critical expressions. See \k{crit}. E.g. \c{align=(1 << ALIGN_SHIFT)}
- \c{ALIGN_SHIFT} must be defined before it is used here.
critical expressions. See \k{crit}. For example, in the case of
\c{align=(1 << ALIGN_SHIFT)}, \c{ALIGN_SHIFT} must be defined before
it is used here.
\b Any code which comes before an explicit \c{SECTION} directive
is directed by default into the \c{.text} section.
@ -179,7 +180,7 @@ for historical reasons) is the one produced by \i{MASM} and
\c{obj} provides a default output file-name extension of \c{.obj}.
\c{obj} is not exclusively a 16-bit format, though: NASM has full
\c{obj} is not exclusively a 16-bit format, though; NASM has full
support for the 32-bit extensions to the format. In particular,
32-bit \c{obj} format files are used by \i{Borland's Win32
compilers}, instead of using Microsoft's newer \i\c{win32} object
@ -326,6 +327,10 @@ A group does not have to contain any segments; you can still make
you are referring to. OS/2, for example, defines the special group
\c{FLAT} with no segments in it.
\c{GROUP} is cumulative. The above example can be done like this:
\c group dgroup data
\c group dgroup bss
\S{uppercase} \i\c{UPPERCASE}: Disabling Case Sensitivity in Output
@ -510,6 +515,41 @@ information. To suppress the generation of dependencies, use
\c %pragma obj nodepend
\H{obj2fmt} \i\c{obj2}: \i{OS/2 32-bit OMF}\I{OMF} Object Files
The \c{obj2} output format is the same as \c{obj} except:
\b Default attributes for a segment are \c{ALIGN=16} and \c{USE32}.
\b All 32-bit segment is added to \c{FLAT} group implicitly.
\b Support Unix sections such as \c{.text}, \c{.rodata}, \c{.data}
and \c{.bss} for compatibility with other Unix platforms. And they are
aliased to \c{TEXT32}, \c{CONST32}, \c{DATA32}, \c{BSS32}, respectively.
\b Set default classes implicitly for known segments such as TEXT32,
CONST32, DATA32, BSS32 and so on.
The defaults assumed by NASM if you do not specify the qualifiers are:
\c SECTION .text ALIGN=16 USE32 CLASS=CODE FLAT
\c SECTION .rodata ALIGN=16 USE32 CLASS=CONST FLAT
\c SECTION .data ALIGN=16 USE32 CLASS=DATA FLAT
\c SECTION .bss ALIGN=16 USE32 CLASS=BSS FLAT
\c SECTION CODE ALIGN=16 USE32 CLASS=CODE FLAT
\c SECTION TEXT ALIGN=16 USE32 CLASS=CODE FLAT
\c SECTION CONST ALIGN=16 USE32 CLASS=CONST FLAT
\c SECTION DATA ALIGN=16 USE32 CLASS=DATA FLAT
\c SECTION BSS ALIGN=16 USE32 CLASS=BSS FLAT
\c SECTION STACK ALIGN=16 USE32 CLASS=STACK FLAT
\c SECTION CODE32 ALIGN=16 USE32 CLASS=CODE FLAT
\c SECTION TEXT32 ALIGN=16 USE32 CLASS=CODE FLAT
\c SECTION CONST32 ALIGN=16 USE32 CLASS=CONST FLAT
\c SECTION DATA32 ALIGN=16 USE32 CLASS=DATA FLAT
\c SECTION BSS32 ALIGN=16 USE32 CLASS=BSS FLAT
\c SECTION STACK32 ALIGN=16 USE32 CLASS=STACK FLAT
\H{win32fmt} \i\c{win32}: Microsoft Win32 Object Files
The \c{win32} output format generates Microsoft Win32 object files,
@ -605,13 +645,14 @@ It will get linked into the \c{.text} section anyway - see the info on
\W{https://github.com/MicrosoftDocs/win32/blob/docs/desktop-src/Debug/pe-format.md#grouped-sections-object-only}\c{Grouped Sections}.
\c section .text$1 align=16 comdat=1:FirstFnc
\c ... ; Code linked only if referenced from C
\c ... ; Code linked only if referenced from C
\c
\c section .text$1 align=16 comdat=1:SecondFnc
\c ... ; Code linked only if referenced from C
\c ... ; Code linked only if referenced from C
\c
\c section .rdata align=32 comdat=5:FirstFnc
\c ... ; Data linked only if the related code (FirstFnc) is linked
\c ... ; Data linked onlyif the related code
\c ; (FirstFnc) is linked
\c
The defaults assumed by NASM if you do not specify the above
@ -631,42 +672,42 @@ Any other section name is treated by default like \c{.text}.
\S{win32safeseh} \c{win32}: Safe Structured Exception Handling
Among other improvements in Windows XP SP2 and Windows Server 2003
Microsoft has introduced concept of "safe structured exception
handling." General idea is to collect handlers' entry points in
designated read-only table and have alleged entry point verified
against this table prior exception control is passed to the handler. In
order for an executable module to be equipped with such "safe exception
handler table," all object modules on linker command line has to comply
with certain criteria. If one single module among them does not, then
the table in question is omitted and above mentioned run-time checks
will not be performed for application in question. Table omission is by
default silent and therefore can be easily overlooked. One can instruct
linker to refuse to produce binary without such table by passing
Among other improvements in Windows XP SP2 and Windows Server 2003,
Microsoft has introduced the concept of "safe structured exception
handling." The general idea is to collect handlers' entry points
in a designated read-only table and have SEH entry points verified
against this table before exception control is passed to the
corresponding handler. In order for an executable module to be
equipped with this read-only table, all object modules on linker
command line have to comply with certain criteria. If even a single
module among them does not, then the table in question is omitted
and above mentioned run-time checks will not be performed for the
application in question. Table omission is silent by default and
therefore can be easily missed. One can instruct the linker to
refuse to produce binary without such table by passing the
\c{/safeseh} command line option.
Without regard to this run-time check merits it's natural to expect
Without regard to this run-time check, it's natural to expect
NASM to be capable of generating modules suitable for \c{/safeseh}
linking. From developer's viewpoint the problem is two-fold:
linking. From the developer's viewpoint the problem is two-fold:
\b how to adapt modules not deploying exception handlers of their own;
\b how to adapt/develop modules utilizing custom exception handling;
Former can be easily achieved with any NASM version by adding following
line to source code:
The former can be easily achieved with any NASM version by adding the
following line to the source code:
\c $@feat.00 equ 1
As of version 2.03 NASM adds this absolute symbol automatically. If
it's not already present to be precise. I.e. if for whatever reason
developer would choose to assign another value in source file, it would
still be perfectly possible.
As of version 2.03 NASM adds this absolute symbol automatically, if
it is not already present (in which case the developer can choose to
assign another value, if desired, for whatever reason).
Registering custom exception handler on the other hand requires certain
"magic." As of version 2.03 additional directive is implemented,
\c{safeseh}, which instructs the assembler to produce appropriately
formatted input data for above mentioned "safe exception handler
Registering a custom exception handler on the other hand requires
certain "magic." As of version 2.03, an additional \c{safeseh} directive
is implemented, which instructs the assembler to produce appropriately
formatted input data for the above-mentioned "safe exception handler
table." Its typical use would be:
\c section .text
@ -699,19 +740,18 @@ table." Its typical use would be:
\c section .drectve info
\c db '/defaultlib:user32.lib /defaultlib:msvcrt.lib '
As you might imagine, it's perfectly possible to produce .exe binary
with "safe exception handler table" and yet engage unregistered
exception handler. Indeed, handler is engaged by simply manipulating
\c{[fs:0]} location at run-time, something linker has no power over,
run-time that is. It should be explicitly mentioned that such failure
to register handler's entry point with \c{safeseh} directive has
undesired side effect at run-time. If exception is raised and
unregistered handler is to be executed, the application is abruptly
terminated without any notification whatsoever. One can argue that
system could at least have logged some kind "non-safe exception
handler in x.exe at address n" message in event log, but no, literally
no notification is provided and user is left with no clue on what
caused application failure.
As you might imagine, it's perfectly possible to produce an .exe binary
with the "safe exception handler table" and yet invoke an unregistered
exception handler. A handler is invoked by manipulating \c{[fs:0]}
at run-time, something the linker has no power over. It is therefore
important to note that such failure to register a handler's entry point
with the \c{safeseh} directive will have undesired side effects at
run-time. If an exception is raised and an unregistered handler is to be
executed, the application is abruptly terminated without any notification
whatsoever. One can argue that the system should at least log some kind
of "non-safe exception handler in x.exe at address n" message in the
event log, but unfortunately the user is left without any clue as to
what might have caused the crash.
Finally, all mentions of linker in this paragraph refer to Microsoft
linker version 7.x and later. Presence of \c{@feat.00} symbol and input
@ -719,6 +759,33 @@ data for "safe exception handler table" causes no backward
incompatibilities and "safeseh" modules generated by NASM 2.03 and
later can still be linked by earlier versions or non-Microsoft linkers.
\S{win32wrt} \c{win32}: Special Symbol and WRT
The Microsoft linker may require symbol table indexes instead of absolute or
image relative addresses in some more modern structures, like those used for
exception handler control flow guard metadata (ehcont). This can be
accomplished by getting the symbol address with respect to the special
\c{..symtab} symbol. For instance:
\c __guard_ehcont_main: dd main.cont wrt ..symtab
\S{win32glob} \c{win32} Extensions to the \c{GLOBAL}, \c{EXTERN} and
\c{STATIC} Directives\I{GLOBAL, win32 extensions to}\I{EXTERN, win32
extensions to}\I{STATIC, win32 extensions to}
You can specify whether a symbol is a function by suffixing the name
with a colon and the word \i\c{function}. For example:
\c global hashlookup:function
\c static localfunc:function
\c extern extfunc:function
The linker may use this extra symbol information when generating tables of
valid indirect branch targets and such.
\S{codeview} Debugging formats for Windows
\I{Windows debugging formats}
@ -749,7 +816,7 @@ references. Consider a switch dispatch table:
\c ...
Even a novice Win64 assembler programmer will soon realize that the code
is not 64-bit savvy. Most notably linker will refuse to link it with
is not 64-bit savvy. Most notably the linker will refuse to link it, showing:
\c 'ADDR32' relocation to '.text' invalid without /LARGEADDRESSAWARE:NO
@ -758,15 +825,15 @@ So [s]he will have to split jmp instruction as following:
\c lea rbx,[rel dsptch]
\c jmp qword [rbx+rax*8]
What happens behind the scene is that effective address in \c{lea} is
encoded relative to instruction pointer, or in perfectly
What happens behind the scenes is that the effective address in \c{lea}
is encoded relative to instruction pointer, in a perfectly
position-independent manner. But this is only part of the problem!
Trouble is that in .dll context \c{caseN} relocations will make their
way to the final module and might have to be adjusted at .dll load
time. To be specific when it can't be loaded at preferred address. And
when this occurs, pages with such relocations will be rendered private
to current process, which kind of undermines the idea of sharing .dll.
But no worry, it's trivial to fix:
The issue is that in a .dll context, the \c{caseN} relocations will make
their way to the final module and might have to be adjusted at .dll load
time (specifically, when it can't be loaded at the preferred address).
When this occurs, pages with such relocations will be rendered private
to current process, which kind of undermines the idea of a shared .dll.
But not to worry, it's trivial to fix:
\c lea rbx,[rel dsptch]
\c add rbx,[rbx+rax*8]
@ -777,11 +844,11 @@ But no worry, it's trivial to fix:
\c ...
NASM version 2.03 and later provides another alternative, \c{wrt
..imagebase} operator, which returns offset from base address of the
current image, be it .exe or .dll module, therefore the name. For those
acquainted with PE-COFF format base address denotes start of
\c{IMAGE_DOS_HEADER} structure. Here is how to implement switch with
these image-relative references:
..imagebase} operator, which returns an offset from base address of the
current image, be it .exe or .dll module, hence the name. For those
acquainted with PE-COFF format, this base address denotes the start of
the \c{IMAGE_DOS_HEADER} structure. Here is how to implement a switch
statement with these image-relative references:
\c lea rbx,[rel dsptch]
\c mov eax,[rbx+rax*4]
@ -792,10 +859,10 @@ these image-relative references:
\c dsptch: dd case0 wrt ..imagebase
\c dd case1 wrt ..imagebase
One can argue that the operator is redundant. Indeed, snippet before
last works just fine with any NASM version and is not even Windows
specific... The real reason for implementing \c{wrt ..imagebase} will
become apparent in next paragraph.
That said, the snippet before last works just fine with any NASM version
and is not even Windows specific, which makes this operator unnecessary
in this case. The real reason for the \c{wrt ..imagebase} operator will
become apparent in the next section.
It should be noted that \c{wrt ..imagebase} is defined as 32-bit
operand only:
@ -807,65 +874,61 @@ operand only:
\S{win64seh} \c{win64}: Structured Exception Handling
Structured exception handing in Win64 is completely different matter
from Win32. Upon exception program counter value is noted, and
linker-generated table comprising start and end addresses of all the
functions [in given executable module] is traversed and compared to the
saved program counter. Thus so called \c{UNWIND_INFO} structure is
identified. If it's not found, then offending subroutine is assumed to
be "leaf" and just mentioned lookup procedure is attempted for its
caller. In Win64 leaf function is such function that does not call any
other function \e{nor} modifies any Win64 non-volatile registers,
including stack pointer. The latter ensures that it's possible to
identify leaf function's caller by simply pulling the value from the
Structured exception handing in Win64 is completely different compared
to Win32. When an exception occurs, the program counter is noted, and a
linker-generated table containing start and end addresses of all the
functions (in a given executable module) is traversed and compared to
the saved program counter. This is used to identify the corresponding
\c{UNWIND_INFO} structure. If missing, then the offending subroutine is
assumed to be "leaf" and this lookup procedure is instead attempted for
its caller. In Win64, a leaf function is a function that does not call
any other functions \e{nor} modifies any Win64 non-volatile registers,
including the stack pointer. The latter ensures that it's possible to
identify a leaf function's caller by simply pulling the value from the
top of the stack.
While majority of subroutines written in assembler are not calling any
other function, requirement for non-volatile registers' immutability
leaves developer with not more than 7 registers and no stack frame,
which is not necessarily what [s]he counted with. Customarily one would
meet the requirement by saving non-volatile registers on stack and
restoring them upon return, so what can go wrong? If [and only if] an
exception is raised at run-time and no \c{UNWIND_INFO} structure is
associated with such "leaf" function, the stack unwind procedure will
expect to find caller's return address on the top of stack immediately
followed by its frame. Given that developer pushed caller's
non-volatile registers on stack, would the value on top point at some
code segment or even addressable space? Well, developer can attempt
copying caller's return address to the top of stack and this would
actually work in some very specific circumstances. But unless developer
can guarantee that these circumstances are always met, it's more
appropriate to assume worst case scenario, i.e. stack unwind procedure
going berserk. Relevant question is what happens then? Application is
abruptly terminated without any notification whatsoever. Just like in
Win32 case, one can argue that system could at least have logged
"unwind procedure went berserk in x.exe at address n" in event log, but
no, no trace of failure is left.
While the majority of subroutines written in assembler are not calling
any other functions, they may not qualify as "leaf" functions in the
Win64 sense. The requirement for non-volatile registers to be
unchanged leaves the developer with not more than 7 registers and no
stack frame, which is not necessarily what they counted on.
Customarily one would meet this requirement by saving non-volatile
registers on stack and restoring them upon return. However, if (and
only if) an exception is raised at run-time and no \c{UNWIND_INFO}
structure is associated with such a "leaf" function, the stack unwind
procedure will expect to find the caller's return address on the top of
the stack immediately followed by its frame. Given that the developer
pushed the caller's non-volatile registers onto the stack, the value
on top will no longer point to the right place. The developer can
attempt to copy the caller's return address to the top of stack, which
would work in some very specific circumstances. But unless the
developer can guarantee that these circumstances are always met, it's
more appropriate to assume the worst, i.e. the stack unwind procedure
goes berserk, abruptly terminating without any notification whatsoever
(just like in the the Win32 case).
Now, when we understand significance of the \c{UNWIND_INFO} structure,
let's discuss what's in it and/or how it's processed. First of all it
is checked for presence of reference to custom language-specific
exception handler. If there is one, then it's invoked. Depending on the
return value, execution flow is resumed (exception is said to be
"handled"), \e{or} rest of \c{UNWIND_INFO} structure is processed as
following. Beside optional reference to custom handler, it carries
information about current callee's stack frame and where non-volatile
registers are saved. Information is detailed enough to be able to
reconstruct contents of caller's non-volatile registers upon call to
current callee. And so caller's context is reconstructed, and then
unwind procedure is repeated, i.e. another \c{UNWIND_INFO} structure is
associated, this time, with caller's instruction pointer, which is then
checked for presence of reference to language-specific handler, etc.
The procedure is recursively repeated till exception is handled. As
last resort system "handles" it by generating memory core dump and
terminating the application.
Now that we understand significance of the \c{UNWIND_INFO} structure,
let us discuss what is in it and how it is processed. First, it is
checked for the presence of a reference to a custom language-specific
exception handler. If there is one, then it is invoked. Depending on
the return value, execution flow is resumed (exception is said to be
"handled"), \e{or} the rest of the \c{UNWIND_INFO} structure is
processed as follows. Aside from an optional reference to a custom
handler, it carries information about the current callee's stack frame
and where non-volatile registers are saved. The information is detailed
enough to be able to reconstruct the contents of the caller's
non-volatile registers on entry to the current callee. And so the
caller's context is reconstructed, at which point the unwind procedure
is repeated, using the \c{UNWIND_INFO} structure associated with the
caller's instruction pointer. The procedure is repeated recursively
until the exception is handled. As a last resort, the system "handles"
it by generating a memory dump and terminating the application.
As for the moment of this writing NASM unfortunately does not
facilitate generation of above mentioned detailed information about
stack frame layout. But as of version 2.03 it implements building
blocks for generating structures involved in stack unwinding. As
simplest example, here is how to deploy custom exception handler for
leaf function:
As of this writing, NASM unfortunately does not facilitate generation
of above mentioned detailed information about stack frame layout. But
as of version 2.03, it implements building blocks for generating
structures involved in stack unwinding. Here is a simple example
showing how to deploy a custom exception handler for a leaf function:
\c default rel
\c section .text
@ -900,36 +963,36 @@ leaf function:
\c section .drectve info
\c db '/defaultlib:user32.lib /defaultlib:msvcrt.lib '
What you see in \c{.pdata} section is element of the "table comprising
start and end addresses of function" along with reference to associated
\c{UNWIND_INFO} structure. And what you see in \c{.xdata} section is
\c{UNWIND_INFO} structure describing function with no frame, but with
designated exception handler. References are \e{required} to be
image-relative (which is the real reason for implementing \c{wrt
..imagebase} operator). It should be noted that \c{rdata align=n}, as
well as \c{wrt ..imagebase}, are optional in these two segments'
contexts, i.e. can be omitted. Latter means that \e{all} 32-bit
references, not only above listed required ones, placed into these two
segments turn out image-relative. Why is it important to understand?
Developer is allowed to append handler-specific data to \c{UNWIND_INFO}
structure, and if [s]he adds a 32-bit reference, then [s]he will have
to remember to adjust its value to obtain the real pointer.
What you see is that the \c{.pdata} section contains a single-element
table, containing function start and end addresses, along with references
to associated \c{UNWIND_INFO} structures (only one in this case). The
\c{.xdata} section contains the referenced \c{UNWIND_INFO} structure,
describing a function with no frame, but with a designated exception handler.
These references are \e{required} to be image-relative, which is the real
reason for implementing the \c{wrt ..imagebase} operator). It should be
noted that \c{rdata align=n}, as well as \c{wrt ..imagebase}, are actually
optional in the context of these two segments (they apply even when omitted);
\e{all} 32-bit references placed into these two segments will be image-relative.
This is important to understand, as the developer is allowed to append
handler-specific data to the \c{UNWIND_INFO} structure, and any 32-bit
references that are added may require adjustment to obtain the real pointer.
As already mentioned, in Win64 terms leaf function is one that does not
call any other function \e{nor} modifies any non-volatile register,
including stack pointer. But it's not uncommon that assembler
programmer plans to utilize every single register and sometimes even
have variable stack frame. Is there anything one can do with bare
building blocks? I.e. besides manually composing fully-fledged
\c{UNWIND_INFO} structure, which would surely be considered
error-prone? Yes, there is. Recall that exception handler is called
first, before stack layout is analyzed. As it turned out, it's
perfectly possible to manipulate current callee's context in custom
handler in manner that permits further stack unwinding. General idea is
that handler would not actually "handle" the exception, but instead
restore callee's context, as it was at its entry point and thus mimic
leaf function. In other words, handler would simply undertake part of
unwinding procedure. Consider following example:
As already mentioned, in Win64 terms, a leaf function is one that neither
calls any other function \e{nor} modifies any non-volatile registers,
including the stack pointer. But it is not uncommon for the programmer
to intend to utilize every single register and sometimes even have a
variable stack frame, requiring a more complicated \c{UNWIND_INFO} structure
than in the example above. Is there anything one can do with these simpler
building blocks, and avoid manually composing fully-fledged \c{UNWIND_INFO}
structures, which would surely be considered error-prone? Yes, there is.
Recall that an exception handler is called first, before the stack layout
is analyzed. As it turns out, it is perfectly possible to manipulate
current callee's context in a custom handler in a manner that permits
further stack unwinding. The general idea is that handler would not
actually "handle" the exception, but instead restore the callee's context
(restore to state at entry point) and thus mimic a Win64 leaf function.
In other words, the handler would effectively undertake part of the
unwinding procedure. Consider the following example:
\c function:
\c mov rax,rsp ; copy rsp to volatile register
@ -951,11 +1014,11 @@ unwinding procedure. Consider following example:
\c mov rsp,r11 ; destroy frame
\c ret
The keyword is that up to \c{magic_point} original \c{rsp} value
remains in chosen volatile register and no non-volatile register,
except for \c{rsp}, is modified. While past \c{magic_point} \c{rsp}
remains constant till the very end of the \c{function}. In this case
custom language-specific exception handler would look like this:
The key is that until \c{magic_point}, the original \c{rsp} value
remains in the chosen volatile register, and no non-volatile register
except for \c{rsp} is modified. After \c{magic_point}, \c{rsp} remains
constant till the very end of the \c{function}. In this case a custom
language-specific exception handler would look like this:
\c EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
\c CONTEXT *context,DISPATCHER_CONTEXT *disp)
@ -977,9 +1040,9 @@ custom language-specific exception handler would look like this:
\c return ExceptionContinueSearch;
\c }
As custom handler mimics leaf function, corresponding \c{UNWIND_INFO}
structure does not have to contain any information about stack frame
and its layout.
As this custom handler allows the example function to mimic a Win64 leaf
function, the corresponding \c{UNWIND_INFO} structure does not need to
contain any information about the stack frame and its layout.
\H{cofffmt} \i\c{coff}: \i{Common Object File Format}
@ -1096,6 +1159,38 @@ this extension:
Using with static linker will clear the private extern attribute.
But linker option like \c{-keep_private_externs} can avoid it.
\S{macho-bver} \c{macho} specific directive \i\c{build_version}
The directive \c{build_version} generates a \c{LC_BUILD_VERSION}
load command in the Mach-O header, which allows specifying a
target platform, minimum OS version and optionally SDK version.
Newer Xcode linker versions warn if this is not present in object
files.
This directive takes the target platform name and minimum OS
version as arguments, in this form:
\c build_version macos,10,7
Platform names that make sense for x86 code are \c{macos},
\c{iossimulator}, \c{tvossimulator} and \c{watchossimulator}.
Optionally, a trailing version number and minimum SDK version
can also be specified with this syntax:
\c build_version macos, 10, 14, 0 sdk_version 10, 14, 0
This is a macro implemented as a \c{%pragma}. It can also be
specified in its \c{%pragma} form, in which case it will not
affect non-Mach-O builds of the same source code:
\c %pragma macho build_version ...
This latter form is also useful on the command line when using
the \c{--pragma} command-line switch:
\c nasm -f macho64 --pragma "macho build_version macos,10,9" ...
\H{elffmt} \i\c{elf32}, \i\c{elf64}, \i\c{elfx32}:
\I{ELF}\I{linux, elf}Executable and Linkable Format Object Files
@ -1187,8 +1282,8 @@ override that.
\b \i\c{merge} indicates that duplicate data elements in this section
should be merged with data elements from other object files. Data
elements can be either fixed-sized objects or null-terminatedstrings
(with the \c{strings} attribute.) A size specifier is required unless
elements can be either fixed-sized objects or null-terminated strings
(with the \c{strings} attribute). A size specifier is required unless
\c{strings} is specified, in which case the size defaults to \c{byte}.
\b \i\c{tls} defines the section to be one which contains
@ -1347,6 +1442,15 @@ Declaring the type and size of global symbols is necessary when
writing shared library code. For more information, see
\k{picglobal}.
NASM supports the GNU indirect function symbol type using the keyword
\c{gnu_ifunc}. This marks the symbol as \c{STT_GNU_IFUNC} and causes the
dynamic loader to call the symbol as a resolver at runtime. For example:
\c global func_ifunc:function
\c
\c global func:gnu_ifunc
\c func equ func_ifunc
\S{elfextrn} \c{elf} Extensions to the \c{EXTERN} Directive\I{EXTERN,
elf extensions to}\I{EXTERN, elf extensions to}

View file

@ -17,7 +17,7 @@ and the macro facilities of many other assemblers.
The input to the preprocessor is expanded in the following ways in the
order specified here.
\S{pcbackslash} \i{Continuation Line} Collapsing
\S{pcbackslash} \i{Continuation} Line Collapsing
The preprocessor first collapses all lines which end with a backslash
(\c{\\}) character into a single line. Thus:
@ -38,7 +38,7 @@ After concatenation, comments are removed.
begin with the character \c{;} unless contained
inside a quoted string or a handful of other special contexts.
\I{ccomment}Note that this is applied \e{after} \i{continuation lines}
\I{ccomment}Note that this is applied \e{after} \i{continuation} lines
are collapsed. This means that
\c add al,'\\' ; Add the ASCII code for \\
@ -146,6 +146,31 @@ running in preprocessor-only mode, to the output file (see \k{opt-E});
if necessary prefixed by a newly inserted \i\c{%line} directive.
\H{ppcaveats} \i{Preprocessor caveats}\I{caveats, preprocessor}
\S{ppcase} Case Insensitivity\I{case sensitivity, preprocessor}
The NASM preprocessor allows the user to create case-insensitive
macros using directives prefixed with \c{%i} for 'insensitive'
(\i\c{%idefine}, \i\c{%imacro}, etc.) However, this is limited by NASM
inherently not being aware of the character set used in either the
source code nor the output object code.
The primary intended use for case-insensitive macros is to override
NASM keywords or instructions. Therefore, \e{NASM case insensitivity
is limited to the ASCII character range only.} NASM does permit
non-ASCII characters (bytes with values above 127) in macros (and
labels), but treats them as opaque bytes that can only be matched
exactly.
In general, it is recommended to avoid using case insensitive macros
unless you have specific reasons to need them.
The same caveat applies to any other case-insensitive matching: the
\i\c{%ifidni} and \i\c{%elifidni} directives and the \i\c{%isidni()}
and \i\c{%findi()} functions.
\H{slmacro} \i{Single-Line Macros}
Single-line macros are expanded inline, much like macros in the C
@ -185,13 +210,13 @@ Otherwise it will be treated as an expansion. For example:
\c %define bar(a,b) ; two arguments, empty expansion
Macros defined with \c{%define} are \i{case sensitive}: after
Macros defined with \c{%define} are case sensitive: after
\c{%define foo bar}, only \c{foo} will expand to \c{bar}: \c{Foo} or
\c{FOO} will not. By using \c{%idefine} instead of \c{%define} (the
`i' stands for `insensitive') you can define all the case variants
of a macro at once, so that \c{%idefine foo bar} would cause
\c{foo}, \c{Foo}, \c{FOO}, \c{fOO} and so on all to expand to
\c{bar}.
\c{bar}. See however \k{ppcase}.
There is a mechanism which detects when a macro call has occurred as
a result of a previous expansion of the same macro, to guard against
@ -291,7 +316,7 @@ To have a reference to an embedded single-line macro resolved at the
time that the embedding macro is \e{defined}, as opposed to when the
embedding macro is \e{expanded}, you need a different mechanism to the
one offered by \c{%define}. The solution is to use \c{%xdefine}, or
it's \I{case sensitive}case-insensitive counterpart \c{%ixdefine}.
it's case-insensitive counterpart \c{%ixdefine}.
Suppose you have the following code:
@ -486,7 +511,7 @@ command-line using the `-u' option on the NASM command line: see
\S{assign} \i{Preprocessor Variables}: \i\c{%assign}
An alternative way to define single-line macros is by means of the
\c{%assign} command (and its \I{case sensitive}case-insensitive
\c{%assign} command (and its case-insensitive
counterpart \i\c{%iassign}, which differs from \c{%assign} in
exactly the same way that \c{%idefine} differs from \c{%define}).
@ -612,8 +637,8 @@ It's often useful to be able to handle strings in macros. NASM
supports a few simple string handling macro operators from which
more complex operations can be constructed.
All the string operators define or redefine a value (either a string
or a numeric value) to a single-line macro. When producing a string
All the string operators define or redefine a single-line macro to some
value (either a string or a numeric value). When producing a string
value, it may change the style of quoting of the input string or
strings, and possibly use \c{\\}-escapes inside \c{`}-quoted strings.
@ -680,7 +705,7 @@ than the description:
As with \c{%strlen} (see \k{strlen}), the first parameter is the
single-line macro to be created and the second is the string. The
third parameter specifies the first character to be selected, and the
optional fourth parameter preceded by comma) is the length. Note
optional fourth parameter (preceded by comma) is the length. Note
that the first index is 1, not 0 and the last index is equal to the
value that \c{%strlen} would assign given the same string. Index
values out of range result in an empty string. A negative length
@ -759,7 +784,7 @@ treats an empty argument list as a single empty argument.
\S{f_depend} \i\c\{%depend()} Function
he \c{%depend()} function takes a quoted string as argument, adds it
The \c{%depend()} function takes a quoted string as argument, adds it
to the output dependency list generated by the \c{-M} options (see
\k{opt-M}), and evaluates to the unchanged string.
@ -769,6 +794,31 @@ This is the function equivalent of the \c{%depend} directive, see
See also the \c{%pathsearch()} function (\k{f_pathsearch}).
\S{f_env} \i\c{%env()} Function
The \c{%env()} function takes an optionally quoted string as its first
argument, and if an environment variable with that name exists,
expands to a quoted string with the value of that environment
variable. If the environment variable does \e{not} exist, expands to
any additional arguments given, or to an empty quoted string if no
additional arguments are provided.
\c ; This example assumes USER=nasmuser and MISSING is undefined
\c
\c db %env(USER) ; db 'nasmuser'
\c db %env("USER") ; db 'nasmuser'
\c db %env("USER",0) ; db 'nasmuser'
\c db %env(MISSING) ; db ''
\c db %env("MISSING",0xff) ; db 0xff
\c db %env("MISSING",1,"2",3) ; db 1,"2",3
\c
\c ; This line generates a warning for "db" without data:
\c db %env("MISSING",) ; db
See also the \c{%ifenv} directive (\k{ifenv}) and the \c{%!}
construct (\k{getenv}).
\S{f_eval} \i\c{%eval()} Function
The \c{%eval()} function evaluates its argument as a numeric
@ -793,7 +843,7 @@ by an optional list. These are turned into quoted strings if
necessary, and then compared as if by the \i\c{%isidn()} or
\i\c{%isidni()} functions, respectively (see \k{ifidn}) \- the
\c{%find()} function compares case sensitively, and \c{%findi()} case
insensitively.
insensitively; see however \k{ppcase}.
The functions then expand to \c{0} if none of the strings in the list
match the first string, or the position in the list where the first
@ -863,6 +913,45 @@ Unlike the C \c{defined()} preprocessor construct, these functions are
valid anywhere in the source code, not just in \c{%if} expressions.
\S{f_limit} \i\c{%limit()} Function
The \c{%limit()} function takes as its first argument an optionally
quoted string which is matched against a resource limit as defined by
the \c{--limit-} command line option or the \c{%pragma limit}
directive (see \k{opt-limit}). The macro then expands to the value of
that limit, or \c{0} if no limit with that name is known in the
current version of NASM.
An optional second argument can be set to one of the following
optionally quoted strings:
\b \c{current}: the current value for the limit. This is also the result
if no second argument is specified.
\b \e{reset}: the initial value for the limit, set on the command line
or the default value if no such value is set; this is the value
that \c{%pragma limit} \e{limit-name} \c{reset} would set the limit
to.
\b \e{default}: the default value for the limit. This is the
value that \c{%pragma limit} \e{limit-name} \c{default} would set
the limit to.
\b \e{maximum}: the maximum permitted value for the limit. This is the
value that \c{%pragma limit} \e{limit-name} \c{maximum} would set
the limit to.
The value \c{unlimited} is represented by a very large positive
number. If the limit name is the empty string or \c{unlimited},
\c{%limit()} returns this value for comparison purposes.
The standard macro \c{__?NASM_LIMITS?__} expands to a comma-separated
list of quoted strings representing all limits defined in the current
version of NASM, see \k{nasm_limits}.
The \c{%limit()} function was introduced in NASM 3.02.
\S{f_map} \i\c{%map()} Function
The \c{%map()} function takes as its first parameter the name of a
@ -1011,6 +1100,24 @@ expands to nothing.
The arguments not selected are never expanded.
\S{f_selbits} \i\c{%selbits()} Function
The \c{%selbits()} function returns its first, second, or third
argument depending on if the current mode is 16, 32 or 64 bits. If
less than three arguments are given, the last argument is considered
repeated. Like \c{%cond()}, this is a specialized version of the
\c{%sel()} function.
For example:
\c BITS 64
\c
\c %define breg %selbits(bx,ebx,rbx)
\c %define vreg %selbits(ax,eax)
\c
\c mov vreg,[breg] ; mov eax,[rbx]
\S{f_str} \i\c\{%str()} Function
The \c{%str()} function converts its argument, including any commas,
@ -1469,7 +1576,7 @@ iterated through in reverse order.
\S{concat} \i{Concatenating Macro Parameters}
NASM can concatenate macro parameters and macro indirection constructs
on to other text surrounding them. This allows you to declare a family
with other surrounding text. This allows you to declare a family
of symbols, for example, in a macro definition. If, for example, you
wanted to generate a table of key codes along with offsets into the
table, you could code something like
@ -1559,7 +1666,7 @@ however, \c{%-1} will report an error if passed either of these,
because no inverse condition code exists.
\S{nolist} \i{Disabling Listing Expansion}\I\c{.nolist}
\S{nolist} \i{Disabling Listing Expansion}\i\c{.nolist}
When NASM is generating a listing file from your program, it will
generally expand multi-line macros by means of writing the macro
@ -1774,7 +1881,8 @@ to be assembled if and only if \c{text1} and \c{text2}, after
expanding single-line macros, are identical pieces of text.
Differences in white space are not counted.
\c{%ifidni} is similar to \c{%ifidn}, but is \i{case-insensitive}.
\c{%ifidni} is similar to \c{%ifidn}, but is case-insensitive; see
however \k{ppcase}.
For example, the following macro pushes a register or number on the
stack, and allows you to treat \c{IP} as a real register:
@ -1958,12 +2066,14 @@ this test, for example:
The conditional assembly construct \c{%ifenv} assembles the
subsequent code if and only if the environment variable referenced by
the \c{%!}\e{variable} directive exists.
the \c{%!}\e{variable} construct exists.
Just as for \c{%!}\e{variable} the argument should be written as a
string if it contains characters that would not be legal in an
Just as for \c{%!}\e{variable} the variable name must be written as a
quoted string if it contains characters that would not be legal in an
identifier. See \k{getenv}.
See also the the \c{%env()} function (\k{f_env}).
\S{if_caveat} Backwards Compatibility Caveat
@ -2155,8 +2265,8 @@ existence and inclusion of a specific standard macro package, see
Having labels that are local to a macro definition is sometimes not
quite powerful enough: sometimes you want to be able to share labels
between several macro calls. An example might be a \c{REPEAT} ...
\c{UNTIL} loop, in which the expansion of the \c{REPEAT} macro
would need to be able to refer to a label which the \c{UNTIL} macro
\c{UNTIL} loop, in which the expansion of the \c{UNTIL} macro
would need to be able to refer to a label which the \c{REPEAT} macro
had defined. However, for such a macro you would also want to be
able to nest these loops.
@ -2180,7 +2290,7 @@ This pushes a new context called \c{foobar} on the stack. You can have
several contexts on the stack with the same name: they can still be
distinguished. If no name is given, the context is unnamed (this is
normally used when both the \c{%push} and the \c{%pop} are inside a
single macro definition.)
single macro definition).
The directive \c{%pop}, taking one optional argument, removes the top
context from the context stack and destroys it, along with any
@ -2212,9 +2322,9 @@ above could be implemented by means of:
and invoked by means of, for example,
\c mov cx,string
\c mov di,string
\c repeat
\c add cx,3
\c add di,3
\c scasb
\c until e
@ -2352,7 +2462,7 @@ implement a block IF statement as a set of macros.
This code is more robust than the \c{REPEAT} and \c{UNTIL} macros
given in \k{ctxlocal}, because it uses conditional assembly to check
that the macros are issued in the right order (for example, not
calling \c{endif} before \c{if}) and issues a \c{%error} if they're
calling \c{endif} before \c{if}) and issues an \c{%error} if they're
not.
In addition, the \c{endif} macro has to be able to cope with the two
@ -2702,6 +2812,9 @@ variable, for example:
\c %defstr C_colon %!'C:'
See also the \c{%ifenv} directive (\k{ifenv}) and the \c{%env()}
function (\k{f_env}).
\S{clear} \i\c\{%clear}: Clear All Macro Definitions

View file

@ -23,13 +23,14 @@ sub font {
return map { /^(.*?)-*$/; $1 } @f;
}
my $text = ['SourceSans', 'SourceSans3',
my $text = ['Roboto', 'SourceSans', 'SourceSans3',
'SourceSansPro', 'SourceSansPro3',
'LiberationSans', 'Arial', 'Helvetica'];
my $code = ['SourceCodePro', 'LiberationMono', 'Courier'];
my $code = ['RobotoMono', 'SourceCodePro', 'LiberationMono', 'Courier'];
my $regular = ['Regular', ''];
my $italic = ['Italic', 'It'];
my $bold = ['Bold'];
my $medium = ['Medium', 'Semibold', 'Regular'];
my $semi = ['Semibold', 'Bold'];
my @TText = font($text, $bold);
@ -37,10 +38,10 @@ my @TItal = font($text, $bold, $italic);
my @TCode = font($code, $bold);
my @HText = font($text, $semi);
my @HItal = font($text, $semi, $italic);
my @HCode = font($code, $semi);
my @HCode = font($code, $bold);
my @BText = font($text, $regular);
my @BItal = font($text, $italic);
my @BCode = font($code, $regular);
my @BCode = font($code, $medium);
my @QText = font($text, $italic);
my @QBold = font($text, $bold, $italic);
my @QCode = font($code, $regular);

View file

@ -78,7 +78,7 @@ sub win32_gs_help() {
foreach my $p (split(/\;/, $gs[0]->{'/GS_LIB'})) {
foreach my $exe ('gswin64c.exe', 'gswin32c.exe', 'gs.exe') {
last if (defined($gsp));
my $e = File::Spec->catpath($p, $exe);
my $e = File::Spec->catfile($p, $exe);
$gsp = $e if (-f $e && -x _);
}
}

View file

@ -1,36 +1,6 @@
#!/usr/bin/perl
## --------------------------------------------------------------------------
##
## Copyright 1996-2018 The NASM Authors - All Rights Reserved
## See the file AUTHORS included with the NASM distribution for
## the specific copyright holders.
##
## Redistribution and use in source and binary forms, with or without
## modification, are permitted provided that the following
## conditions are met:
##
## * Redistributions of source code must retain the above copyright
## notice, this list of conditions and the following disclaimer.
## * Redistributions in binary form must reproduce the above
## copyright notice, this list of conditions and the following
## disclaimer in the documentation and/or other materials provided
## with the distribution.
##
## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
## CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
## INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
## MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
## DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
## NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
## LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
## HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
## EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
##
## --------------------------------------------------------------------------
# SPDX-License-Identifier: BSD-2-Clause
# Copyright 1996-2025 The NASM Authors - All Rights Reserved
# Read the source-form of the NASM manual and generate the various
@ -207,7 +177,7 @@ if ($out_format eq 'txt') {
print "$outfile: producing text output...\n";
&write_txt;
} elsif ($out_format eq 'html') {
$outfile = 'nasmdoc0.html';
$outfile = 'nasm00.html';
print "$outfile: producing HTML output...\n";
&write_html;
} elsif ($out_format eq 'dip') {
@ -867,68 +837,183 @@ sub word_txt {
sub html_filename($) {
my($node) = @_;
(my $number = lc($xrefnodes{$node})) =~ s/.*-//;
my $fname="nasmdocx.html";
substr($fname,8 - length $number, length $number) = $number;
return $fname;
$node = lc($node);
if ($node eq 'contents') {
return 'nasm00.html';
} elsif ($node eq 'index') {
return 'nasmix.html';
} else {
$node =~ /^(\w+)(?:[ -](\w+))?/;
my $type = $1;
my $number = $2;
if ($type eq 'chapter') {
return sprintf 'nasm%02d.html', $number;
} else {
# Appendix
return "nasma${number}.html";
}
}
}
my $html_fh;
sub html_openfile($) {
my($node) = @_;
die if (defined($html_fh));
my $filename = html_filename($node);
my $pathname = File::Spec->catfile($out_path, $filename);
open($html_fh, '>', $pathname)
or die "$0: $pathname: $!\n";
select $html_fh;
return $filename;
}
sub html_closefile() {
if (defined($html_fh)) {
select STDOUT;
close($html_fh);
undef $html_fh;
}
}
my @html_navbar;
sub html_navbar_generate() {
@html_navbar = (['Contents', html_filename('contents'), 'toc']);
my $ctype;
for ($node = $tstruct_next{'Top'}; $node; $node = $tstruct_next{$node}) {
my $plevel = $tstruct_level{$node};
next unless ($plevel == 1);
next unless ($node =~ /^(\w+) ([\w\.]+)?/);
my $nctype = $1;
my $nname = $2;
if ($nctype ne $ctype) {
$nname = "$nctype\&ensp;$nname";
$ctype = $nctype;
}
push(@html_navbar, [$nname, html_filename($node), lc($ctype)]);
}
push(@html_navbar, ['Index', html_filename('Index'), 'index']);
}
# Open an HTML file and write common preamble code
sub html_preamble($) {
my($node) = @_;
my $filename = html_openfile($node);
$node =~ /^(\w+)(?:[ -](\w+))?/;
my $nodetype = lc($1);
my $nodenum = $2;
$nodetype = 'toc' if ($nodetype eq 'contents');
print "<!DOCTYPE html>\n";
print "<head>\n";
print "<meta charset=\"UTF-8\" />\n";
print "<title>", $metadata{'title'}, "</title>\n";
print "<link href=\"nasmdoc.css\" rel=\"stylesheet\" type=\"text/css\" />\n";
print "<link href=\"local.css\" rel=\"stylesheet\" type=\"text/css\" />\n";
print "</head>\n";
print "<body>\n";
# Navigation bar
print "<div class=\"header\">\n";
# Stray whitespace inside the <nav> tag cause problems; handle by
# putting line breaks inside HTML comments. HACK!
print "<nav class=\"navbar\" role=\"navigation\"><ul><!--\n";
foreach my $nv (@html_navbar) {
my $is_this = '';
$is_this = ' navthis' if ($nv->[1] eq $filename);
printf "--><li class=\"nav%s%s\"><a href=\"%s\">%s</a></li><!--\n",
$nv->[2], $is_this, $nv->[1], $nv->[0];
}
print "--></ul></nav>\n";
print "<div class=\"title\">\n";
print "<h1>", $metadata{'title'}, "</h1>\n";
print '<h2>', $metadata{'subtitle'}, "</h2>\n";
print "</div>\n";
print "</div>\n";
print "<div class=\"contents $nodetype\">\n";
}
# Write common postable code and close an HTML file
sub html_postamble {
return unless (defined($html_fh));
print "</div>\n</body>\n</html>\n";
html_closefile();
}
sub write_html {
# This is called from the top level, so I won't bother using
# my or local.
# Create the navbar list
html_navbar_generate();
# Write contents file. Just the preamble, then a menu of links to the
# Write contents file. Just the preamble, then a menu of links to the
# separate chapter files and the nodes therein.
print "writing contents file...";
open TEXT, '>', File::Spec->catfile($out_path, 'nasmdoc0.html');
select TEXT;
undef $html_nav_last;
$html_nav_next = $tstruct_next{'Top'};
&html_preamble(0);
print "<p>This manual documents NASM, the Netwide Assembler: an assembler\n";
print "targeting the Intel x86 series of processors, with portable source.\n</p>";
print "<div class=\"toc\">\n";
html_preamble('contents');
print "<h2>Table of Contents</h2>\n";
$level = 0;
for ($node = $tstruct_next{'Top'}; $node; $node = $tstruct_next{$node}) {
my $lastlevel = $level;
while ($tstruct_level{$node} < $level) {
print "</li>\n</ol>\n";
$level--;
}
while ($tstruct_level{$node} > $level) {
print "<ol class=\"toc", ++$level, "\">\n";
}
if ($lastlevel >= $level) {
$ollevel = 0;
sub toc_close_tags($) {
my($plevel) = @_;
while ($plevel < $level) {
print "</li>\n";
if ($level-- <= $ollevel) {
print "</ol>\n";
$ollevel--;
}
}
$level = $tstruct_level{$node};
}
undef $ctype; # Chapter or Appendix
for ($node = $tstruct_next{'Top'}; $node; $node = $tstruct_next{$node}) {
my $plevel = $tstruct_level{$node};
my @pnn = split(/[ \.]/, $node);
(my $nname = $node) =~ s/^.*?\s+//;
my $nnum = $pnn[-1] + 0 || ord($pnn[-1]) - ord('A') + 1;
my $nctype = lc($pnn[0]);
toc_close_tags($plevel);
if ($plevel < 2 && $nctype ne $ctype) {
toc_close_tags(0);
my $plural = $nctype;
$plural =~ s/^(.)/\U$1/;
$plural =~ s/ix$/ice/; # ix -> ice + s -> ices
$plural .= 's';
print "<h3 class=\"tocheading $nctype\">$plural</h3>\n";
$ctype = $nctype;
}
while ($plevel > $level) {
$level++;
my $cclass = ($level == 1) ? " $ctype" : '';
print "<ol class=\"toc${level}${cclass}\"", ">\n";
$ollevel = $level;
}
if ($level == 1) {
$link = $fname = html_filename($node);
} else {
# Use the preceding filename plus a marker point.
$link = $fname . "#$xrefnodes{$node}";
}
$pname = $tstruct_pname{$node};
$title = plist_to_html(@$pname);
print "<li class=\"toc${level}\">\n";
print "<span class=\"node\">$node: </span><a href=\"$link\">$title</a>\n";
my $pname = $tstruct_pname{$node};
my $title = plist_to_html(@$pname);
printf "<li value=\"%d\" data-name=\"%s\">\n", $nnum, $nname;
# The $node span is obsolete and is only included for now to avoid
# breaking any existing local.css files.
printf "<a href=\"%s\"><span class=\"node\">%s: </span>%s</a>\n",
$link, $node, $title;
}
while ($level--) {
print "</li>\n</ol>\n";
}
print "</div>\n";
print "</body>\n";
print "</html>\n";
select STDOUT;
close TEXT;
toc_close_tags(0);
html_postamble();
# Open a null file, to ensure output (eg random &html_jumppoints calls)
# goes _somewhere_.
print "writing chapter files...";
open TEXT, '>', File::Spec->devnull();
select TEXT;
undef $html_nav_last;
undef $html_nav_next;
# open TEXT, '>', File::Spec->devnull();
# select TEXT;
$in_list = 0;
$in_bquo = 0;
@ -945,46 +1030,27 @@ sub write_html {
$endtag = '';
if ($ptype eq "chap") {
# Chapter heading. Begin a new file.
$pflags =~ /chap (.*) :(.*)/;
$title = "Chapter $1: ";
if ($ptype eq 'chap' || $ptype eq 'appn') {
# Chapter/appendix heading. Begin a new file.
$pflags =~ /^\w+ (.*) :(.*)/;
$xref = $2;
&html_postamble; select STDOUT; close TEXT;
$html_nav_last = $chapternode;
$title = "$2 $1:&ensp;";
$title =~ s/-\S+//;
$title =~ s/^(.)/\U$1/;
html_postamble();
$chapternode = $nodexrefs{$xref};
$html_nav_next = $tstruct_mnext{$chapternode};
open(TEXT, '>', File::Spec->catfile($out_path, html_filename($chapternode)));
select TEXT;
&html_preamble(1);
html_preamble($chapternode);
foreach $i (@$pname) {
$ww = &word_html($i);
$title .= $ww unless $ww eq "\001";
$ww = &word_html($i);
$title .= $ww unless $ww eq "\001";
}
$h = "<h2 id=\"$xref\">$title</h2>\n";
print $h; print FULL $h;
} elsif ($ptype eq "appn") {
# Appendix heading. Begin a new file.
$pflags =~ /appn (.*) :(.*)/;
$title = "Appendix $1: ";
$xref = $2;
&html_postamble; select STDOUT; close TEXT;
$html_nav_last = $chapternode;
$chapternode = $nodexrefs{$xref};
$html_nav_next = $tstruct_mnext{$chapternode};
open(TEXT, '>', File::Spec->catfile($out_path, html_filename($chapternode)));
select TEXT;
&html_preamble(1);
foreach $i (@$pname) {
$ww = &word_html($i);
$title .= $ww unless $ww eq "\001";
}
print "<h2 id=\"$xref\">$title</h2>\n";
print $h;
} elsif ($ptype eq "head" || $ptype eq "subh") {
# Heading or subheading.
$pflags =~ /.... (.*) :(.*)/;
$hdr = ($ptype eq "subh" ? "h4" : "h3");
$title = $1 . " ";
$title = $1 . ".&ensp;";
$xref = $2;
foreach $i (@$pname) {
$ww = &word_html($i);
@ -1059,59 +1125,14 @@ sub write_html {
print "</pre>\n" if ($in_code);
print "</li>\n</ul>\n" if ($in_list);
print "</blockquote>\n" if ($in_bquo);
&html_postamble; select STDOUT; close TEXT;
html_postamble();
print "\n writing index file...";
open TEXT, '>', File::Spec->catfile($out_path, 'nasmdoci.html');
select TEXT;
&html_preamble(0);
print "<h2 class=\"index\">Index</h2>\n";
print "<div class=\"index\">\n";
html_preamble('index');
print "<h2>Index</h2>\n";
&html_index;
print "</div>\n\n</body>\n</html>\n";
select STDOUT;
close TEXT;
}
html_postamble();
sub html_preamble {
print "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\" ?>\n";
print "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" ";
print "\"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">\n";
print "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n";
print "<head>\n";
print "<meta charset=\"UTF-8\" />\n";
print "<title>", $metadata{'title'}, "</title>\n";
print "<link href=\"nasmdoc.css\" rel=\"stylesheet\" type=\"text/css\" />\n";
print "<link href=\"local.css\" rel=\"stylesheet\" type=\"text/css\" />\n";
print "</head>\n";
print "<body>\n";
# Navigation bar
print "<div class=\"header\">\n";
print "<ul class=\"navbar\">\n";
if (defined($html_nav_last)) {
my $lastf = html_filename($html_nav_last);
print "<li class=\"first\"><a class=\"prev\" href=\"$lastf\">$html_nav_last</a></li>\n";
}
if (defined($html_nav_next)) {
my $nextf = html_filename($html_nav_next);
print "<li><a class=\"next\" href=\"$nextf\">$html_nav_next</a></li>\n";
}
print "<li><a class=\"toc\" href=\"nasmdoc0.html\">Contents</a></li>\n";
print "<li class=\"last\"><a class=\"index\" href=\"nasmdoci.html\">Index</a></li>\n";
print "</ul>\n";
print "<div class=\"title\">\n";
print "<h1>", $metadata{'title'}, "</h1>\n";
print '<span class="subtitle">', $metadata{'subtitle'}, "</span>\n";
print "</div>\n";
print "</div>\n";
print "<div class=\"contents\">\n";
}
sub html_postamble {
# Common closing tags
print "</div>\n</body>\n</html>\n";
}
sub html_index {

View file

@ -102,41 +102,89 @@ sections of interest, avoiding excessively long listings.
Use this option to specify listing output details.
Supported options are:
\c{-L} options for general use are:
\b \c{-Lb} show builtin macro packages (standard and \c{%use})
\b \c{-Lb} show builtin macro packages (standard and \c{%use}, see \k{use})
\b \c{-Lc} list the data from \c{INCBIN} files (see \k{incbin})
\b \c{-Ld} show byte and repeat counts in decimal, not hex
\b \c{-Le} show the preprocessed input
\b \c{-Le} show the preprocessed output
\b \c{-Lf} ignore \c{.nolist} and force listing output
\b \c{-Lf} ignore \c{.nolist} (force output) (see \k{nolist})
\b \c{-LF} ignore \c{[LIST -]} directives (force output) (see \k{LIST})
\b \c{-Lm} show multi-line macro calls with expanded parameters
\b \c{-Lp} output a list file in every pass, in case of errors
\b \c{-Lp} output a list file every pass, in case of errors
\b \c{-Ls} show all single-line macro definitions
\b \c{-Lw} flush the output after every line (very slow, mainly useful
to debug NASM crashes)
\b \c{-Lt} list the full output from \c{TIMES} and \c{ALIGN}
directives
\b \c{-L+} enable \e{all} listing options except \c{-Lw} (very verbose)
\b \c{-L+} equivalent to \c{-LbdefFmps}
\b \c{-L++} equivalent to \c{-L+} \c{-Lct}
\c{-L} options intended for the debugging of NASM itself (including
bug reporting), and not likely to be otherwise useful:
\b \c{-Lw} flush the output after every line (very slow!)
\b \c{-LX} list instruction pattern line numbers from \c{insns.xda}
\b \c{-L!} enable \e{all} listing options including debugging ones
For forward compatility reasons, an undefined flag will be
ignored. Thus, a new flag introduced in a newer version of NASM can be
specified without breaking older versions. Listing flags will always
be a single alphanumeric character and are case sensitive.
These options can be enabled or disabled at runtime using the
\c{%pragma list options} directive:
\c %pragma list options [+|-]flags...
\c %pragma list options [+|-|*]{!|flags}...
\c{+}, \c{-} and \c{*} adds, removes, or restores to the command-line
default the flags that follow.
For example, to turn on the \c{d} and \c{m} flags but disable the
\c{s} flag:
\c %pragma list options +dm -s
For forward compatility reasons, an undefined flag will be
ignored. Thus, a new flag introduced in a newer version of NASM can be
specified without breaking older versions. Listing flags will always
be a single alphanumeric character and are case sensitive.
The \c{+} and \c{++} shorthands available in on the command line are
not available when using \c{%pragma list options}; each listing option
needs to be specified explicitly, or \c{!} can be used to specify all
options.
Spaces, quotation marks, and commas in the argument are explicitly
ignored; thus, specifying the options as one or more quoted strings is
valid.
The built-in macros \i\c{__?LIST_OPTIONS?__} and
\i\c{__?LIST_OPTIONS_DEFAULT?__} contain the currently active and the
command-line default listing options, respectively, as quoted strings.
To save and restore the listing options, one can use:
\c %macro ...
\c %xdefine %%saved_list_options __?LIST_OPTIONS?__
\c %pragma list options ; ... changing the options
\c ; ... do stuff with special listing options ...
\c %pragma list options -! +%%saved_list_options
\c %endmacro
The statement:
\c %pragma list options -! +__?LIST_OPTIONS_DEFAULT?__
... is exactly equivalent to ...
\c %pragma list options *!
\S{opt-M} The \i\c{-M} Option: Generate \i{Makefile Dependencies}
@ -270,7 +318,7 @@ See also the \c{Visual C++} output format, \k{win32fmt}.
\S{opt-Z} The \i\c{-Z} Option: Send Errors to a File
Under \I{DOS}\c{MS-DOS} it can be difficult (though there are ways) to
Under \i{MS-DOS} it can be difficult (though there are ways) to
redirect the standard-error output of a program to a file. Since
NASM usually produces its warning and \i{error messages} on
\i\c{stderr}, this can make it hard to capture the errors if (for
@ -290,7 +338,7 @@ preprocessing only, with disastrous results. See \k{opt-E}.
\S{opt-s} The \i\c{-s} Option: Send Errors to \i\c{stdout}
The \c{-s} option redirects \i{error messages} to \c{stdout} rather
than \c{stderr}, so it can be redirected under \I{DOS}\c{MS-DOS}. To
than \c{stderr}, so it can be redirected under \i{MS-DOS}. To
assemble the file \c{myfile.asm} and pipe its output to the \c{more}
program, you can type:
@ -513,6 +561,9 @@ the \i\c{[WARNING]} directive. See \k{asmdir-warning}.
See \k{warnings} for the complete list of warning classes.
\IR{-v} \c{-v} option
\IR{--v} \c{--v} option
\S{opt-v} The \i\c{-v} Option: Display \i{Version} Info
Typing \c{NASM -v} will display the version of NASM which you are using,
@ -524,23 +575,45 @@ For command-line compatibility with Yasm, the form \i\c{--v} is also
accepted for this option starting in NASM version 2.11.05.
\S{opt-pfix} The \i\c{--(g|l)prefix}, \i\c{--(g|l)postfix} Options.
\IR{--prefix} \c{--prefix} option
\IC{--prefix}{--gprefix} \c{--gprefix} option
\IC{--prefix}{--lprefix} \c{--lprefix} option
\IC{--prefix}{--gpostfix} \c{--gpostfix} option
\IC{--prefix}{--lpostfix} \c{--lpostfix} option
\IC{--prefix}{--suffix} \c{--suffix} option
\IC{--prefix}{--gsuffix} \c{--gsuffix} option
\IC{--prefix}{--lsuffix} \c{--lsuffix} option
The \c{--(g)prefix} options prepend the given argument
\S{opt-pfix} The \I{--prefix}\c{--[gl]prefix} and \c{--[gl]postfix} Options
The \c{--gprefix} option prepends the given argument
to all \c{extern}, \c{common}, \c{static}, and \c{global} symbols, and the
\c{--lprefix} option prepends to all other symbols. Similarly,
\c{--(g)postfix} and \c{--lpostfix} options append
the argument in the exactly same way as the \c{--xxprefix} options does.
\c{--gpostfix} and \c{--lpostfix} options append
the argument, in a manner similar to the \c{--[gl]prefix} options.
Running this:
\c nasm -f macho --gprefix _
is equivalent to place the directive with \c{%pragma macho gprefix _}
is equivalent to placing the directive \c{%pragma macho gprefix _}
at the start of the file (\k{mangling}). It will prepend the underscore
to all global and external variables, as C requires it in some, but not all,
system calling conventions.
\c{--prefix} is an alias for \c{--gprefix}.
See \k{mangling} for the equivalent directives and pragmas.
Earlier versions of NASM called the pragmas \i\c{suffix} and the
options \i\c{--postfix}, and did not implement directives at all
despite being so documented. Since NASM 3.01, the directive forms are
implemented, and directives, pragmas and options all support all
spellings.
\IR{--pragma} \c{--pragma} option
\S{opt-pragma} The \i\c{--pragma} Option
NASM accepts an argument as \c{%pragma} option, which is like placing
@ -552,20 +625,39 @@ Running this:
is equivalent to the example in \k{opt-pfix}. See \k{pragma}.
\IR{--before} \c{--before} option
\S{opt-before} The \i\c{--before} Option
A preprocess statement can be accepted with this option. The example
shown in \k{opt-pragma} is the same as running this:
Insert a statement (usually, but not necessarily) a preprocess
statement before the input file. The example shown in \k{opt-pragma}
is the same as running this:
\c nasm -f macho --before "%pragma macho gprefix _"
\S{opt-limit} The \i\c{--limit-X} Option
\IR{--bits} \c{--bits} option
This option allows user to setup various maximum values after which
\S{opt-bits} The \i\c{--bits} Option
Set the processor mode by inserting a \c{BITS} directive (kee
\k{bits}) before the input file. The following two statements are
exactly equivalent:
\c nasm -f bin --bits 16 file.asm
\c nasm -f bin --before "BITS 16" file.asm
The \c{--bits} option was introduced in NASM 3.01; the \c{--before}
form can be used for compatibility with older versions of NASM.
\IR{--limit-} \c{--limit-} options
\S{opt-limit} The \i\c{--limit-} Options
These options allows user to setup various maximum values after which
NASM will terminate with a fatal error rather than consume arbitrary
amount of compute time. Each limit can be set to a positive number or
\c{unlimited}.
amount of compute time. Each limit can be set to a positive number,
\c{unlimited}, \c{maximum}, or \c{default}.
\b\c{--limit-passes}: Number of maximum allowed passes. Default is
\c{unlimited}.
@ -585,12 +677,15 @@ before returning to the top-level input. Default is 100000.
\b\c{--limit-rep}: Maximum number of allowed preprocessor loop, defined
under \c{%rep}. Default is 1000000.
\b\c{--limit-eval}: This number sets the boundary condition of allowed
\b\c{--limit-eval}: This number sets the maximum allowed
expression length. Default is 8192 on most systems.
\b\c{--limit-lines}: Total number of source lines allowed to be
processed. Default is 2000000000.
\b\c{--limit-params}: Maximum number of multi-line macro
parameters. Default is 16383.
For example, set the maximum line count to 1000:
\c nasm --limit-lines 1000
@ -600,18 +695,31 @@ example:
\c %pragma limit lines 1000
Specifying the limit value as \c{*} or \c{reset} resets the limit to
the value specified on the command line or the default value, undoing
any previous \c{%pragma limit}.
See also the \c{%limit()} preprocessor function (\k{f_limit}) and the
\c{__?NASM_LIMITS?__} standard macro (\k{nasm_limits}).
\IR{--keep-all} \c{--keep-all} option
\S{opt-keep-all} The \i\c{--keep-all} Option
This option prevents NASM from deleting any output files even if an
error happens.
\IR{--no-line} \c{--no-line} option
\S{opt-no-line} The \i\c{--no-line} Option
If this option is given, all \i\c{%line} directives in the source code
are ignored. This can be useful for debugging already preprocessed
code. See \k{line}.
\IR{--reproducible} \c{--reproducible} option
\S{opt-reproducible} The \i\c{--reproducible} Option
If this option is given, NASM will not emit information that is
@ -768,14 +876,10 @@ chooses to call them \c{st0}, \c{st1} etc.
For historical reasons, NASM uses the keyword \i\c{TWORD} where MASM
and compatible assemblers use \i\c{TBYTE}.
Historically, NASM does not declare \i{uninitialized storage} in the
Historically, NASM does not declare \i{uninitialized} storage in the
same way as MASM: where a MASM programmer might use \c{stack db 64 dup
(?)}, NASM requires \c{stack resb 64}, intended to be read as `reserve
64 bytes'. For a limited amount of compatibility, since NASM treats
\c{?} as a valid character in symbol names, you can code \c{? equ 0}
and then writing \c{dw ?} will at least do something vaguely useful.
As of NASM 2.15, the MASM syntax is also supported.
64 bytes'. As of NASM 2.15, the MASM syntax is also supported.
In addition to all of this, macros and directives work completely
differently to MASM. See \k{preproc} and \k{directive} for further
@ -783,4 +887,5 @@ details.
\S{masm-compat} MASM compatibility package
See \k{pkg_masm}.
The MASM compatibility macro package can be used to improve MASM
compatibility. See \k{pkg_masm}.

View file

@ -12,7 +12,10 @@ available, if you do not require changing the source code.
The preferred build platforms are development environments which
support POSIX (Unix)-style tools (a "POSIX environment"). For Windows,
MSYS2 (\w{https://www.msys2.org/}) is such a development environment.
MSYS2 (\w{https://www.msys2.org/}) is such a development
environment. Normally either \c{gcc} or \c{clang} is used as the
compiler, but it is also possible to use MSVC with a POSIX wrapper
like \W{https://github.com/swig/cccl}\c{cccl} from the SWIG project.
In a POSIX environment, run:
@ -23,15 +26,16 @@ A number of options can be passed to \c{configure}; see
\c{sh configure --help}. In particular, the \c{--host} option can be
used to cross-compile NASM to run on another host system.
For non-POSIX environments, a set of Makefiles for some other
For non-POSIX environments, a set of makefiles for a handful of other
environments are also available; please see the file
\c{Mkfiles/README}.
\c{Mkfiles/README}. These makefiles are generally considered
unreliable, as we have very little ability to test them.
The \c{.zip} version of the source archive has DOS/Windows line
endings (\c{CR LF}), which many POSIX systems will not recognize. To
extract the \c{.zip} version on such a system, use \c{unzip
-a}. The \c{.tar} versions of the source archive has POSIX line
endings (\c{LF}).
endings (\c{CR LF}), which many Unix/POSIX systems will not
recognize. To extract the \c{.zip} version on such a system, use
\c{unzip -a}. The \c{.tar} versions of the source archive has POSIX
line endings (\c{LF}).
\H{buildtools} Optional Build Tools
@ -64,9 +68,9 @@ To build the documentation:
\b Either Ghostscript (\w{https://www.ghostscript.com/}) or Adobe
Acrobat Distiller (untested.)
\b The Adobe \e{Source Sans} (or \e{Source Sans 3}) and \e{Source
Code} fonts, which are freely available under the SIL Open Font
License (\w{https://fonts.adobe.com/}).
\b The Google \e{Roboto} and \e{Roboto Mono} fonts, which are freely
available under the SIL Open Font License
(\w{https://github.com/google/roboto}).
To build the Unix man pages:
@ -134,14 +138,3 @@ To build modified sources, you will need the tools described in
Some build system changes might not be possible without a POSIX
environment.
If you have modified the sources to change the embedded declarations
of warning classes, you may have to manually re-build the warning
catalog:
\c make warnings
This is not done automatically, as the tools do not have the ability
to automatically detect when it is necessary to do so.

View file

@ -45,7 +45,7 @@ or
\c db 1,32,98,0
Note that the above lines are generate exactly the same code, the second
Note that the above lines generate exactly the same code, the second
line is used just to give an indication of the order that the separate
values will be present in memory.
@ -184,6 +184,20 @@ clock:
\c __?UTC_TIME_NUM?__ 210042
\c __?POSIX_TIME?__ 1262293242
\H{nasm_limits} \i\c{__?NASM_LIMITS?__}: List of Resource Limits
The standard macro \c{__?NASM_LIMITS?__} is defined as a
comma-separated list of quoted strings corresponding to all resource
limits defined in the current version of NASM. It also indicates the
availability of the \c{%limit()} function and the keywords
\c{default}, \c{maximum}, and \c{reset} for \c{%pragma limit}.
See \k{opt-limit} and \c{f_limit}.
\c{__?NASM_LIMITS?__} is defined since NASM 3.02.
\H{has_ifdirective} \i\c{__?NASM_HAS_IFDIRECTIVE?__}: Directive
Probing Support
@ -213,6 +227,20 @@ For example, if the \c{altreg} package is included (see
See also the \c{%ifusable} and \c{%ifusing} directives, \k{ifusing}.
\H{list_options_macro} \i\c{__?LIST_OPTIONS?__}: Current Listing Options
Contains a quoted string with the listing options currently in
effect. See \k{opt-L}.
\H{list_options_default_macro} \i\c{__?LIST_OPTIONS_DEFAULT?__}:
Default Listing Options
Contains a quoted string with the listing options originally specified
by the user on the command line. See \k{opt-L}.
\H{pass_macro} \i\c{__?PASS?__}: Assembly Pass
The macro \c{__?PASS?__} is defined to be \c{1} on preparatory passes,

434
doc/syntax.src Normal file
View file

@ -0,0 +1,434 @@
\C{Syntax} Syntax Quirks and Summaries
\H{jumpcall} Summary of the \c{JMP} and \c{CALL} Syntax
The \i\c{JMP} and \i\c{CALL} instructions support a variety of syntaxes to
simplify their specific use cases. Some of the following chapters explain how
these two instructions interact with various special symbols that NASM uses and
some document non-obvious scenarios regarding differently sized modes of
operation.
\S{labeljmps} \i{Near Jump}s
Near jumps are jumps within a single segment. Probably the most common way to
use them is through labels, as explained in \k{locallab}. \i\c{APX} added a near
jump instruction - \i\c{JMPABS}, that allows jumps to any \I{64-bit
immediate}64-bit address specified with an immediate operand. The instruction
works with absolute addresses and the syntax options are shown in
\k{jmpabs}.
\S{jumploop} \i{Infinite Loop} Trick
One of the ways to quickly implement an infinite loop is using the \I{$,
here}\c{$} token which evaluates to the current position in the code. So a one
line infinite loop can simply look like:
\c jmp $
\S{mixsizejmpsum} Jumps and Mixed Sizes
\I{jumps, mixed-size}In some special circumstances one might need to jump
between 16-bit mode and 32-bit mode. \I{addressing, mixed-size}\I{mixed-size
addressing}A similar issue is addressing between 16 and 32 bit segments. The
possible cases and the relevant syntax for both problems are explained in
\k{mixjump} and \k{mixaddr} respectively.
\S{callprocoutlib} Calling Procedures Outside of a Shared Library
When writing shared libraries it's often necessary to call external code. In the
ELF format the \I\c{WRT} keyword takes on a different meaning than normally when
it helps reference a segment - it's used to refer to some special symbols (more
about it can be found in \k{win64pic}). In the case described here, "\c{wrt}
\i\c{..plt}" references a \i{PLT} (\i{procedure linkage table}) entry. It can be
used to call external routines in a way explained in \k{picproc}.
\S{farcall} \I{far call}\I{far jmp}\c{FAR} Calls and Jumps
NASM supports \c{FAR} (inter-segment) calls and jumps by means of the
syntax \c{call segment:offset}, where \c{segment} and \c{offset}
both represent immediate values. So to call a far procedure, you
could code either of
\c call (seg procedure):procedure
\c call weird_seg:(procedure wrt weird_seg)
(The parentheses are included for clarity, to show the intended
parsing of the above instructions. They are not necessary in
practice.)
NASM also supports the syntax \I\c{CALL FAR}\c{call far procedure} as
a synonym for the first of the above usages. \c{JMP} works identically
to \c{CALL} in these examples.
To declare a \i{far pointer} to a data item in a data segment, you
must code
\c dw symbol, seg symbol ; 16 bit
\c dd symbol, word seg symbol ; 32 bit
NASM supports no convenient synonym for this, though you can always
invent one using the macro processor.
\S{jmpabs} 64-bit absolute jump (\i\c{JMPABS})
Defined as part of the APX specification, \c{JMPABS} is a new near
jump instruction takes a 64-bit \e{absolute} address immediate. It is
the only \e{direct} jump instruction that can jump anywhere in the
address space in 64-bit mode.
NASM allows this instruction to be specified either as:
\c jmpabs target
... or:
\c jmp abs target
The generated code is identical. The \c{ABS} is required regardless of
the \c{DEFAULT} setting.
\S{opt_jumps} Optimizing jump lengths and sizes
\i\c{JMP} lengths can be specified using keywords such as \i\c{SHORT} and
\i\c{NEAR}. The keyword used also has consequences in how many bytes will be
emitted in the final assembled instruction. It's worth to note the behavior of
\c{SHORT} and \c{NEAR} for example in 16 bit mode. If it's specifically required
to emit a 3 byte encoding of the jump instruction, then the \c{NEAR} version
shall always fulfill this requirement, even if the jump is made within a
\c{SHORT} distance (so up to a byte away). If the optimized version is expected
then it's best to not use a length specifier at all and let the assembler pick
the relevant version by itself.
Using size specifiers with jumps (and therefore with labels which are just
immediates) will be optimized down to the shortest possible encoding since the
size specifier is relevant to the operation size and not to the jump length.
\c 00000000 EB09 jmp label
\c 00000002 EB07 jmp SHORT label
\c 00000004 E90400 jmp NEAR label
\c 00000007 EB02 jmp BYTE label
\c 00000009 EB00 jmp WORD label
\c
\c label:
\H{shortnddnds} Compact \i{NDS}/\i{NDD} Operands
Some instructions that use the \i\c{VEX} prefix, mainly AVX ones, use
NDS (\i{Non-Destructive Source}) or NDD (\i{New Data Destination})
operands. Semantically it works by passing another operand to the
instruction so that none of the source operands are modified as a
result of the operation.
Syntactically NASM allows both the obvious format mentioned above and a
\i{compact format} - compact meaning that if a user passes two
operands instead of three, one of them is simply copied to be used as
the source or destination. Thereby these instructions have exactly
the same encoding:
\c vaddpd xmm0, xmm0, xmm1
\c vaddpd xmm0, xmm1
Here the \c{XMM0} register is used as the "non-destructive
source" even though in this case it will of course be modified.
\H{64moff} 64-bit \I{moffs}\e{moffs}
The \e{moffs} operand can be used with the \c{MOV} instruction, only
using the "\c{A}" register (\c{AL}, \c{AX}, \c{EAX}, or \c{RAX}), and
for non-64-bit operand size means to address memory at an offset from
a segment. For \I{64-bit immediate}64-bit operands it simply accesses
memory at a specified offset (since segment based addressing is mostly
unavailable in 64-bit mode). Syntax to use 64-bit offsets to address
memory is showcased in \k{id64disp}.
\H{spliteas} \i{Split EA} Addressing Syntax
Instructions that use the mib operand, (that is memory addressed with a base
register, with some offset, with an added index register that's multiplied by
some scale factor) can also utilize the split EA (\I{effective
addresses}effective addressing). The new form is mainly intended for MPX
instructions that use the \i{mib} operands, but can be used for any memory
reference. The basic concept of this form is splitting base and index:
\c mov eax,[ebx+8,ecx*4] ; ebx=base, ecx=index, 4=scale, 8=disp
NASM supports all currently possible forms of the mib syntax:
\c ; bndstx
\c ; next 5 lines are parsed same
\c ; base=rax, index=rbx, scale=1, displacement=3
\c bndstx [rax+0x3,rbx], bnd0 ; NASM - split EA
\c bndstx [rbx*1+rax+0x3], bnd0 ; GAS - '*1' indecates an index reg
\c bndstx [rax+rbx+3], bnd0 ; GAS - without hints
\c bndstx [rax+0x3], bnd0, rbx ; ICC-1
\c bndstx [rax+0x3], rbx, bnd0 ; ICC-2
\H{ternarylogic} No Syntax for Ternary Logic Instruction
\i\c{VPTERNLOGD} and \i\c{VPTERNLOGQ} are instructions that implement
an arbitrary logic function for three inputs. They take three register
operands and one immediate value that determines what logic function
the instruction shall implement on execution. Specifically the output
of the desired logic function is encoded in the immediate 8-bit
operand. 3 binary inputs can be configured in 8 possible ways giving 8
output bits that could implement any one of 256 possible logic
functions. Therefore it's not practical to have any syntax around
different possible logic functions.
However there are some macro solutions that can help avoid writing out truth
tables in order to use the ternary logic instructions. The simple, more manual
way is to calculate the logic operation encoding on the fly with a few lines of
arithmetic directives:
\c a equ 0xaa
\c b equ 0xcc
\c c equ 0xf0
\c imm equ a | b & c
Here, values for "a", "b" and "c" together are all possible bit configurations
that a 3 input function can take ("a" being the least significant bit and "c"
being the most significant one). Then the "imm" variable is calculated by
evaluating the desired logic function, in this case "a or b and c", thereby
getting the function's output column that one would get when writing out the
truth tables.
Note that only the expression must be written using the bitwise
operators \c{&}, \c{|}, \c{^}, and \c{~}. Using the boolean operators
\c{&&}, \c{||}, \c{^^}, \c{!} and \c{? :} will not work correctly.
The \i\c{vtern} standard macro package, \k{pkg_vtern}, allows for
these kinds of expressions without introducing the symbols \c{a},
\c{b} and \c{c} into the global namespace:
\c %use vtern
\c vpternlogd xmm1, xmm2, xmm3, a | b & c
\c vpternlogq ymm4, ymm5, xmm6, (b ^ c) & ~a
\c ; a, b, and c are not defined as symbols elsewhere
\H{APX} \I{apx syntax}\i{APX} Instruction Syntax
Intel APX (\i{Advanced Performance Extensions}) introduces multiple
new features, mostly to existing instructions. APX is only available
in 64-bit mode.
\b There are 16 new general purpose registers, \c{R16} to \c{R31}.
\b Many instructions now support a non-destructive destination
operand.
\b The ability to suppress the setting of the arithmetic flags.
\b The ability to zero the upper parts of a full 64-bit register for
8- and 16-bit operation size instructions. (This zeroing is always
performed for 32-bit operations; this has been the case since 64-bit
mode was first introduced.)
\b New instructions to conditionally set the arithmetic flags to a
user-specified value.
\b Performance-enhanced versions of the \c{PUSH} and \c{POP}
instructions.
\b A 64-bit absolute jump instruction.
\b A new \i{REX2} prefix.
See \w{https://www.nasm.us/specs/apx} for a link to the APX technical
documentation. NASM generally follows the syntax specified in the
\e{Assembly Syntax Recommendations for Intel APX} document although
some syntax is relaxed, see below.
\S{egprs} \i{Extended General Purpose Registers} (\i{EGPRs})
When it comes to register size, the new registers (\c{R16}-\c{R31})
work the same way as registers \c{R8}-\c{R15} (see also \k{reg64}):
\b \c{R31} is the 64-bit form of register 31,
\b \c{R31D} is the 32-bit form,
\b \c{R31W} is the 16-bit form, and
\b \c{R31B} is the 8-bit form. The form \c{R31L} can also be used if
the \c{altreg} macro package is used (\c{%use altreg}), see
\k{pkg_altreg}.
Extended registers require that either a REX2 prefix (the default, if
possible) or an EVEX prefix is used.
There are some instructions that don't support EGPRs. In that case,
NASM will generate an error if they are used.
\S{apx_ndd} \i{New Data Destination} (\i{NDD})
Using the new data destination register (when supported) is specified
by adding an additional register in place of the first operand.
For example an \c{ADD} instruction:
\c add rax, rbx, rcx
... which would add \c{RBX} and \c{RCX} and store the result in
\c{RAX}, without modifying neither \c{RBX} nor \c{RCX}.
\S{apx_nf} Suppress Modifying Flags (\i{NF})
The \c{\{nf\}} prefix on a supported instruction inhibits the update
of the flags, for example:
\c {nf} add rax, rbx
... will add \c{RAX} and \c{RBX} together, storing the result in
\c{RAX}, while leaving the flags register unchanged.
NASM also allows the \c{\{nf\}} prefix (or any other curly-brace
prefix) to be specified \e{after} the instruction mnemonic. Spaces
around curly-brace prefixes are optional:
\c {nf} add rax, rbx ; Standard syntax
\c {nf}add rax, rbx ; Prefix without space
\c add {nf} rax, rbx ; Suffix syntax
\c add{nf} rax, rbx ; Suffix without space
\S{apx_zu} \i{Zero Upper} (\i{ZU})
The \c{\{zu\}} prefix can be used meaning -
"zero-upper", which disables retaining the upper parts of the
registers and instead zero-extends the value into the full 64-bit
register when the operand size is 8 or 16 bits (this is always done
when the operand size is 32 bits, even without APX). For example:
\c {zu} setb al
... zeroes out bits [63:8] of the \c{RAX} register. For this specific
instruction, NASM also eccepts these alternate syntaxes:
\c {zu} setb ax
\c setb {zu} al
\c setb {zu} ax
\c setb {zu} eax
\c setb {zu} rax
\c setb eax
\c setb rax
\S{apx_dfv} \i{Source Condition Code} (\I{scc}S\e{cc}) and \i{Default Flags
Value} (\i{DFV})
The source condition code (S\e{cc}) instructions, \c{CCMPS}\e{cc} and
\c{CTESTS}\c{cc}, perform a test which if successful set the
arithmetic flags to a user specfied value and otherwise leave them
unchanged.
NASM allows the resulting \e{default flags value} to be specified
either using the \I\c{\{dfv=\}}\c{\{dfv=\}}...\c{\}} syntax,
containing a comma-separated list of zero or more of the CPU flags
\c{OF}, \c{SF}, \c{ZF} or \c{CF} or simply as a numeric immediate
(with \c{OF}, \c{SF}, \c{ZF} and \c{CF} being represented by bits 3 to
0 in that order.)
The \c{PF} flag is always set to the same value as the \c{CF} flag,
and the \c{AF} flag is always cleared. NASM allows \c{\{dfv=pf\}} as
an alias for \c{\{dfv=cf\}}, but do note that it still affects both
flags.
NASM allows, but does not require, a comma after the \c{\{dfv=\}}
value; when using the immediate syntax a comma is required; these
examples all produce the same instruction:
\c ccmpl {dfv=of,cf} rdx, r30
\c ccmpl {dfv=of,cf}, rdx, r30
\c ccmpl 0x9, rdx, r30 ; Comma required
The immediate syntax also allows for the \c{\{dfv=\}} values to be
stored in a symbol, or having arithmetic done on them. Note that when
used in an expression, or in contexts other than \c{EQU} or one of the
\c{S}\e{cc} instructions, parenteses are required; this is a safety
measure (programmer needs to explicitly indicate that use as an
expression is what is intended):
\c ccmpl ({dfv=of}|{dfv=cf}), rdx, r30 ; Parens, comma required
\c ocf1 equ {dfv=of,cf} ; Parens not required
\c ccmpl ocf1, rdx, r30 ; Comma required
\c ofcf equ ({dfv=of,sf,cf} & ~{dfv=sf}) ; Parens required
\c ccmpl ofcf2, rdx, r30 ; Comma required
\S{apx_pushpop} \c{PUSH} and \c{POP} Extensions
APX adds variations of the \c{PUSH} and \c{POP} instructions that:
\b informs the CPU that a specific \c{PUSH} and \c{POP} constitute a
matched pair, allowing the hardware to optimize for this common use
case: \i\c{PUSHP} and \i\c{POPP};
\b operates on two registers at the same time: \i\c{PUSH2} and
\i\c{POP2}, with paired variants \i\c{PUSH2P} and \i\c{POP2P}.
These extensions only apply to register forms; they are not supported
for memory or immediate operands.
The standard syntax for (\c{P})\c{PUSH2} and (\c{P})\c{POP2} specify
the registers in the order they are to be pushed and popped on the
stack:
\c push2p rax, rbx
\c ; rax in [rsp+8]
\c ; rbx is [rsp+0]
\c pop2p rbx, rax
... would be the equivalent of:
\c push rax
\c push rbx
\c ; rax in [rsp+8]
\c ; rbx is [rsp+0]
\c pop rbx
\c pop rax
NASM also allows the registers to be specified as a \e{register pair}
separated by a colon, in which case the order is always specified in
the order \e{high}\c{:}\e{low} and thus is the same for \c{PUSH2} and
\c{POP2}. This means the order of the operands in the \c{POP2}
instruction is different:
\c push2p rax:rbx
\c ; rax in [rsp+8]
\c ; rbx is [rsp+0]
\c pop2p rax:rbx
\S{apx_opt} \I{apx optimizer}APX and the NASM optimizer
When the optimizer is enabled (see \k{opt-O}), NASM may apply a number
of optimizations, some of which may apply non-APX instructions to what
otherwise would be APX forms. Some examples are:
\b The \c{\{nf\}} prefix may be ignored on instructions that already
don't modify the arithmetic flags.
\b When the \c{\{nf\}} prefix is specified, NASM may generate another
instruction which would not modify the flags register. For example,
\c{\{nf\} ror rax, rcx, 3} can be translated into
\c{rorx rax, rcx, 3}.
\b The \c{\{zu\}} prefix may be ignored on instruction that already
zero the upper parts of the destination register.
\b When the \c{\{zu\}} prefix is specified, NASM may generate another
instruction which would zero the upper part of the register. For
example, \c{\{zu\} mov ax, cs} can be translated into \c{mov eax, cs}.
\b New data destination or nondestructive source operands may be
contracted if they are the same (and the semantics are otherwise
identical). For example, \c{add eax, eax, edx} could be encoded as
\c{add eax, edx} using legacy encoding. \e{NASM does not perform
this optimization as of version 3.00, but it probably will in the
future.}
\S{apx_force} Force APX Encoding
APX encoding, using REX2 and EVEX, respectively, can be forced by
using the \i\c{\{rex2\}} or \i\c{\{evex\}} instruction prefixes.

168
editors/builtin.mac Normal file
View file

@ -0,0 +1,168 @@
;;; Automatically generated list of builtin macros
%define __?FILE?__
%define __?LINE?__
%define __?BITS?__
%define __?PTR?__
%define __?DEFAULT?__
%define __?LIST_OPTIONS?__
%idefine %abs(=)
%idefine %chr(=+)
%idefine %count(+)
%idefine %depend()
%idefine %eval(=+)
%idefine %hs2b(&&+)
%idefine %map(+)
%idefine %null(+)
%idefine %pathsearch()
%idefine %realpath()
%idefine %selbits(+)
%idefine %str(&+)
%idefine %strcat(&&+)
%idefine %strlen(&&)
%idefine %tok(&&)
%idefine %is(+)
%idefine %isctx(+)
%idefine %isdef(+)
%idefine %isdefalias(+)
%idefine %isdifi(+)
%idefine %isdirective(+)
%idefine %isempty(+)
%idefine %isenv(+)
%idefine %isfile(+)
%idefine %isid(+)
%idefine %isidn(+)
%idefine %isidni(+)
%idefine %ismacro(+)
%idefine %isnum(+)
%idefine %isstr(+)
%idefine %istoken(+)
%idefine %isusable(+)
%idefine %isusing(+)
%idefine %isn(+)
%idefine %isnctx(+)
%idefine %isndef(+)
%idefine %isndefalias(+)
%idefine %isndifi(+)
%idefine %isndirective(+)
%idefine %isnempty(+)
%idefine %isnenv(+)
%idefine %isnfile(+)
%idefine %isnid(+)
%idefine %isnidn(+)
%idefine %isnidni(+)
%idefine %isnmacro(+)
%idefine %isnnum(+)
%idefine %isnstr(+)
%idefine %isntoken(+)
%idefine %isnusable(+)
%idefine %isnusing(+)
%idefine %hex(=+/ux)
%idefine %sel(=,+)
%idefine %cond(=,,)
%idefine %num(=,=,=)
%idefine %substr(&&,=,=)
%idefine %ord(&&,=,=)
%idefine %b2hs(&&,&&)
%idefine %limit(&&,&&)
%idefine %env(&&)
%idefine %env(&&,+)
%idefine %findi(&&,+)
%idefine %find(&&,+)
%define __?NASM_LIMITS?__
%define __?LIST_OPTIONS_DEFAULT?__
%define __?PASS?__
%define __?SECT?__
%defalias __SECT__
%define __?SECTALIGN_ALIGN_UPDATES_SECTION?__
%defalias __SECTALIGN_ALIGN_UPDATES_SECTION__
%define __?FLOAT_DAZ?__
%define __?FLOAT_ROUND?__
%define __?FLOAT?__
%defalias __FLOAT_DAZ__
%defalias __FLOAT_ROUND__
%defalias __FLOAT__
%defalias __NASM_MAJOR__
%defalias __NASM_MINOR__
%defalias __NASM_SUBMINOR__
%defalias __NASM_PATCHLEVEL__
%defalias __NASM_SNAPSHOT__
%defalias __NASM_VERSION_ID__
%defalias __NASM_VER__
%defalias __OUTPUT_FORMAT__
%defalias __DEBUG_FORMAT__
%defalias __DATE__
%defalias __DATE_NUM__
%defalias __TIME__
%defalias __TIME_NUM__
%defalias __UTC_DATE__
%defalias __UTC_DATE_NUM__
%defalias __UTC_TIME__
%defalias __UTC_TIME_NUM__
%defalias __POSIX_TIME__
%defalias __FILE__
%defalias __LINE__
%defalias __BITS__
%defalias __PTR__
%defalias __PASS__
%idefine __?infinity?__
%idefine __?nan?__
%idefine __?qnan?__
%idefine __?snan?__
%idefine __?float8?__
%idefine __?float16?__
%idefine __?float32?__
%idefine __?float64?__
%idefine __?float80m?__
%idefine __?float80e?__
%idefine __?float128l?__
%idefine __?float128h?__
%idefine __?utf16?__
%idefine __?utf16le?__
%idefine __?utf16be?__
%idefine __?utf32?__
%idefine __?utf32le?__
%idefine __?utf32be?__
%idefine __?ilog2e?__
%idefine __?ilog2w?__
%idefine __?ilog2f?__
%idefine __?ilog2c?__
%idefalias __infinity__
%idefalias __nan__
%idefalias __qnan__
%idefalias __snan__
%idefalias __float8__
%idefalias __float16__
%idefalias __float32__
%idefalias __float64__
%idefalias __float80m__
%idefalias __float80e__
%idefalias __float128l__
%idefalias __float128h__
%idefalias __utf16__
%idefalias __utf16le__
%idefalias __utf16be__
%idefalias __utf32__
%idefalias __utf32le__
%idefalias __utf32be__
%idefalias __ilog2e__
%idefalias __ilog2w__
%idefalias __ilog2f__
%idefalias __ilog2c__
%define __?NASM_HAS_IFDIRECTIVE?__
%define __?NASM_MAJOR?__
%define __?NASM_MINOR?__
%define __?NASM_SUBMINOR?__
%define __?NASM_PATCHLEVEL?__
%define __?NASM_VERSION_ID?__
%define __?NASM_VER?__
%define __?SECT?__
%define __?DATE?__
%define __?DATE_NUM?__
%define __?TIME?__
%define __?TIME_NUM?__
%define __?UTC_DATE?__
%define __?UTC_DATE_NUM?__
%define __?UTC_TIME?__
%define __?UTC_TIME_NUM?__
%define __?POSIX_TIME?__
%define __?OUTPUT_FORMAT?__

21
editors/dumpbuiltin.sh Executable file
View file

@ -0,0 +1,21 @@
#!/bin/sh -
# Copyright 1996-20xx The NASM Authors - All Rights Reserved
# SPDX-License-Identifier: BSD-2-Clause
#
# Run the nasm binary and extract the list of macros that may or may
# not be defined in .mac files.
#
tmp="$(mktemp -d)"
[ -n "$tmp" ] || exit 1
NASM="${NASM:-../nasm}"
NASM="${1:-$NASM}"
: > "$tmp/junk.asm"
"$NASM" -f bin -o "$tmp/junk.bin" -Lsb -l "$tmp/junk.lst" "$tmp/junk.asm"
printf ';;; Automatically generated list of builtin macros\n'
sed -n -E -e 's/^[^;]*;;; *(%i?(define|defalias|macro)) ([^ ]*) .*$/\1 \3/p'\
< "$tmp/junk.lst"
rm -rf "$tmp"

423
editors/nasmtok.pl Executable file
View file

@ -0,0 +1,423 @@
#!/usr/bin/perl
#
# Automatically produce some tables useful for an emacs NASM major mode
#
use integer;
use strict;
use File::Spec;
use File::Find;
my $format = 'el';
if ($ARGV[0] =~ /^-(\S+)$/) {
$format = $1;
shift @ARGV;
}
my($outfile, $srcdir, $objdir) = @ARGV;
if (!defined($outfile)) {
die "Usage: $0 [-format] outfile srcdir objdir\n";
}
my @vpath;
$srcdir = $srcdir || File::Spec->curdir();
$objdir = $objdir || $srcdir;
push(@vpath, $objdir) if ($objdir ne $srcdir);
push(@vpath, $srcdir);
my %tokens = (); # Token lists per category
my %token_category = (); # Tokens to category map
sub xpush($@) {
my $ref = shift @_;
$$ref = [] unless (defined($$ref));
return push(@$$ref, @_);
}
# Search for a file, and return a file handle if successfully opened
sub open_vpath($$) {
my($mode, $file) = @_;
my %tried;
# For simplicity, allow filenames to be specified
# with Unix / syntax internally
$file = File::Spec->catfile(split(/\//, $file));
foreach my $d (@vpath) {
my $fn = File::Spec->catfile($d, $file);
next if ($tried{$fn});
$tried{$fn}++;
my $fh;
return $fh if (open($fh, $mode, $fn));
}
return undef;
}
sub must_open($) {
my($file) = @_;
my $fh = open_vpath('<', $file);
return $fh if (defined($fh));
die "$0:$file: $!\n";
}
# Combine some specific token types
my %override = (
'brcconst' => 'special-constant',
'id' => 'special',
'float' => 'function',
'floatize' => 'function',
'strfunc' => 'function',
'ifunc' => 'function',
'insn' => 'instruction',
'reg' => 'register',
'seg' => 'special',
'wrt' => 'special',
'times' => 'special');
sub addtoken($@) {
my $type = shift @_;
foreach my $token (@_) {
unless (defined($token_category{$token})) {
$type = $override{$type} if (defined($override{$type}));
xpush(\$tokens{$type}, $token);
$token_category{$token} = $type;
}
}
}
sub read_tokhash_c($) {
my($tokhash_c) = @_;
my $th = must_open($tokhash_c);
my $l;
my $tokendata = 0;
while (defined($l = <$th>)) {
if ($l =~ /\bstruct tokendata tokendata\[/) {
$tokendata = 1;
next;
} elsif (!$tokendata) {
next;
}
last if ($l =~ /\}\;/);
if ($l =~ /^\s*\{\s*\"(.*?)\",.*?,\s*TOKEN_(\w+),(.*)\}/) {
my $token = $1;
my $type = lc($2);
my $flags = $3;
$token = "{${token}}" if ($flags =~ /\bTFLAG_BRC\b/);
# Parametric token: omit the actual parameter(s)
$token =~ s/^(\{[\w-]+=).+(\})$/$1$2/;
if ($token !~ /^(\{[\w-]+=?\}|\w+)$/) {
$type = 'operator';
} elsif ($token =~ /^__\?masm_.*\?__$/) {
next;
}
addtoken($type, $token);
if ($token =~ /^__\?(.*)\?__$/) {
# Also encode the "user" (macro) form without __?...?__
addtoken($type, $1);
}
}
}
close($th);
}
sub read_pptok_c($) {
my($pptok_c) = @_;
my $pt = must_open($pptok_c);
my $l;
my $pp_dir = 0;
while (defined($l = <$pt>)) {
if ($l =~ /\bpp_directives\[/) {
$pp_dir = 1;
next;
} elsif (!$pp_dir) {
next;
}
last if ($l =~ /\}\;/);
if ($l =~ /^\s*\"(.*?)\"/) {
addtoken('pp-directive', $1);
}
}
close($pt);
}
sub read_directiv_dat($) {
my($directiv_dat) = @_;
my $dd = must_open($directiv_dat);
my $l;
my $directiv = 0;
while (defined($l = <$dd>)) {
if ($l =~ /^\; ---.*?(pragma)?/) {
$directiv = ($1 ne 'pragma');
next;
} elsif (!$directiv) {
next;
}
if ($l =~ /^\s*(\w+)/) {
addtoken('directive', $1);
}
}
close($dd);
}
my %version;
sub read_version($) {
my($vfile) = @_;
my $v = must_open($vfile);
while (defined(my $vl = <$v>)) {
if ($vl =~ /^NASM_(\w+)=(\S+)\s*$/) {
$version{lc($1)} = $2;
}
}
close($v);
}
# This is called from the directory search in read_macros(), so
# don't use must_open() here.
sub read_macro_file($) {
my($file) = @_;
open(my $fh, '<', $file) or die "$0:$file: $!\n";
while (defined(my $l = <$fh>)) {
next unless ($l =~ /^\s*\%/);
my @f = split(/\s+/, $l);
next unless (scalar(@f) >= 2);
next if ($f[1] =~ /^[\%\$][^\(]+$/); # Internal use only
$f[1] =~ s/\(.*$//; # Strip argument list if any
$f[1] = lc($f[1]) if ($f[0] =~ /^\%i/);
if ($f[0] =~ /^\%(i)?(assign|defalias|define|defstr|substr|xdefine)\b/) {
addtoken('smacro', $f[1]);
} elsif ($f[0] =~ /^\%i?macro$/) {
addtoken('mmacro', $f[1]);
}
}
close($fh);
}
sub read_macros(@) {
my %visited;
my @dirs = (File::Spec->curdir(), qw(macros output editors));
@dirs = map { my $od = $_; map { File::Spec->catdir($od, $_) } @dirs } @_;
foreach my $dir (@dirs) {
next if ($visited{$dir});
$visited{$dir}++;
next unless opendir(my $dh, $dir);
while (defined(my $fn = readdir($dh))) {
next unless ($fn =~ /\.mac$/i);
read_macro_file(File::Spec->catfile($dir, $fn));
}
closedir($dh);
}
}
# Handle special tokens which may not have been picked up by the automatic
# process, because they depend on the build parameters, or are buried
# deep in C code...
sub add_special_cases() {
# Not defined in non-snapshot builds
addtoken('smacro', '__NASM_SNAPSHOT__', '__?NASM_SNAPSHOT?__');
}
sub make_lines($$@) {
my $maxline = shift @_;
my $indent = shift @_;
# The first line isn't explicitly indented and the last line
# doesn't end in "\n"; assumed the surrounding formatter wants
# do control that
my $linepos = 0;
my $linewidth = $maxline - $indent;
my $line = '';
my @lines = ();
foreach my $w (@_) {
my $l = length($w);
if ($linepos > 0 && $linepos+$l+1 >= $linewidth) {
$line .= "\n" . (' ' x $indent);
push(@lines, $line);
$linepos = 0;
$line = '';
}
if ($linepos > 0) {
$line .= ' ';
$linepos++;
}
$line .= $w;
$linepos += $l;
}
if ($linepos > 0) {
push(@lines, $line);
}
return @lines;
}
sub quote_for_emacs(@) {
return map { s/[\\\"\']/\\$1/g; '"'.$_.'"' } @_;
}
# Emacs LISP
sub write_output_el {
my($out, $outfile, $file) = @_;
my $whoami = 'NASM '.$version{'ver'};
print $out ";;; ${file} --- lists of NASM assembler tokens\n\n";
print $out ";;; Commentary:\n\n";
print $out ";; This file contains list of tokens from the NASM x86\n";
print $out ";; assembler, automatically extracted from ${whoami}.\n";
print $out ";;\n";
print $out ";; This file is intended to be (require)d from a `nasm-mode\'\n";
print $out ";; major mode definition.\n";
print $out ";;\n";
print $out ";; Tokens that are only recognized inside curly braces are\n";
print $out ";; noted as such. Tokens of the form {xxx=} are parametric\n";
print $out ";; tokens, where the token may contain additional text on\n";
print $out ";; the right side of the = sign. For example,\n";
print $out ";; {dfv=} should be matched by {dfv=cf,zf}.\n";
print $out "\n";
print $out ";;; Code:\n";
my @types = sort keys(%tokens);
# Write the individual token type lists
foreach my $type (sort keys(%tokens)) {
print $out "\n(defconst nasm-${type}\n";
print $out " \'(";
print $out make_lines(78, 4, quote_for_emacs(sort @{$tokens{$type}}));
print $out ")\n";
print $out " \"${whoami} ${type} tokens for `nasm-mode\'.\")\n";
}
# Generate a list of all the token type lists.
print $out "\n(defconst nasm-token-lists\n";
print $out " \'(";
print $out make_lines(78, 4, map { "nasm-$_" } sort keys(%tokens));
print $out ")\n";
print $out " \"List of all ${whoami} token type lists.\")\n";
# The NASM token extracted version
printf $out "\n(defconst nasm-token-version %s\n",
quote_for_emacs($version{'ver'});
print $out " \"Version of NASM from which tokens were extracted,\n";
print $out "as a human-readable string.\")\n";
printf $out "\n(defconst nasm-token-version-id #x%08x\n",
$version{'version_id'};
print $out " \"Version of NASM from which tokens were extracted,\n";
print $out "as numeric identifier, for comparisons. Equivalent to the\n";
print $out "__?NASM_VERSION_ID?__ NASM macro value.\")\n";
printf $out "\n(defconst nasm-token-version-snapshot %s\n",
$version{'snapshot'} || 'nil';
print $out " \"Daily NASM snapshot build from which tokens were extracted,\n";
print $out "as a decimal number in YYYYMMDD format, or nil if not a\n";
print $out "daily snapshot build.\")\n";
# Footer
print $out "\n(provide 'nasmtok)\n";
print $out ";;; ${file} ends here\n";
return 0;
}
# JSON
sub write_output_json {
use JSON;
my($out, $outfile, $file) = @_;
my $whoami = 'NASM '.$version{'ver'};
my $json = JSON->new;
$json = $json->ascii(1)->canonical(1);
my %ver;
foreach my $vn (keys(%version)) {
my $vv = $version{$vn};
next if ($vn eq 'version_xid');
$vn =~ s/_ver$//;
$vn =~ s/^version_//;
$vv = $vv + 0 if ($vn ne 'ver');
$ver{$vn} = $vv;
}
my $txt = $json->encode({
'$comment' => "NASM syntax information extracted from ${whoami}",
'tokens' => \%tokens, 'version' => \%ver});
# $json->encode() creates a single long line; break up the lines
# at least...
my @txt = split(/\,/, $txt);
my $last = shift @txt;
foreach my $t (@txt) {
if (length($last)+length($t) > 77) {
print $out $last, ",\n";
$last = $t;
} else {
$last .= ",$t";
}
}
print $out $last, "\n";
return 0;
}
sub write_output($$) {
my($format, $outfile) = @_;
my %formats = (
'el' => \&write_output_el,
'json' => \&write_output_json
);
my $outfunc = $formats{$format};
if (!defined($outfunc)) {
die "$0: unknown output format: $format\n";
}
open(my $out, '>', $outfile)
or die "$0:$outfile: $!\n";
my($vol,$dir,$file) = File::Spec->splitpath($outfile);
my $err = $outfunc->($out, $outfile, $file);
close($out);
if ($err) {
unlink($outfile);
die "$0:$outfile: error writing output\n";
}
}
add_special_cases();
read_tokhash_c('asm/tokhash.c');
read_pptok_c('asm/pptok.c');
read_directiv_dat('asm/directiv.dat');
read_version('version.mak');
read_macros(@vpath);
write_output($format, $outfile);

View file

@ -1,33 +0,0 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 1996-2010 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ----------------------------------------------------------------------- */

View file

@ -1,33 +0,0 @@
\# --------------------------------------------------------------------------
\#
\# Copyright 1996-2010 The NASM Authors - All Rights Reserved
\# See the file AUTHORS included with the NASM distribution for
\# the specific copyright holders.
\#
\# Redistribution and use in source and binary forms, with or without
\# modification, are permitted provided that the following
\# conditions are met:
\#
\# * Redistributions of source code must retain the above copyright
\# notice, this list of conditions and the following disclaimer.
\# * Redistributions in binary form must reproduce the above
\# copyright notice, this list of conditions and the following
\# disclaimer in the documentation and/or other materials provided
\# with the distribution.
\#
\# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
\# CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
\# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
\# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
\# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
\# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
\# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
\# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
\# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
\# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
\# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
\# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
\# EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
\#
\# --------------------------------------------------------------------------

View file

@ -1,33 +0,0 @@
;; --------------------------------------------------------------------------
;;
;; Copyright 1996-2010 The NASM Authors - All Rights Reserved
;; See the file AUTHORS included with the NASM distribution for
;; the specific copyright holders.
;;
;; Redistribution and use in source and binary forms, with or without
;; modification, are permitted provided that the following
;; conditions are met:
;;
;; * Redistributions of source code must retain the above copyright
;; notice, this list of conditions and the following disclaimer.
;; * Redistributions in binary form must reproduce the above
;; copyright notice, this list of conditions and the following
;; disclaimer in the documentation and/or other materials provided
;; with the distribution.
;;
;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
;; CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
;; INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
;; MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
;; DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
;; CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
;; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
;; NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
;; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
;; HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
;; CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
;; OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
;; EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
;;
;; --------------------------------------------------------------------------

View file

@ -1,33 +0,0 @@
## --------------------------------------------------------------------------
##
## Copyright 1996-2010 The NASM Authors - All Rights Reserved
## See the file AUTHORS included with the NASM distribution for
## the specific copyright holders.
##
## Redistribution and use in source and binary forms, with or without
## modification, are permitted provided that the following
## conditions are met:
##
## * Redistributions of source code must retain the above copyright
## notice, this list of conditions and the following disclaimer.
## * Redistributions in binary form must reproduce the above
## copyright notice, this list of conditions and the following
## disclaimer in the documentation and/or other materials provided
## with the distribution.
##
## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
## CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
## INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
## MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
## DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
## NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
## LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
## HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
## EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
##
## --------------------------------------------------------------------------

View file

@ -1,35 +1,5 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 1996-2025 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ----------------------------------------------------------------------- */
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2025 The NASM Authors - All Rights Reserved */
/*
* bytesex.h - byte order helper functions
@ -245,7 +215,7 @@ struct unaligned32 {
} __attribute__((packed));
static inline uint32_t getu32(const void *p)
{
return l32toh(((const struct unaligned32 *)p)->v);
return le32toh(((const struct unaligned32 *)p)->v);
}
static inline uint32_t setu32(void *p, uint32_t v)
{
@ -283,7 +253,7 @@ static inline uint16_t setu16(void *p, uint16_t v)
static inline uint32_t getu32(const void *p)
{
const uint32_t _unaligned *pp = p;
return l32toh(*pp);
return le32toh(*pp);
}
static inline uint32_t setu32(void *p, uint32_t v)
{

View file

@ -1,35 +1,5 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 2007-2025 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ----------------------------------------------------------------------- */
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 2007-2025 The NASM Authors - All Rights Reserved */
/*
* compiler.h
@ -99,6 +69,30 @@
# include <sys/types.h>
#endif
/*
* This is impossible to do 100% accurately, because the actual type
* of size_t may differ from its range.
*/
#ifdef _WIN32
# define PRIz "I" /* Needed for msvcrt, not ucrt */
#elif defined(PRINTF_SUPPORTS_Z) || \
(defined(__STDC_VERSION__) && __STDC_VERSION__ >= 199901L)
# define PRIz "z"
#elif SIZE_MAX == UINT_MAX
# define PRIz ""
#elif SIZE_MAX == ULONG_MAX
# define PRIz "l"
#elif SIZE_MAX == ULONGLONG_MAX
# define PRIz "ll"
#else
# error "Unable to determine printf format for size_t"
#endif
#define PRIzd PRIz "u" /* size_t is always unsigned */
#define PRIzu PRIz "u"
#define PRIzu PRIz "u"
#define PRIzx PRIz "x"
#define PRIzX PRIz "X"
#ifdef HAVE_STDBIT_H
# include <stdbit.h>
@ -183,23 +177,10 @@ int vsnprintf(char *, size_t, const char *, va_list);
size_t strlcpy(char *, const char *, size_t);
#endif
#if !defined(HAVE_STRCHRNUL) || !HAVE_DECL_STRCHRNUL
char * pure_func strrchrnul(const char *, int);
#endif
#if !defined(__cplusplus) || (__STDC_VERSION >= 202311L)
/* C++ and C23 have bool, false, and true as proper keywords */
#if !defined(__cplusplus) && (__STDC_VERSION__ < 202311L)
# ifdef HAVE_STDBOOL_H
/* If <stdbool.h> exists, include it explicitly to prevent it from
begin included later, causing the "bool" macro to be defined. */
# include <stdbool.h>
# ifdef bool
/* Force bool to be a typedef instead of a macro. What a "clever" hack
this is... */
typedef bool /* The macro definition of bool */
# undef bool
bool; /* No longer the macro definition */
# endif
# elif defined(HAVE___BOOL)
typedef _Bool bool;
# define false 0
@ -207,14 +188,10 @@ char * pure_func strrchrnul(const char *, int);
# else
/* This is a bit dangerous, because casting to this ersatz bool
will not produce the same result as the standard (bool) cast.
Instead, use the bool() constructor-style macro defined below. */
Instead, use the explicit construct !!x instead of relying on
implicit conversions or casts. */
typedef enum bool { false, true } bool;
# endif
/* This amounts to a C++-style conversion cast to bool. This works
because C ignores an argument-taking macro when used without an
argument and because bool was redefined as a typedef if it previously
was defined as a macro (see above.) */
# define bool(x) ((bool)!!(x))
#endif
/* Create a NULL pointer of the same type as the address of
@ -326,12 +303,18 @@ static inline void *mempset(void *dst, int c, size_t n)
* Hints to the compiler that a particular branch of code is more or
* less likely to be taken.
*/
#if HAVE___BUILTIN_EXPECT
# define likely(x) __builtin_expect(bool(x), true)
# define unlikely(x) __builtin_expect(bool(x), false)
#ifdef HAVE___BUILTIN_EXPECT
# define likely(x) __builtin_expect(!!(x), true)
# define unlikely(x) __builtin_expect(!!(x), false)
#else
# define likely(x) bool(x)
# define unlikely(x) bool(x)
# define likely(x) (!!(x))
# define unlikely(x) (!!(x))
#endif
#ifdef HAVE___BUILTIN_PREFETCH
# define prefetch(x) __builtin_prefetch(x)
#else
# define prefetch(x) ((void)(x))
#endif
/*
@ -482,4 +465,15 @@ static inline unsigned int watcom_switch_hack(uint64_t x)
# define default case BOGUS_CASE: default
#endif
#ifndef unreachable /* C23 defines as a macro in <stddef.h> */
# ifdef HAVE___BUILTIN_UNREACHABLE
# define unreachable() __builtin_unreachable()
# else
# define unreachable() do { abort(); } while(1)
# endif
#endif
/* This should be set from main() */
extern const char *_progname;
#endif /* NASM_COMPILER_H */

View file

@ -1,35 +1,5 @@
/* ----------------------------------------------------------------------- *
*
* Copyright 2020 The NASM Authors - All Rights Reserved
* See the file AUTHORS included with the NASM distribution for
* the specific copyright holders.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following
* conditions are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following
* disclaimer in the documentation and/or other materials provided
* with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* ----------------------------------------------------------------------- */
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 2020 The NASM Authors - All Rights Reserved */
/*
* dbginfo.h - debugging info structures

Some files were not shown because too many files have changed in this diff Show more