Compare commits

..

No commits in common. "master" and "nasm-3.00rc12" have entirely different histories.

19925 changed files with 18621 additions and 262193 deletions

View file

@ -1,147 +0,0 @@
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,9 +2,6 @@
*.aout
*.aoutb
*.bin
*.bin16
*.bin32
*.bin64
*.coff
*.com
*.dbg
@ -14,7 +11,6 @@
*.ith
*.lib
*.lst
*.log
*.map
*.mo32
*.mo64
@ -82,10 +78,9 @@ 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
@ -98,10 +93,6 @@ TAGS
/test/golden
/test/perf/*.asm
/test/testresults
/test/ffmpegtest
/test/x264test
/travis.mk
/travis.mak
/version.h
/version.mac
/version.mak
@ -125,4 +116,3 @@ 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+ releases.
C: Contributions from 2008-12-15 to 2026-08-15 are Copyright Intel Corporation.
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.
N: John Fine
E: johnfine@earthlink.net

View file

@ -1,9 +1,7 @@
NASM is now licensed under the 2-clause BSD license, also known as the
simplified BSD license.
SPDX-License-Identifier: BSD-2-Clause
Copyright 1996-2025 the NASM Authors - All rights reserved.
Copyright 1996-2010 the NASM Authors - All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following
@ -15,7 +13,7 @@ SPDX-License-Identifier: BSD-2-Clause
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,14 +1,12 @@
# -*- 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@
@ -19,12 +17,6 @@ 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@
@ -38,11 +30,9 @@ INTERNAL_CFLAGS = -I$(srcdir) -I$(objdir) \
-I$(srcdir)/disasm -I$(objdir)/disasm \
-I$(srcdir)/output -I$(objdir)/output \
$(ZLIBINC)
EXTRA_CFLAGS =
ALL_CFLAGS = $(BUILD_CFLAGS) $(INTERNAL_CFLAGS) $(EXTRA_CFLAGS)
ALL_CFLAGS = $(BUILD_CFLAGS) $(INTERNAL_CFLAGS)
LDFLAGS = @LDFLAGS@
EXTRA_LDFLAGS =
ALL_LDFLAGS = $(ALL_CFLAGS) $(LDFLAGS) $(EXTRA_LDFLAGS)
ALL_LDFLAGS = $(ALL_CFLAGS) $(LDFLAGS)
LIBS = @LIBS@
ZLIB = @ZLIB@
@ -59,16 +49,15 @@ PERLFLAGS = -I$(top_srcdir)/perllib -I$(srcdir)
RUNPERL = $(PERL) $(PERLFLAGS)
EMPTY = : >
SIDE = @: Generated by side effect
PYTHON3 = @PYTHON3@
GREP = grep
PYTHON3 = python3
INSTALL = @INSTALL@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_DATA = @INSTALL_DATA@
# Optional tools
NROFF = @NROFF@
ASCIIDOC = @ASCIIDOC@
XMLTO = @XMLTO@
MAKENSIS = @MAKENSIS@
@ -104,12 +93,9 @@ 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 warnings
.PHONY: dist tags TAGS nothing manpages nsis editors travis
.PHONY: install_doc everything install_everything strip perlreq dist tags TAGS
.PHONY: nothing manpages nsis
.c.$(O):
$(CC) -c $(ALL_CFLAGS) -o $@ $<
@ -135,46 +121,7 @@ NDISASM = disasm/ndisasm.$(O)
PROGOBJ = $(NASM) $(NDISASM)
PROGS = nasm$(X) ndisasm$(X)
# 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
# Files dependent on extracted warnings
WARNOBJ = asm/warnings.$(O)
WARNFILES = asm/warnings_c.h include/warnings.h doc/warnings.src
@ -187,8 +134,10 @@ OUTPUTOBJ = \
output/outdbg.$(O) output/outieee.$(O) output/outmacho.$(O) \
output/codeview.$(O)
# Assembler-only library objects
LIBOBJ_ASM = \
# The source files for these objects are scanned for warnings
LIBOBJ_W = \
nasmlib/readnum.$(O) \
\
asm/error.$(O) \
asm/floats.$(O) \
asm/directiv.$(O) \
@ -201,7 +150,16 @@ LIBOBJ_ASM = \
asm/strfunc.$(O) \
asm/segalloc.$(O) \
asm/rdstrnum.$(O) \
asm/srcfile.$(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/directbl.$(O) \
asm/pptok.$(O) \
asm/tokhash.$(O) \
@ -209,62 +167,84 @@ LIBOBJ_ASM = \
\
macros/macros.$(O) \
\
$(WARNOBJ) \
$(OUTPUTOBJ)
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)
# 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)
LIBOBJ = $(LIBOBJ_COM) $(LIBOBJ_ASM) $(LIBOBJ_DIS)
# 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)
ALLOBJ = $(PROGOBJ) $(LIBOBJ)
SUBDIRS = stdlib nasmlib include config output asm disasm x86 \
common zlib macros misc
XSUBDIRS = nsis win test doc editors
XSUBDIRS = test doc nsis win
DEPDIRS = . $(SUBDIRS)
EDITORS = editors/nasmtok.el editors/nasmtok.json
#-- End File Lists --#
all: $(PROGS)
DIRS = dirs
$(DIRS):
@$(MKDIR_P) $(SUBDIRS) $(XSUBDIRS)
all: dirs
$(MAKE) $(PROGS)
NASMLIB = libnasm.$(A)
ASMLIB = libasm.$(A)
DISLIB = libdis.$(A)
DISLIB = libndis.$(A)
$(NASMLIB): $(LIBOBJ_COM)
dirs:
$(MKDIR_P) $(SUBDIRS) $(XSUBDIRS)
$(NASMLIB): $(LIBOBJ)
$(RM_F) $(NASMLIB)
$(AR) cq $(NASMLIB) $(LIBOBJ_COM)
$(AR) cq $(NASMLIB) $(LIBOBJ)
$(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) $(ASMLIB) $(NASMLIB)
$(CC) $(ALL_LDFLAGS) -o $@ $(NASM) $(MANIFEST) \
$(ASMLIB) $(NASMLIB) $(LIBS)
nasm$(X): $(NASM) $(MANIFEST) $(NASMLIB)
$(CC) $(ALL_LDFLAGS) -o nasm$(X) $^ $(LIBS)
ndisasm$(X): $(NDISASM) $(MANIFEST) $(DISLIB) $(NASMLIB)
$(CC) $(ALL_LDFLAGS) -o $@ $(NDISASM) $(MANIFEST) \
$(DISLIB) $(NASMLIB) $(LIBS)
$(CC) $(ALL_LDFLAGS) -o ndisasm$(X) $^ $(LIBS)
# Make sure we have subdirectories set up...
$(ALLOBJ): $(DIRS)
# These are specific to certain Makefile syntaxes...
WARNTIMES = $(WARNFILES:=.time)
WARNSRCS = $(ALLOBJ_W:.$(O)=.c)
#-- Begin Generated File Rules --#
@ -281,36 +261,43 @@ 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
PERLREQ = $(PERLREQ_CLEANABLE)
# Special hack to keep config/unconfig.h from getting deleted
# by "make spotless"...
PERLREQ = config/unconfig.h $(PERLREQ_CLEANABLE)
INSDEP = x86/insns.xda x86/insns.pl x86/insns-iflags.ph x86/iflags.ph x86/insns-cc.ph
INSDEP = x86/insns.xda x86/insns.pl x86/insns-iflags.ph x86/iflags.ph
x86/insns.xda: x86/insns.dat x86/preinsns.pl $(DIRS)
$(RUNPERL) $(srcdir)/x86/preinsns.pl $(srcdir)/x86/insns.dat $@
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/iflag.c: $(INSDEP)
$(RUNPERL) $(srcdir)/x86/insns.pl -fc \
x86/insns.xda x86/iflag.c
$(srcdir)/x86/insns.xda x86/iflag.c
x86/iflaggen.h: $(INSDEP)
$(RUNPERL) $(srcdir)/x86/insns.pl -fh \
x86/insns.xda x86/iflaggen.h
$(srcdir)/x86/insns.xda x86/iflaggen.h
x86/insnsb.c: $(INSDEP)
$(RUNPERL) $(srcdir)/x86/insns.pl -b \
x86/insns.xda x86/insnsb.c
$(srcdir)/x86/insns.xda x86/insnsb.c
x86/insnsa.c: $(INSDEP)
$(RUNPERL) $(srcdir)/x86/insns.pl -a \
x86/insns.xda x86/insnsa.c
$(srcdir)/x86/insns.xda x86/insnsa.c
x86/insnsd.c: $(INSDEP)
$(RUNPERL) $(srcdir)/x86/insns.pl -d \
x86/insns.xda x86/insnsd.c
$(srcdir)/x86/insns.xda x86/insnsd.c
x86/insnsi.h: $(INSDEP)
$(RUNPERL) $(srcdir)/x86/insns.pl -i \
x86/insns.xda x86/insnsi.h
$(srcdir)/x86/insns.xda x86/insnsi.h
x86/insnsn.c: $(INSDEP)
$(RUNPERL) $(srcdir)/x86/insns.pl -n \
x86/insns.xda x86/insnsn.c
$(srcdir)/x86/insns.xda x86/insnsn.c
# These files contains all the standard macros that are derived from
# the version number.
@ -322,7 +309,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 $(DIRS)
nsis/version.nsh: version version.pl
$(RUNPERL) $(srcdir)/version.pl nsis < $(srcdir)/version > nsis/version.nsh
# This source file is generated from the standard macros file
@ -354,6 +341,43 @@ 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 \
@ -391,58 +415,33 @@ 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
# 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)
# Emacs token files
misc/nasmtok.el: misc/emacstbl.pl asm/tokhash.c asm/pptok.c \
asm/directiv.dat version
$(RUNPERL) $< $@ "$(srcdir)" "$(objdir)"
#-- End Generated File Rules --#
perlreq: dirs
$(MAKE) $(PERLREQ)
#-- Begin NSIS Rules --#
nsis/arch.nsh: nsis/getpearch.pl nasm$(X) $(DIRS)
nsis/arch.nsh: nsis/getpearch.pl nasm$(X)
$(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) - \
< $(srcdir)/nsis/nasm.nsi
$(MAKENSIS) -Dsrcdir="$(srcdir)" -Dobjdir="$(objdir)" - < nsis/nasm.nsi
#-- End NSIS Rules --#
# Windows embedded manifest
MANIFEST_RC = win/manifest.rc
win/manifest.$(O): win/manifest.xml $(MANIFEST_RC) $(DIRS)
$(WINDRES) -I. -Iwin -DMANIFEST_FILE='\"$(srcdir)/manifest.xml\"' \
-i $(MANIFEST_RC) -o $@
win/manifest.$(O): win/manifest.xml $(MANIFEST_RC)
$(WINDRES) -I. -Iwin -DMANIFEST_FILE='\"$<\"' -i $(MANIFEST_RC) -o $@
# Generated manpages, also pregenerated for distribution
manpages: nasm.1 ndisasm.1
@ -454,10 +453,6 @@ 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) ; \
@ -470,14 +465,15 @@ clean:
distclean: clean
for d in . $(SUBDIRS) $(XSUBDIRS); do \
$(RM_F) "$$d"/.\#* "$$d"/\#* "$$d"/*~ "$$d"/*.bak \
"$$d"/*.lst "$$d"/*.bin "$$d"/*.dep ; \
$(RM_F) "$$d"/.\# "$$d"/\# "$$d"/*~ "$$d"/*.bak \
"$$d"/*.lst "$$d"/*.bin ; \
done
$(RM_F) test/*.$(O)
-$(SHELL) autoconf/clean.sh || $(SHELL) $(srcdir)/autoconf/clean.sh
$(RM_F) *.dep
-$(SHELL) autoconf/clean.sh || $(SHELL) '$(srcdir)'/autoconf/clean.sh
cleaner:
$(RM_F) $(PERLREQ_CL) $(EDITORS) *.1 nasm.spec
$(RM_F) $(PERLREQ_CL) *.1 nasm.spec
$(MAKE) -C doc clean
$(MAKE) -C misc clean
$(MAKE) distclean
@ -508,9 +504,7 @@ 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:
@ -519,24 +513,19 @@ 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_editors
editor_builtin: nasm$(X)
$(SHELL) editors/dumpbuiltin.sh ./nasm$(X) > editors/builtin.mac
install_everything: everything install install_doc
dist:
$(MAKE) alldeps
$(MAKE) perlreq spec
$(MAKE) editor_builtin
$(MAKE) editors $(MANPAGES)
$(MAKE) perlreq warnings spec $(MANPAGES)
$(MAKE) distclean
$(SHELL) autogen.sh --clearenv
./autogen.sh
tar: dist
tar -cv --exclude CVS --exclude .git -C .. -f - `basename \`pwd\`` | \
@ -551,7 +540,7 @@ perlbreq.si: $(ALLPERLSRC)
sed -r -e '/perl\((Win32.*)\)/d' | \
sort | uniq > perlbreq.si
doc/perlbreq.src: perlbreq.si $(DIRS)
doc/perlbreq.src: perlbreq.si
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
@ -563,17 +552,14 @@ nasm.spec: nasm.spec.in nasm.spec.sed version.sed perlbreq.si
splint:
splint -weak *.c
#
# Travis tests
#
travis test: $(PROGS)
$(MAKE) -f travis.mak all
test: $(PROGS)
cd test && $(RUNPERL) performtest.pl --nasm=../nasm *.asm
clean-travis travis-clean:
$(MAKE) -f travis.mak clean
golden: $(PROGS)
cd test && $(RUNPERL) performtest.pl --golden --nasm=../nasm *.asm
update-travis travis-update golden:
$(MAKE) -f travis.mak update
travis: $(PROGS)
$(PYTHON3) travis/nasm-t.py run
#
# Rules to run autogen if necessary
@ -595,12 +581,13 @@ doc/Makefile: Makefile
config/config.h: config.status
#
# Dummy rules that changes make behavior
# (at end to avoid confusing non-GNU makes)
#
.SECONDARY:
#
# Synchronize auxiliary Makefiles
#
syncfiles: $(tools)/syncfiles.pl
$(RUNPERL) $(tools)/syncfiles.pl Makefile.in Mkfiles/*.mak
.DELETE_ON_ERROR:
#
# Does this version of this file have external dependencies? This definition
@ -615,17 +602,19 @@ 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: syncfiles $(PERLREQ) $(tools)/mkdep.pl
alldeps: $(PERLREQ) $(tools)/syncfiles.pl $(tools)/mkdep.pl
$(RUNPERL) $(tools)/syncfiles.pl Makefile.in Mkfiles/*.mak
$(RUNPERL) $(tools)/mkdep.pl -i -M Makefile.in Mkfiles/*.mak -- \
$(DEPDIRS)
$(RM_F) *.dep
@ -635,7 +624,8 @@ alldeps: syncfiles $(PERLREQ) $(tools)/mkdep.pl
# Strip internal dependency information from all Makefiles; this makes
# the output good for git checkin
cleandeps: syncfiles $(PERLREQ) $(tools)/mkdep.pl
cleandeps: $(PERLREQ) $(tools)/syncfiles.pl $(tools)/mkdep.pl
$(RUNPERL) $(tools)/syncfiles.pl Makefile.in Mkfiles/*.mak
$(RUNPERL) $(tools)/mkdep.pl -e -M Makefile.in Mkfiles/*.mak -- \
$(DEPDIRS)
$(RM_F) *.dep
@ -643,14 +633,6 @@ cleandeps: syncfiles $(PERLREQ) $(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,8 +10,6 @@ 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:
@ -21,8 +19,8 @@ The Makefiles are:
http://nsis.sourceforge.net/Download
3. Ghostscript (ps2pdf) or Acrobat Distriller (acrodist)
https://downloads.ghostscript.com/
4. The Google Roboto and Roboto Mono fonts
https://github.com/googlefonts/
4. The Adobe Source Sans Pro and Source Code Pro fonts
https://github.com/adobe-fonts
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.
# Last tested on Visual Studio 2022 Community Edition.
# 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.
#
# Make sure to have the proper directories in your path.
# This is typically done by opening the Visual Studio Command Prompt.
#
@ -18,49 +18,39 @@ exec_prefix = $(prefix)
bindir = $(prefix)/bin
mandir = $(prefix)/man
MANIFEST_FLAGS = /manifest:embed /manifestfile:$(MANIFEST)
MANIFEST_FLAGS = /MANIFEST:EMBED /MANIFESTFILE:$(MANIFEST)
!IF "$(DEBUG)" == "1"
OPTFLAGS = /Od
LDFLAGS = /debug
CFLAGS = /Od /Zi
LDFLAGS = /DEBUG
!ELSE
OPTFLAGS = /O2
CFLAGS = /O2 /Zi
# /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)/zlib
/I$(srcdir)/output /I./output
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 /s /f /q
LN_S = copy /y
EMPTY = copy /y nul:
SIDE = @rem Created by side effect
RM_F = -del /f
LN_S = copy
# Binary suffixes
O = obj
@ -70,12 +60,10 @@ 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 --#
@ -86,46 +74,7 @@ NDISASM = disasm\ndisasm.obj
PROGOBJ = $(NASM) $(NDISASM)
PROGS = nasm$(X) ndisasm$(X)
# 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
# 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
# Files dependent on extracted warnings
WARNOBJ = asm\warnings.obj
WARNFILES = asm\warnings_c.h include\warnings.h doc\warnings.src
@ -138,8 +87,10 @@ OUTPUTOBJ = \
output\outdbg.obj output\outieee.obj output\outmacho.obj \
output\codeview.obj
# Assembler-only library objects
LIBOBJ_ASM = \
# The source files for these objects are scanned for warnings
LIBOBJ_W = \
nasmlib\readnum.obj \
\
asm\error.obj \
asm\floats.obj \
asm\directiv.obj \
@ -148,11 +99,19 @@ LIBOBJ_ASM = \
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\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 \
@ -160,52 +119,76 @@ LIBOBJ_ASM = \
\
macros\macros.obj \
\
$(WARNOBJ) \
$(OUTPUTOBJ)
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 \
disasm\diserror.obj \
\
x86\insnsd.obj x86\regdis.obj
LIBOBJ = $(LIBOBJ_COM) $(LIBOBJ_ASM) $(LIBOBJ_DIS)
# 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
LIBOBJ = $(LIBOBJ_W) $(LIBOBJ_NW) $(ZLIB)
ALLOBJ_W = $(NASM) $(LIBOBJ_W)
ALLOBJ = $(PROGOBJ) $(LIBOBJ)
SUBDIRS = stdlib nasmlib include config output asm disasm x86 \
common zlib macros misc
XSUBDIRS = nsis win test doc editors
common zlib macros
XSUBDIRS = test doc nsis win
DEPDIRS = . $(SUBDIRS)
EDITORS = editors\nasmtok.el editors\nasmtok.json
#-- End File Lists --#
NASMLIB = libnasm.$(A)
ASMLIB = libasm.$(A)
DISLIB = libdis.$(A)
NDISLIB = libndis.$(A)
all: nasm$(X) ndisasm$(X)
nasm$(X): $(NASM) $(MANIFEST) $(ASMLIB) $(NASMLIB)
$(CC) /Fe:$@ $(ALL_CFLAGS) $(NASM) $(ASMLIB) $(NASMLIB) $(LIBS) \
$(ALL_LDFLAGS)
nasm$(X): $(NASM) $(MANIFEST) $(NASMLIB)
$(CC) /Fe$@ $(NASM) $(ALL_LDFLAGS) $(NASMLIB) $(LIBS)
ndisasm$(X): $(NDISASM) $(MANIFEST) $(DISLIB) $(NASMLIB)
$(CC) /Fe:$@ $(ALL_CFLAGS) $(NDISASM) $(DISLIB) $(NASMLIB) $(LIBS) \
$(ALL_LDFLAGS)
ndisasm$(X): $(NDISASM) $(MANIFEST) $(NDISLIB) $(NASMLIB)
$(CC) /Fe$@ $(NDISASM) $(ALL_LDFLAGS) $(NDISLIB) $(NASMLIB) $(LIBS)
$(NASMLIB): $(LIBOBJ_COM)
$(AR) $(ARFLAGS) /out:$@ $**
$(NASMLIB): $(LIBOBJ)
$(AR) $(ARFLAGS) /OUT:$@ $**
$(ASMLIB): $(LIBOBJ_ASM)
$(AR) $(ARFLAGS) /out:$@ $**
$(DISLIB): $(LIBOBJ_DIS)
$(AR) $(ARFLAGS) /out:$@ $**
$(NDISLIB): $(LIBOBJ_DIS)
$(AR) $(ARFLAGS) /OUT:$@ $**
# These are specific to certain Makefile syntaxes...
WARNSRCS = $(LIBOBJ_NW:.c=.obj)
WARNTIMES = $(patsubst %,%.time,$(WARNFILES))
WARNSRCS = $(patsubst %.obj,%.c,$(LIBOBJ_NW))
#-- Begin Generated File Rules --#
# Edit in Makefile.in, not here!
@ -223,36 +206,43 @@ 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
PERLREQ = $(PERLREQ_CLEANABLE)
# Special hack to keep config\unconfig.h from getting deleted
# by "make spotless"...
PERLREQ = config\unconfig.h $(PERLREQ_CLEANABLE)
INSDEP = x86\insns.xda x86\insns.pl x86\insns-iflags.ph x86\iflags.ph x86\insns-cc.ph
INSDEP = x86\insns.xda x86\insns.pl x86\insns-iflags.ph x86\iflags.ph
x86\insns.xda: x86\insns.dat x86\preinsns.pl $(DIRS)
$(RUNPERL) $(srcdir)\x86\preinsns.pl $(srcdir)\x86\insns.dat $@
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\iflag.c: $(INSDEP)
$(RUNPERL) $(srcdir)\x86\insns.pl -fc \
x86\insns.xda x86\iflag.c
$(srcdir)\x86\insns.xda x86\iflag.c
x86\iflaggen.h: $(INSDEP)
$(RUNPERL) $(srcdir)\x86\insns.pl -fh \
x86\insns.xda x86\iflaggen.h
$(srcdir)\x86\insns.xda x86\iflaggen.h
x86\insnsb.c: $(INSDEP)
$(RUNPERL) $(srcdir)\x86\insns.pl -b \
x86\insns.xda x86\insnsb.c
$(srcdir)\x86\insns.xda x86\insnsb.c
x86\insnsa.c: $(INSDEP)
$(RUNPERL) $(srcdir)\x86\insns.pl -a \
x86\insns.xda x86\insnsa.c
$(srcdir)\x86\insns.xda x86\insnsa.c
x86\insnsd.c: $(INSDEP)
$(RUNPERL) $(srcdir)\x86\insns.pl -d \
x86\insns.xda x86\insnsd.c
$(srcdir)\x86\insns.xda x86\insnsd.c
x86\insnsi.h: $(INSDEP)
$(RUNPERL) $(srcdir)\x86\insns.pl -i \
x86\insns.xda x86\insnsi.h
$(srcdir)\x86\insns.xda x86\insnsi.h
x86\insnsn.c: $(INSDEP)
$(RUNPERL) $(srcdir)\x86\insns.pl -n \
x86\insns.xda x86\insnsn.c
$(srcdir)\x86\insns.xda x86\insnsn.c
# These files contains all the standard macros that are derived from
# the version number.
@ -264,7 +254,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 $(DIRS)
nsis\version.nsh: version version.pl
$(RUNPERL) $(srcdir)\version.pl nsis < $(srcdir)\version > nsis\version.nsh
# This source file is generated from the standard macros file
@ -296,6 +286,43 @@ 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 \
@ -321,9 +348,6 @@ 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
@ -333,39 +357,10 @@ 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
# 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)
# Emacs token files
misc\nasmtok.el: misc\emacstbl.pl asm\tokhash.c asm\pptok.c \
asm\directiv.dat version
$(RUNPERL) $< $@ "$(srcdir)" "$(objdir)"
#-- End Generated File Rules --#
@ -374,15 +369,14 @@ perlreq: $(PERLREQ)
#-- Begin NSIS Rules --#
# Edit in Makefile.in, not here!
nsis\arch.nsh: nsis\getpearch.pl nasm$(X) $(DIRS)
nsis\arch.nsh: nsis\getpearch.pl nasm$(X)
$(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) - \
< $(srcdir)\nsis\nasm.nsi
$(MAKENSIS) -Dsrcdir="$(srcdir)" -Dobjdir="$(objdir)" - < nsis\nasm.nsi
#-- End NSIS Rules --#
@ -421,31 +415,14 @@ 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.
#
# 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=.. \
# Abuse doc/Makefile.in to build nasmdoc.pdf only
docs:
cd doc && $(MAKE) /f Makefile.in srcdir=. top_srcdir=.. \
PERL=$(PERL) PDFOPT= nasmdoc.pdf
everything: all docs nsis

View file

@ -6,235 +6,202 @@
top_srcdir = .
srcdir = .
VPATH = $(srcdir)/asm;$(srcdir)/x86;$(srcdir)/macros;$(srcdir)/output;
VPATH +=$(srcdir)/common;$(srcdir)/stdlib;$(srcdir)/nasmlib;
VPATH +=$(srcdir)/disasm;$(srcdir)/zlib;asm;x86;macros
VPATH = $(srcdir)\asm;$(srcdir)\x86;asm;x86;$(srcdir)\macros;macros;$(srcdir)\output;$(srcdir)\lib;$(srcdir)\common;$(srcdir)\stdlib;$(srcdir)\nasmlib;$(srcdir)\disasm
prefix = C:\Program Files\NASM
exec_prefix = $(prefix)
bindir = $(prefix)/bin
mandir = $(prefix)/man
bindir = $(prefix)\bin
mandir = $(prefix)\man
CC = *wcc386
CC = *wcl386
DEBUG =
CFLAGS = -zq -6 -ox -wx -wcd=124 -ze -fpi $(DEBUG)
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"
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
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)
!ifdef __LOADDLL__
!loaddll wcc wccd.dll
!loaddll wcc386 wccd386.dll
!loaddll wlib wlibd.dll
!loaddll wlink wlinkd.dll
!endif
EMPTY = $(RUNPERL) -e ""
.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
MAKENSIS = makensis
# Binary suffixes
O = obj
A = lib
X = .exe
O = obj
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 .lib .exe
.SUFFIXES: .man .1 .obj .i .c
# Needed to find C files anywhere but in the current directory
.c : $(VPATH)
.c.obj: .AUTODEPEND
$(CC) $(ALL_CFLAGS) -fo=$^@ $[@
.c.obj:
@set INCLUDE=
$(CC) -c $(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)
# 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
# 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
# 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
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 &
# The source files for these objects are scanned for warnings
LIBOBJ_W = &
nasmlib\readnum.obj &
&
macros/macros.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 &
&
$(WARNOBJ) &
$(OUTPUTOBJ)
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 &
disasm/diserror.obj &
disasm\disasm.obj disasm\sync.obj disasm\prefix.obj &
&
x86/insnsd.obj x86/regdis.obj
x86\insnsd.obj x86\regdis.obj
LIBOBJ = $(LIBOBJ_COM) $(LIBOBJ_ASM) $(LIBOBJ_DIS)
# 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
LIBOBJ = $(LIBOBJ_W) $(LIBOBJ_NW) $(ZLIB)
ALLOBJ_W = $(NASM) $(LIBOBJ_W)
ALLOBJ = $(PROGOBJ) $(LIBOBJ)
SUBDIRS = stdlib nasmlib include config output asm disasm x86 &
common zlib macros misc
XSUBDIRS = nsis win test doc editors
common zlib macros
XSUBDIRS = test doc nsis win
DEPDIRS = . $(SUBDIRS)
EDITORS = editors/nasmtok.el editors/nasmtok.json
#-- End File Lists --#
what: $(PHONY)
what: .SYMBOLIC
@echo Please build "dos", "win32", "os2" or "linux386"
dos: $(PHONY)
@set TARGET_CFLAGS=-bt=DOS -I"$(%WATCOM)/h"
dos: .SYMBOLIC
@set TARGET_CFLAGS=-bt=DOS -I"$(%WATCOM)\h"
@set TARGET_LFLAGS=sys causeway
@%make all
win32: $(PHONY)
@set TARGET_CFLAGS=-bt=NT -I"$(%WATCOM)/h" -I"$(%WATCOM)/h/nt"
win32: .SYMBOLIC
@set TARGET_CFLAGS=-bt=NT -I"$(%WATCOM)\h" -I"$(%WATCOM)\h\nt"
@set TARGET_LFLAGS=sys nt
@%make all
os2: $(PHONY)
@set TARGET_CFLAGS=-bt=OS2 -I"$(%WATCOM)/h" -I"$(%WATCOM)/h/os2"
os2: .SYMBOLIC
@set TARGET_CFLAGS=-bt=OS2 -I"$(%WATCOM)\h" -I"$(%WATCOM)\h\os2"
@set TARGET_LFLAGS=sys os2v2
@%make all
linux386: $(PHONY)
@set TARGET_CFLAGS=-bt=LINUX -I"$(%WATCOM)/lh"
linux386: .SYMBOLIC
@set TARGET_CFLAGS=-bt=LINUX -I"$(%WATCOM)\lh"
@set TARGET_LFLAGS=sys linux
@%make all
all: perlreq nasm$(X) ndisasm$(X) $(PHONY)
all: perlreq nasm$(X) ndisasm$(X) .SYMBOLIC
# cd rdoff && $(MAKE) all
NASMLIB = nasm.lib
ASMLIB = asm.lib
DISLIB = dis.lib
NDISLIB = ndisasm.lib
nasm$(X): $(NASM) $(ASMLIB) $(NASMLIB)
$(LD) $(LDFLAGS) name nasm$(X) libr {$(ASMLIB) $(NASMLIB) $(LIBS)} file {$(NASM)}
nasm$(X): $(NASM) $(NASMLIB)
$(LD) $(LDFLAGS) name nasm$(X) libr {$(NASMLIB) $(LIBS)} file {$(NASM)}
ndisasm$(X): $(NDISASM) $(DISLIB) $(NASMLIB)
$(LD) $(LDFLAGS) name ndisasm$(X) libr {$(DISLIB) $(NASMLIB) $(LIBS)} file {$(NDISASM)}
ndisasm$(X): $(NDISASM) $(NDISLIB) $(NASMLIB)
$(LD) $(LDFLAGS) name ndisasm$(X) libr {$(NDISLIB) $(NASMLIB) $(LIBS)} file {$(NDISASM)}
<<<<<<< HEAD
nasm.lib: $(LIBOBJ_COM)
wlib -q -b -n $@ $(LIBOBJ_COM)
nasm.lib: $(LIBOBJ)
wlib -q -b -n $@ $(LIBOBJ)
asm.lib: $(LIBOBJ_ASM)
wlib -q -b -n $@ $(LIBOBJ_ASM)
dis.lib: $(LIBOBJ_DIS)
ndisasm.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!
@ -245,206 +212,221 @@ ndisasm.lib: $(LIBOBJ_DIS)
# 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) &
version.h version.mac version.mak nsis/version.nsh
misc\nasmtok.el &
version.h version.mac version.mak nsis\version.nsh
PERLREQ = $(PERLREQ_CLEANABLE)
# Special hack to keep config\unconfig.h from getting deleted
# by "make spotless"...
PERLREQ = config\unconfig.h $(PERLREQ_CLEANABLE)
INSDEP = x86/insns.xda x86/insns.pl x86/insns-iflags.ph x86/iflags.ph x86/insns-cc.ph
INSDEP = x86\insns.xda x86\insns.pl x86\insns-iflags.ph x86\iflags.ph
x86/insns.xda: x86/insns.dat x86/preinsns.pl $(DIRS)
$(RUNPERL) $(srcdir)/x86/preinsns.pl $(srcdir)/x86/insns.dat $@
x86\insns.xda: x86\insns.dat x86\preinsns.pl
$(RUNPERL) '$(srcdir)'\x86\preinsns.pl $< $@
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
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
# 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 $(DIRS)
$(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
$(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
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
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
# 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
# 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)
# Emacs token files
misc\nasmtok.el: misc\emacstbl.pl asm\tokhash.c asm\pptok.c &
asm\directiv.dat version
$(RUNPERL) $< $@ "$(srcdir)" "$(objdir)"
#-- End Generated File Rules --#
perlreq: $(PERLREQ) .SYMBOLIC
#-- Begin NSIS Rules --#
# Edit in Makefile.in, not here!
nsis/arch.nsh: nsis/getpearch.pl nasm$(X) $(DIRS)
$(PERL) $(srcdir)/nsis/getpearch.pl nasm$(X) > nsis/arch.nsh
nsis\arch.nsh: nsis\getpearch.pl nasm$(X)
$(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) - &
< $(srcdir)/nsis/nasm.nsi
nsis: nsis\nasm.nsi nsis\arch.nsh nsis\version.nsh
$(MAKENSIS) -Dsrcdir="$(srcdir)" -Dobjdir="$(objdir)" - < nsis\nasm.nsi
#-- End NSIS Rules --#
clean: $(PHONY)
clean: .SYMBOLIC
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 zlib/*.obj zlib/*.s zlib/*.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 config.h config.log config.status
rm -f nasm$(X) ndisasm$(X) $(NASMLIB) $(NDISLIB)
distclean: clean $(PHONY)
distclean: clean .SYMBOLIC
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 $(PHONY)
cleaner: clean .SYMBOLIC
rm -f $(PERLREQ)
rm -f *.man
rm -f nasm.spec
# cd doc && $(MAKE) clean
spotless: distclean cleaner $(PHONY)
rm -f doc/Makefile doc/*~ doc/*.bak
spotless: distclean cleaner .SYMBOLIC
rm -f doc\Makefile doc\*~ doc\*.bak
strip: $(PHONY)
strip: .SYMBOLIC
$(STRIP) *.exe
doc:
# cd doc && $(MAKE) all
# cd doc && $(MAKE) all
everything: all doc
@ -452,13 +434,13 @@ everything: all doc
# This build dependencies in *ALL* makefiles. Partially for that reason,
# it's expected to be invoked manually.
#
alldeps: perlreq $(PHONY)
$(PERL) syncfiles.pl Makefile.in Mkfiles/openwcom.mak
$(PERL) mkdep.pl -M Makefile.in Mkfiles/openwcom.mak -- . output lib
alldeps: perlreq .SYMBOLIC
$(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 https://github.com/netwide-assembler/nasm.git
The NASM sources are tracked by Git SCM at http://repo.or.cz/w/nasm.git
repository. You either could download packed sources or use git tool itself
git clone https://github.com/netwide-assembler/nasm.git
git clone git://repo.or.cz/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,10 +86,8 @@ An example of patch message
From: Random J Developer <random@developer.example.org>
Subject: [PATCH] Short patch description
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.
Long patch description (could be skipped if patch
is trivial enough)
Signed-off-by: Random J Developer <random@developer.example.org>
---

View file

@ -1,5 +1,35 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 2025 The NASM Authors - All Rights Reserved */
/* ----------------------------------------------------------------------- *
*
* 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.
*
* ----------------------------------------------------------------------- */
#ifndef NASM_ASMUTIL_H
#define NASM_ASMUTIL_H

View file

@ -1,5 +1,35 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2025 The NASM Authors - All Rights Reserved */
/* ----------------------------------------------------------------------- *
*
* 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.
*
* ----------------------------------------------------------------------- */
/*
* assemble.c code generation for the Netwide Assembler
@ -30,9 +60,9 @@ enum match_result {
MERR_OPSIZEINVAL,
MERR_OPSIZEMISSING,
MERR_OPSIZEMISMATCH,
MERR_MASKNOTHERE,
MERR_BRNOTHERE,
MERR_BRNUMMISMATCH,
MERR_MASKNOTHERE,
MERR_DECONOTHERE,
MERR_BADZU,
MERR_MEMZU,
@ -75,11 +105,11 @@ enum match_result {
static int64_t assemble(insn *instruction);
static int64_t insn_size(insn *instruction);
static int64_t calcsize(insn *);
static int64_t calcsize_speculative(const insn *, const struct itemplate *);
static int64_t calcsize(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(insn *instruction);
static enum match_result find_match(const struct itemplate **tempp,
insn *instruction);
static enum match_result matches(const struct itemplate *, const insn *);
static opflags_t regflag(const operand *);
static int32_t regval(const operand *);
@ -249,6 +279,17 @@ 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.
@ -389,6 +430,78 @@ 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;
@ -455,6 +568,11 @@ 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),
@ -634,85 +752,8 @@ 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 insn *ins, const struct itemplate *temp)
static enum match_result jmp_match(const struct itemplate *temp, const insn *ins)
{
const struct operand * const op0 = get_operand_const(ins, 0);
int64_t delta;
@ -753,18 +794,34 @@ jmp_match(const insn *ins, const struct itemplate *temp)
* instruction size.
*
* Note that the instruction size is to be *subtracted* from the
* initial (beginning-of-instruction) delta value, or *added* to the
* limiting value compared to.
* initial (beginning-of-instruction) delta value.
*/
delta = op0->offset - ins->loc.offset;
if (delta < -128 + 2 || delta > 127 + 15) {
if (delta - 2 < -128 || delta - 15 > 127) {
/* This cannot be a byte-sized jump */
return MERR_INVALOP;
} else if (delta >= -128 + 15 && delta <= 127 + 2) {
} else if (delta - 15 >= -128 && delta - 2 <= 127) {
/* It is guaranteed to be a valid byte-sized jump, no need to test */
} else {
/* Borderline: need to do this the hard way... */
int64_t isize = calcsize_speculative(ins, temp);
/*
* 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;
if (isize < 0)
return MERR_INVALOP;
delta -= isize;
@ -871,24 +928,13 @@ 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;
@ -903,7 +949,6 @@ 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;
@ -942,6 +987,7 @@ static int64_t assemble(insn *instruction)
}
lfmt->set_offset(data.loc.offset);
lfmt->uplevel(LIST_INCBIN, len);
if (!len)
goto end_incbin;
@ -953,7 +999,6 @@ 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
@ -966,8 +1011,6 @@ 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) {
@ -978,39 +1021,31 @@ 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);
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;
}
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;
}
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;
}
}
if (need_downlevel_times)
lfmt->downlevel(LIST_TIMES);
end_incbin:
lfmt->downlevel(LIST_INCBIN);
if (instruction->times > 1) {
lfmt->uplevel(LIST_TIMES, instruction->times);
lfmt->downlevel(LIST_TIMES);
}
if (ferror(fp)) {
nasm_nonfatal("`incbin': error while"
" reading file `%s'", fname);
@ -1030,15 +1065,10 @@ static int64_t assemble(insn *instruction)
/* Pre-match instruction structure update */
insn_early_setup(instruction);
m = find_match(instruction);
m = find_match(&temp, 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;
@ -1050,9 +1080,27 @@ static int64_t assemble(insn *instruction)
* warning classes for "obsolete but valid for this
* specific CPU" and "obsolete and gone."
*
* This currently doesn't really happen correctly;
* it requires better information in insns.dat.
*!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.
*/
whathappened = never ? "never implemented" : "obsolete";
if (!never && !iflag_cmp_cpu_level(&insns_flags[temp->iflag_idx], &cpu)) {
@ -1070,12 +1118,8 @@ static int64_t assemble(insn *instruction)
whathappened, validity);
}
data.inslen = calcsize(instruction);
/* This can happen if the instruction generated an error */
if (data.inslen <= 0)
return 0;
data.inslen = calcsize(instruction, temp);
nasm_assert(data.inslen >= 0);
data.inslen = merge_resb(instruction, data.inslen);
data.insoffs = 0;
@ -1087,7 +1131,75 @@ static int64_t assemble(insn *instruction)
nasm_assert(data.loc.offset - start == data.inslen);
} else {
no_match_error(m, instruction);
/* 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;
}
instruction->times = 1; /* Avoid repeated error messages */
}
}
@ -1256,6 +1368,7 @@ 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;
@ -1303,13 +1416,11 @@ static int64_t insn_size(insn *instruction)
/* Pre-matching setup */
insn_early_setup(instruction);
m = find_match(instruction);
if (m < MOK_GOOD) {
no_match_error(m, instruction);
m = find_match(&temp, instruction);
if (m < MOK_GOOD)
return -1; /* No match */
}
isize = calcsize(instruction);
isize = calcsize(instruction, temp);
debug_set_type(instruction);
isize = merge_resb(instruction, isize);
@ -1336,6 +1447,12 @@ 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;
@ -1392,49 +1509,12 @@ 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
/*
* 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)
static int64_t calcsize(insn *ins, const struct itemplate * const temp)
{
const struct itemplate * const temp = ins->itemp;
const int bits = ins->bits;
const uint8_t *codes = temp->code;
int64_t length = 0;
@ -1454,9 +1534,11 @@ static int64_t calcsize(insn *ins)
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 (prefixes are handled in the byte code) */
/* Default operand size */
ins->op_size = bits != 16 ? 32 : 16;
nasm_zero(need_pfx);
@ -1501,7 +1583,7 @@ static int64_t calcsize(insn *ins)
if (opx->type & (BITS16 | BITS32 | BITS64))
length += (opx->type & BITS16) ? 2 : 4;
else
length += (ins->op_size == 16) ? 2 : 4;
length += (bits == 16) ? 2 : 4;
break;
case4(040):
@ -1528,7 +1610,7 @@ static int64_t calcsize(insn *ins)
if (opx->type & (BITS16 | BITS32 | BITS64))
length += (opx->type & BITS16) ? 2 : 4;
else
length += (ins->op_size == 16) ? 2 : 4;
length += (bits == 16) ? 2 : 4;
break;
case4(070):
@ -1671,6 +1753,11 @@ static int64_t calcsize(insn *ins)
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) {
@ -1804,6 +1891,17 @@ static int64_t calcsize(insn *ins)
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"
@ -1892,6 +1990,16 @@ static int64_t calcsize(insn *ins)
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");
@ -2118,8 +2226,21 @@ static int64_t calcsize(insn *ins)
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");
}
@ -2141,6 +2262,17 @@ static int64_t calcsize(insn *ins)
*/
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;
@ -2326,6 +2458,13 @@ 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",
@ -2344,6 +2483,12 @@ 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",
@ -2467,7 +2612,7 @@ static void gencode(struct out_data *data, insn *ins)
if (opx->type & (BITS16 | BITS32))
size = (opx->type & BITS16) ? 2 : 4;
else
size = (ins->op_size == 16) ? 2 : 4;
size = (bits == 16) ? 2 : 4;
out_imm(data, opx, size, OUT_WRAP);
break;
@ -2503,7 +2648,7 @@ static void gencode(struct out_data *data, insn *ins)
if (opx->type & (BITS16 | BITS32 | BITS64))
size = (opx->type & BITS16) ? 2 : 4;
else
size = (ins->op_size == 16) ? 2 : 4;
size = (bits == 16) ? 2 : 4;
out_reladdr(data, opx, size);
break;
@ -2929,18 +3074,17 @@ static uint32_t op_evexflags(const operand * o, uint32_t mask)
return evexflags(o->decoflags, mask);
}
static enum match_result find_match(insn *instruction)
static enum match_result find_match(const struct itemplate **tempp,
insn *instruction)
{
const int bits = instruction->bits;
const struct itemplate_list *templist;
const struct itemplate *temp;
const struct itemplate *best;
const struct itemplate *best = NULL;
enum match_result m, merr;
int this_good;
int rex = instruction->prefixes[PPS_REX];
int n, i, besti;
instruction->itemp = best = NULL;
instruction->itempindex = besti = -1;
unsigned int n;
/* Impossible encoding request? */
if (bits != 64) {
@ -2949,29 +3093,31 @@ static enum match_result find_match(insn *instruction)
}
merr = MERR_INVALOP;
best = NULL;
this_good = 0;
templist = &nasm_instructions[instruction->opcode];
n = templist->ntemp;
temp = templist->temp;
for (i = 0; i < n; i++) {
while (n--) {
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) {
/* If this was a fuzzy match it is confirmed now */
merr = MOK_GOOD;
instruction->itemp = best;
instruction->itempindex = besti;
}
if (merr >= MOK_FIRST)
merr = MOK_GOOD; /* Fuzzy match but valid */
*tempp = best;
return merr;
}
@ -3097,7 +3243,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 (bits == 64 && itemp_has(itemp, IF_NWSIZE) && op_size == 32) {
if (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;
}
@ -3137,23 +3283,18 @@ 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; this is specially coded */
/* Only a short form exists; allow both NEAR and SHORT */
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;
}
}
@ -3162,18 +3303,20 @@ 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.
*/
if (isize[i] == BITS8) {
switch (isize[i]) {
case BITS8:
if (ttype & BYTEEXTMASK) {
isize[i] = tsize[i];
itype[i] |= BYTEEXTMASK;
}
} else if (isize[i] == BITS32) {
break;
case BITS32:
if (ttype & DWORDEXTMASK)
isize[i] = tsize[i];
break;
default:
break;
}
/*
@ -3396,7 +3539,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(ins, itemp);
return jmp_match(itemp, ins);
return MOK_GOOD;
}
@ -3507,7 +3650,14 @@ static int process_ea(operand *input, int rfield, opflags_t rflags,
input->type |= IP_REL;
}
if ((input->type & IP_REL) == IP_REL) {
if (!pass_first() && absolute_op(input)) {
/*!
*!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)) {
nasm_warn(WARN_EA_ABSOLUTE,
"absolute address can not be RIP-relative");
input->type &= ~IP_REL;
@ -3524,6 +3674,12 @@ 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,5 +1,35 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2025 The NASM Authors - All Rights Reserved */
/* ----------------------------------------------------------------------- *
*
* 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.
*
* ----------------------------------------------------------------------- */
/*
* assemble.h - header file for stuff private to the assembler

View file

@ -1,5 +1,35 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2025 The NASM Authors - All Rights Reserved */
/* ----------------------------------------------------------------------- *
*
* 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.
*
* ----------------------------------------------------------------------- */
/*
* Parse and handle assembler directives
@ -22,7 +52,6 @@
#include "listing.h"
#include "labels.h"
#include "iflag.h"
#include "quote.h"
struct cpunames {
const char *name;
@ -179,51 +208,34 @@ static int get_bits(const char *value)
static enum directive parse_directive_line(char **directive, char **value)
{
char *p, *q, *eol, *buf;
char c;
char *p, *q, *buf;
buf = nasm_skip_spaces(*directive);
/*
* It should be enclosed in [ ].
*
* 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.
* XXX: we don't check there is nothing else on the remainder of the
* line, except a possible comment.
*/
if (*buf != '[')
return D_none;
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;
}
}
q = strchr(buf, ']');
if (!q)
return D_corrupt;
/*
* 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.
* 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.
*/
eol = nasm_skip_spaces(q+1);
if (*eol != '\0' && *eol != ';') {
nasm_warn(WARN_DIRECTIVE_GARBAGE_EOL,
"garbage found on line after directive");
p = strchr(buf, ';');
if (p) {
if (p < q) /* ouch! somewhere inside */
return D_corrupt;
*p = '\0';
}
/* no brace, no trailing spaces */
@ -282,7 +294,7 @@ bool process_directives(char *directive)
switch (d) {
case D_none:
return false;
return D_none; /* Not a directive */
case D_corrupt:
nasm_nonfatal("invalid directive line");
@ -303,12 +315,6 @@ 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;
@ -388,7 +394,6 @@ bool process_directives(char *directive)
{
bool validid;
int64_t size = 0;
char *fullvalue = value; /* Including leading $ if present */
char *sizestr;
bool rn_error;
@ -396,7 +401,7 @@ bool process_directives(char *directive)
value++; /* skip escaping $ if present */
validid = nasm_isidchar(*value);
if (globl.dollarhex)
validid &= !nasm_isnumstart(*value);
validid &= !nasm_isnumchar(*value);
} else {
validid = nasm_isidstart(*value);
}
@ -412,7 +417,7 @@ bool process_directives(char *directive)
}
if (!validid) {
nasm_nonfatal("identifier expected after %s, got `%s'",
directive, fullvalue);
directive, value);
break;
}
@ -527,9 +532,8 @@ 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] */
@ -542,7 +546,7 @@ bool process_directives(char *directive)
user_nolist = false;
} else {
if (*value == '-') {
user_nolist = !list_option('F');
user_nolist = true;
} else {
bad_param = true;
}
@ -629,24 +633,13 @@ 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 true;
return d != D_none;
}

View file

@ -1,5 +1,35 @@
;; SPDX-License-Identifier: BSD-2-Clause
;; Copyright 1996-2025 The NASM Authors - All Rights Reserved
;; --------------------------------------------------------------------------
;;
;; 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.
;;
;; --------------------------------------------------------------------------
;;
;; List of global NASM directives and pragma operations codes
;;
@ -17,12 +47,6 @@
;; 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
@ -31,15 +55,10 @@
#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
@ -51,29 +70,16 @@ dollarhex
extern
float
global
static
list
pragma
required
sectalign
section
segment
static
warning
; --- Common output directives/pragmas
prefix
suffix
postfix
gprefix
gsuffix
gpostfix
lprefix
lsuffix
lpostfix
sectalign
pragma
required
; --- 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
@ -95,8 +101,6 @@ 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
@ -109,17 +113,22 @@ osabi ; outelf
safeseh ; outcoff
uppercase ; outieee, outobj
; --- The following are tokens used in pragmas, not actual directives.
; They will not be accepted as directives.
; --- The following are tokens used in pragmas, not actual directives
#special pragma_tokens
; --- Assembler pragmas
prefix
suffix
gprefix
gsuffix
lprefix
lsuffix
limit
; --- Listing pragmas
options
; --- Backend-specific pragmas
; --- Backend pragmas
subsections_via_symbols ; macho
no_dead_strip ; macho
maxdump ; dbg

View file

@ -1,5 +1,35 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2025 The NASM Authors - All Rights Reserved */
/* ----------------------------------------------------------------------- *
*
* 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.
*
* ----------------------------------------------------------------------- */
/*
* error.c - error message handling routines for the assembler
@ -8,28 +38,96 @@
#include "compiler.h"
#include "nasmlib.h"
#include "error.h"
#include "files.h"
#include "listing.h"
#include "srcfile.h"
#include "strlist.h"
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 */
};
unsigned int debug_nasm; /* Debugging messages? */
unsigned int opt_verbose_info; /* Informational messages? */
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];
/* 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);
}
static void usage(void);
/*
* Warning stack management. Note that there is an implicit "push"
@ -41,7 +139,6 @@ 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)
@ -61,6 +158,12 @@ 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;
@ -68,33 +171,16 @@ void pop_warnings(void)
}
}
/* Called after the command line is parsed, but before the first pass */
static void init_warnings(void)
/* Call after the command line is parsed, but before the first pass */
void init_warnings(void)
{
push_warnings();
warning_state_init = warning_stack;
}
void error_init(void)
{
erropt.worst = 0;
init_warnings();
}
/* 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)
/* Call after each pass */
void reset_warnings(void)
{
struct warning_stack *ws = warning_stack;
@ -108,19 +194,19 @@ static 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 (see warnings.dat):
* all - all possible warnings
* other - any warning not specifically assigned a class
* 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).
*/
bool set_warning_status(const char *value)
{
@ -214,21 +300,18 @@ 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] |= old & mask;
warning_state[i] |= warning_state_init->state[i] & 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);
}
@ -263,504 +346,3 @@ 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,5 +1,35 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2024 The NASM Authors - All Rights Reserved */
/* ----------------------------------------------------------------------- *
*
* 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.
*
* ----------------------------------------------------------------------- */
/*
* eval.c expression evaluator for the Netwide Assembler
@ -736,7 +766,6 @@ 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,5 +1,35 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2009 The NASM Authors - All Rights Reserved */
/* ----------------------------------------------------------------------- *
*
* 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.
*
* ----------------------------------------------------------------------- */
/*
* eval.h header file for eval.c

View file

@ -1,5 +1,35 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2017 The NASM Authors - All Rights Reserved */
/* ----------------------------------------------------------------------- *
*
* 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.
*
* ----------------------------------------------------------------------- */
/*
* exprdump.c
@ -31,9 +61,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 %lu",
snprintf(seg_str, sizeof seg_str, "%sseg %d",
(type - EXPR_SEGBASE) == location.segment ? "this " : "",
(unsigned long)(type - EXPR_SEGBASE));
type - EXPR_SEGBASE);
return seg_str;
} else {
return "ERR";
@ -44,7 +74,6 @@ void dump_expr(const expr *e)
{
printf("[");
for (; e->type; e++)
printf("<%s(%"PRId32"),%"PRId64">",
expr_type(e->type), e->type, e->value);
printf("<%s(%d),%"PRId64">", expr_type(e->type), e->type, e->value);
printf("]\n");
}

View file

@ -1,5 +1,35 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2017 The NASM Authors - All Rights Reserved */
/* ----------------------------------------------------------------------- *
*
* 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.
*
* ----------------------------------------------------------------------- */
/*
* exprlib.c

View file

@ -1,5 +1,35 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2020 The NASM Authors - All Rights Reserved */
/* ----------------------------------------------------------------------- *
*
* 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.
*
* ----------------------------------------------------------------------- */
/*
* float.c floating-point constant support for the Netwide Assembler
@ -199,6 +229,10 @@ 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);
@ -799,10 +833,19 @@ 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");
}
@ -819,6 +862,10 @@ 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,5 +1,35 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2020 The NASM Authors - All Rights Reserved */
/* ----------------------------------------------------------------------- *
*
* 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.
*
* ----------------------------------------------------------------------- */
/*
* floats.h header file for the floating-point constant module of

View file

@ -1,5 +1,35 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 2025 The NASM Authors - All Rights Reserved */
/* ----------------------------------------------------------------------- *
*
* 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.
*
* ----------------------------------------------------------------------- */
#include "compiler.h"
#include "nasm.h"

View file

@ -1,5 +1,35 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2025 The NASM Authors - All Rights Reserved */
/* ----------------------------------------------------------------------- *
*
* 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.
*
* ----------------------------------------------------------------------- */
/*
* labels.c label handling for the Netwide Assembler
@ -210,9 +240,6 @@ 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;
}
@ -265,45 +292,14 @@ 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 directive how, const char *what)
void set_label_mangle(enum mangle_index which, 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 */
@ -418,7 +414,6 @@ 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)
@ -530,6 +525,12 @@ 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;
@ -540,7 +541,19 @@ 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,5 +1,35 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2020 The NASM Authors - All Rights Reserved */
/* ----------------------------------------------------------------------- *
*
* 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.
*
* ----------------------------------------------------------------------- */
/*
* listing.c listing file generator for the Netwide Assembler
@ -19,25 +49,11 @@
#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, cmdline_list_options;
bool user_nolist;
uint64_t list_options, active_list_options;
static char listline[LIST_MAX_LEN];
static bool listlinep;
@ -158,7 +174,6 @@ 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)
@ -273,7 +288,7 @@ static void list_output(const struct out_data *data)
}
}
static void list_line(enum list_type type, int32_t lineno, const char *line)
static void list_line(int type, int32_t lineno, const char *line)
{
(void)type;
@ -292,24 +307,20 @@ static void list_line(enum list_type type, int32_t lineno, const char *line)
listlevel_e = listlevel;
}
static void list_uplevel(enum list_type type, int64_t size)
static void list_uplevel(int type, int64_t size)
{
if (!listfp)
return;
switch (type) {
case LIST_INCBIN:
if (!list_option('c')) {
suppress |= 1;
list_size(listoffset, "bin", size);
}
suppress |= 1;
list_size(listoffset, "bin", size);
break;
case LIST_TIMES:
if (!list_option('t')) {
suppress |= 2;
list_size(listoffset, "rep", size);
}
suppress |= 2;
list_size(listoffset, "rep", size);
break;
case LIST_INCLUDE:
@ -322,7 +333,7 @@ static void list_uplevel(enum list_type type, int64_t size)
}
}
static void list_downlevel(enum list_type type)
static void list_downlevel(int type)
{
if (!listfp)
return;
@ -366,68 +377,36 @@ static void list_set_offset(uint64_t offset)
listoffset = offset;
}
/*
* 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)
static void list_update_options(const char *str)
{
bool state = true;
unsigned char c;
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];
uint64_t mask;
while ((c = *str++)) {
uint64_t mask = 0;
switch (c) {
case '+':
if (*cmdline_next_plus)
list_update_options(*cmdline_next_plus++, true);
setmask = LIST_ALL_OPTIONS_MASK;
state = true;
break;
case '-':
setmask = 0;
state = false;
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, false);
list_update_options(pragma->tail);
return DIRR_OK;
default:

View file

@ -1,5 +1,35 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2020 The NASM Authors - All Rights Reserved */
/* ----------------------------------------------------------------------- *
*
* 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.
*
* ----------------------------------------------------------------------- */
/*
* listing.h header file for listing.c
@ -10,21 +40,6 @@
#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:
*/
@ -61,7 +76,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)(enum list_type type, int32_t lineno, const char *line);
void (*line)(int type, int32_t lineno, const char *line);
/*
* Called to change one of the various levelled mechanisms in the
@ -77,12 +92,12 @@ struct lfmt {
* macro, so anything under that level won't be expanded unless
* it includes another file.
*/
void (*uplevel)(enum list_type type, int64_t size);
void (*uplevel)(int type, int64_t size);
/*
* Reverse the effects of uplevel.
*/
void (*downlevel)(enum list_type type);
void (*downlevel)(int type);
/*
* Called on a warning or error, with the error message.
@ -108,7 +123,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, cmdline_list_options;
extern uint64_t list_options, active_list_options;
/*
* This maps the characters a-z, A-Z and 0-9 onto a 64-bit bitmask.
@ -122,10 +137,13 @@ extern uint64_t list_options, active_list_options, cmdline_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 in list_update_options(), which is not
* performance critical.
* 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.)
*/
static inline const_func uint64_t list_option_mask(unsigned char x)
static inline const_func uint64_t list_option_mask_val(unsigned char x)
{
if (x >= 'a') {
if (x > 'z')
@ -146,7 +164,13 @@ static inline const_func uint64_t list_option_mask(unsigned char x)
return UINT64_C(1) << x;
}
#define LIST_ALL_OPTIONS_MASK (~UINT64_C(3))
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);
}
/* Return true if the listing engine is active and a certain option is set. */
static inline pure_func bool list_option(unsigned char x)
@ -166,9 +190,6 @@ 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 *);

1224
asm/nasm.c

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,35 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2025 The NASM Authors - All Rights Reserved */
/* ----------------------------------------------------------------------- *
*
* 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.
*
* ----------------------------------------------------------------------- */
/*
* parser.c source line parser for the Netwide Assembler
@ -300,6 +330,14 @@ 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");
@ -717,7 +755,6 @@ 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;
@ -727,7 +764,6 @@ insn *parse_line(char *buffer, insn *result, const int bits)
restart_parse:
first = true;
colonless_label = false;
stdscan_reset(buffer);
i = stdscan(NULL, &tokval);
@ -746,17 +782,21 @@ 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) {
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);
/*!
*!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");
}
if (i != TOKEN_INSN || tokval.t_integer != I_EQU) {
/*
@ -824,14 +864,7 @@ restart_parse:
set_imm_flags(&result->oprs[0], result->opt);
}
} else if (!first) {
/*
* 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 ? " " : "",
nasm_nonfatal("instruction expected, found `%.*s'",
tokval.t_len, tokval.t_start);
} else if (!result->label) {
nasm_nonfatal("label, instruction or prefix expected at start of line, found `%.*s'",
@ -896,6 +929,13 @@ 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;
@ -964,10 +1004,8 @@ 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 */
result->opt |= OPTIM_NO_Jcc_RELAX | OPTIM_NO_JMP_RELAX;
if (!setsize) /* we want to use only the first */
op->type |= BITS8;
}
setsize = 1;
break;
case S_WORD:
@ -1016,12 +1054,9 @@ 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:
@ -1106,7 +1141,7 @@ restart_parse:
* as if it had ended in a comma, but sets the COLON flag
* on the operand further down.
*/
} else if (mref || (ok_reg && IS_SREG(value->type))) {
} else if (mref || !far_jmp_ok) {
/* segment override? */
mref = true;
@ -1209,8 +1244,7 @@ restart_parse:
i = tokval.t_type;
}
if (!recover && i != 0 && i != ',') {
nasm_nonfatal("comma, decorator or end of line expected, got `%*s'",
(int)tokval.t_len, tokval.t_start);
nasm_nonfatal("comma, decorator or end of line expected, got %d", i);
recover = true;
}
} else { /* immediate operand */
@ -1255,7 +1289,6 @@ 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);
@ -1269,27 +1302,6 @@ 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
@ -1405,6 +1417,21 @@ 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,5 +1,35 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2009 The NASM Authors - All Rights Reserved */
/* ----------------------------------------------------------------------- *
*
* 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.
*
* ----------------------------------------------------------------------- */
/*
* parser.h header file for the parser module of the Netwide

View file

@ -1,5 +1,35 @@
# SPDX-License-Identifier: BSD-2-Clause
# Copyright 1996-2025 The NASM Authors - All Rights Reserved
## --------------------------------------------------------------------------
##
## 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.
##
## --------------------------------------------------------------------------
#
# A * at the end indicates a condition; the list of conditions are

View file

@ -1,6 +1,36 @@
#!/usr/bin/perl
# SPDX-License-Identifier: BSD-2-Clause
# Copyright 1996-2025 The NASM Authors - All Rights Reserved
## --------------------------------------------------------------------------
##
## 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.
##
## --------------------------------------------------------------------------
#
# Produce pptok.c, pptok.h, pptok.ph and pptok.src from pptok.dat

View file

@ -1,5 +1,35 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2019 The NASM Authors - All Rights Reserved */
/* ----------------------------------------------------------------------- *
*
* 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.
*
* ----------------------------------------------------------------------- */
/*
* Parse and handle [pragma] directives. The preprocessor handles
@ -162,10 +192,22 @@ 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);
@ -193,7 +235,21 @@ 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;
@ -216,16 +272,7 @@ void process_pragma(char *str)
else
pragma.opcode = directive_find(pragma.opname);
/*
* 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;
pragma.tail = nasm_trim_spaces(p);
/*
* Search the global pragma namespaces. This is done
@ -287,14 +334,17 @@ 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:
case D_POSTFIX:
case D_GPOSTFIX:
set_label_mangle(LM_GSUFFIX, pragma->tail);
return DIRR_OK;
case D_LPREFIX:
set_label_mangle(LM_LPREFIX, pragma->tail);
return DIRR_OK;
case D_LSUFFIX:
case D_LPOSTFIX:
set_label_mangle(pragma->opcode, pragma->tail);
set_label_mangle(LM_LSUFFIX, pragma->tail);
return DIRR_OK;
default:
return DIRR_UNKNOWN;

View file

@ -1,5 +1,35 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2025 The NASM Authors - All Rights Reserved */
/* ----------------------------------------------------------------------- *
*
* 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.
*
* ----------------------------------------------------------------------- */
/*
* preproc.c macro preprocessor for the Netwide Assembler
@ -148,33 +178,23 @@ 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.
*
* 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...
* 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.
*
* 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;
@ -945,6 +965,17 @@ 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 = "";
@ -1110,19 +1141,6 @@ 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.
@ -1572,6 +1590,17 @@ 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')",
@ -1631,6 +1660,12 @@ 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");
}
@ -1736,6 +1771,11 @@ 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;
@ -1991,9 +2031,6 @@ 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;
@ -2024,8 +2061,6 @@ 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;
}
@ -2039,7 +2074,7 @@ static inline void free_Blocks(void)
static Token *do_delete_Token(Token **tp)
{
if (tp && *tp)
if (tp)
return *tp = free_Token(*tp);
else
return NULL;
@ -2284,11 +2319,12 @@ 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 needing const removal here */
tokval->t_charptr = (char *)txt; /* Fix this */
switch (tline->type) {
default:
break;
return tokval->t_type = tline->type;
case TOKEN_ID:
if (txt[0] == '$') {
@ -2366,6 +2402,13 @@ 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");
}
@ -2769,20 +2812,19 @@ restart:
return false;
}
/* param should be a natural number [0; INT_MAX] */
static int read_param_count(const char *str)
{
int64_t result;
int result;
bool err;
result = readnum(str, &err);
if (err || result < 0) {
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)
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;
}
@ -2841,9 +2883,6 @@ 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, ',')) {
@ -3181,7 +3220,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);
@ -3298,13 +3337,12 @@ list_smacro_def(enum preproc_token op, const Context *ctx, const SMacro *m)
if (m->nparam) {
/*
* Space for "(" at the beginning, then up to 5 flags "=&&!+"
* + "/ux" + terminal "," or ")" per parameter, plus the parameter
* name, if any.
* Space for ( and either , or ) around each
* parameter, plus up to 5 flags + /ux
*/
int i;
size += 1 + (5+3+1) * m->nparam;
size += 1 + 8 * m->nparam;
for (i = 0; i < m->nparam; i++)
size += m->params[i].name.len;
}
@ -3476,8 +3514,6 @@ static int parse_smacro_template(Token ***tpp, SMacro *tmpl)
cp = NULL;
break;
}
if (!cp) /* stop on invalid radix specifier */
break;
}
} else {
if (name)
@ -3603,6 +3639,17 @@ 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",
@ -3612,15 +3659,36 @@ static SMacro *define_smacro(const char *mname, bool casesense,
defined = false;
} else if ((!!nparam) ^ (!!smac->nparam)) {
/*
* The immediately previous versions of NASM considered
* this an error, so promote this warning is promoted to
* to error by default.
* 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}.
*/
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);
@ -3809,6 +3877,12 @@ 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);
}
@ -4282,6 +4356,10 @@ 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:
@ -4690,16 +4768,8 @@ static int do_directive(Token *tline, Token **output, bool suppressed)
/* Emulate legacy behavior */
do_clear(CLEAR_DEFINE|CLEAR_MMACRO, false);
} else {
while (tok_is(t, TOKEN_ID)) {
while ((t = skip_white(t)) && t->type == 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") ||
@ -4730,7 +4800,6 @@ static int do_directive(Token *tline, Token **output, bool suppressed)
} else {
nasm_nonfatal("invalid option to %s: %s", dname, txt);
t = NULL;
break;
}
}
}
@ -4864,17 +4933,9 @@ static int do_directive(Token *tline, Token **output, bool suppressed)
break;
CASE_PP_IF:
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.
*/
if (istk->conds && !emitting(istk->conds->state))
j = COND_NEVER;
} else {
else {
j = if_condition(tline->next, op, dname);
tline->next = NULL; /* it got freed */
}
@ -4902,6 +4963,12 @@ 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;
@ -4946,6 +5013,12 @@ 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;
@ -4970,13 +5043,6 @@ 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;
@ -4985,10 +5051,8 @@ 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;
@ -5012,6 +5076,12 @@ 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);
@ -5035,7 +5105,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 == %"PRIzu, defining->refcnt);
nasm_panic("defining->refcnt == %zu", defining->refcnt);
mmhead = (MMacro **) hash_findi_add(&mmacros, defining->name);
defining->next = *mmhead;
@ -5159,6 +5229,12 @@ 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;
@ -5224,8 +5300,7 @@ static int do_directive(Token *tline, Token **output, bool suppressed)
case PP_EXITREP:
{
MMacro *m = do_exit_macro(dname, false);
if (m)
m->in_progress = 1; /* No more repeats */
m->in_progress = 1; /* No more repeats */
break;
}
@ -6291,6 +6366,7 @@ 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;
@ -6389,6 +6465,8 @@ 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;
@ -6498,7 +6576,13 @@ static SMacro *expand_one_smacro(Token ***tpp)
*/
while (1) {
if (!m) {
nasm_warn(WARN_PP_MACRO_PARAMS_SINGLE,
/*!
*!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,
"single-line macro `%s' exists, "
"but not taking %d parameter%s",
mname, nparam, (nparam == 1) ? "" : "s");
@ -6719,8 +6803,7 @@ 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 %"PRId32,
nasm_warn(WARN_OTHER, "reached maximum recursion depth of %i",
m->max_depth);
}
nasm_free(params);
@ -6888,6 +6971,22 @@ 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) {
@ -6952,6 +7051,12 @@ 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;
@ -7279,7 +7384,7 @@ static int expand_mmacro(Token * tline)
*/
nasm_newn(paramlen, nparam+1);
for (i = 1; i < nparam+1 && (t = params[i]); i++) {
for (i = 1; (t = params[i]); i++) {
bool braced = false;
int brace = 0;
int white = 0;
@ -7785,9 +7890,9 @@ stdmac_tok(const SMacro *s, Token **params, int nparams)
return reverse_tokens(tokenize(unquote_token_cstr(params[0])));
}
/* %sel() */
/* %cond() or %sel() */
static Token *
stdmac_sel(const SMacro *s, Token **params, int nparams)
stdmac_cond_sel(const SMacro *s, Token **params, int nparams)
{
int64_t which;
@ -7796,57 +7901,35 @@ stdmac_sel(const SMacro *s, Token **params, int nparams)
*/
which = get_tok_num(params[0], 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;
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;
}
}
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)
@ -8200,94 +8283,6 @@ 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
@ -8326,7 +8321,6 @@ 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 },
@ -8337,7 +8331,6 @@ 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 },
@ -8433,16 +8426,15 @@ static void pp_add_magic_miscfunc(void)
/* %sel() function */
nasm_zero(tmpl);
tmpl.nparam = 2;
tmpl.expand = stdmac_sel;
tmpl.expand = stdmac_cond_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 */
nasm_zero(tmpl);
/* %cond() function, a variation on %sel */
tmpl.nparam = 3;
tmpl.expand = stdmac_cond;
tmpl.expandpvt.u = 1; /* Booleanize */
nasm_newn(tmpl.params, tmpl.nparam);
tmpl.params[0].flags = SPARM_EVAL;
tmpl.params[1].flags = 0;
@ -8498,29 +8490,6 @@ 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" };
@ -8570,26 +8539,6 @@ 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;
@ -8605,9 +8554,6 @@ 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;
/*
@ -8638,7 +8584,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, char const* mapped_fname, enum preproc_mode mode,
void pp_reset(const char *file, enum preproc_mode mode,
struct strlist *dep_list)
{
cstk = NULL;
@ -8677,7 +8623,7 @@ void pp_reset(const char *file, char const* mapped_fname, enum preproc_mode mode
nasm_fatalf(ERR_NOFILE, "unable to open input file `%s'%s%s",
file, errno ? " " : "", errno ? strerror(errno) : "");
}
src_set(0, mapped_fname);
src_set(0, file);
istk->where = src_where();
istk->lineinc = 1;
@ -8700,36 +8646,6 @@ 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
@ -8897,8 +8813,25 @@ static Token *pp_tokline(void)
/*
* The current file/input has ended; work down the istk
*/
Include *i = pop_include_stack();
Include *i = istk;
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);
@ -9013,19 +8946,10 @@ void pp_cleanup_pass(void)
{
if (defining) {
if (defining->name) {
nasm_nonfatal("end of input while still defining macro `%s'",
nasm_nonfatal("end of file while still defining macro `%s'",
defining->name);
} else {
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;
nasm_nonfatal("end of file while still in %%rep");
}
free_mmacro(defining);
@ -9035,8 +8959,19 @@ void pp_cleanup_pass(void)
while (cstk)
ctx_pop();
free_macros();
while (istk)
nasm_free(pop_include_stack());
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);
if (ppdbg & PDBG_MMACROS)
debug_macro_output();
@ -9113,17 +9048,13 @@ 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;
Token *def, *space;
Line *l;
def = tokenize(string);
if (what) {
Token *wt = tokenize(what);
Token **tailp = tlist_endptr(&wt);
*tailp = new_White(def);
def = wt;
space = new_White(def);
def = new_Token(space, TOKEN_PREPROC_ID, what, 0);
}
nasm_new(l);
@ -9195,7 +9126,7 @@ make_tok_num_radix(Token *next, int64_t val, char radix, bool uns)
upper = !(radix & 0x20);
}
p += numstr(p, sizeof(numbuf)-2, uval, -1, base, upper);
p += numstr(p, 64, uval, -1, base, upper);
next = new_Token(next, TOKEN_NUM, numbuf, p - numbuf);
if (minus)

View file

@ -1,5 +1,35 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2025 The NASM Authors - All Rights Reserved */
/* ----------------------------------------------------------------------- *
*
* 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.
*
* ----------------------------------------------------------------------- */
/*
* preproc.h header file for preproc.c

View file

@ -1,5 +1,35 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2020 The NASM Authors - All Rights Reserved */
/* ----------------------------------------------------------------------- *
*
* 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.
*
* ----------------------------------------------------------------------- */
/*
* quote.c
@ -269,35 +299,36 @@ 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)
{
const unsigned char bq = *str;
const unsigned char *p = (unsigned char *)str;
unsigned char *q = (unsigned char *)str;
unsigned char bq;
const unsigned char *p;
const unsigned char *escp = NULL;
unsigned char *q;
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 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 */
/* `...` string */
state = st_start;
while (state != st_done) {
c = *p++;
@ -305,18 +336,17 @@ 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-1;
escp = p; /* Beginning of argument sequence */
nval = 0;
switch (c) {
case 'a':
nval = 7;
@ -339,33 +369,22 @@ 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;
goto check_brace;
break;
case 'U':
state = st_ucs;
base = 16;
ndig = 8;
goto check_brace;
break;
case 'v':
nval = 11;
break;
case 'x':
case 'X':
state = st_byte;
base = 16;
state = st_hex;
ndig = 2;
goto check_brace;
case 'd': /* NASM extension: \d = decimal */
state = st_byte;
base = 10;
ndig = 3;
goto check_brace;
break;
case '0':
case '1':
case '2':
@ -374,19 +393,10 @@ size_t nasm_unquote_anystr(char *str, char **ep, const uint32_t badctl,
case '5':
case '6':
case '7':
/* 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;
state = st_oct;
ndig = 2; /* Up to two more digits */
nval = c - '0';
break;
case '\0':
nval = '\\';
p--; /* Reprocess; terminates string */
@ -399,24 +409,31 @@ size_t nasm_unquote_anystr(char *str, char **ep, const uint32_t badctl,
EMIT(nval);
break;
case st_byte:
case st_ucs:
if ((v = numvalue_chk(c)) < base) {
nval = (nval * base) + v;
case st_oct:
if (c >= '0' && c <= '7') {
nval = (nval << 3) + (c - '0');
if (--ndig)
break; /* Continue processing number, no output */
} else if (ndig < 0) {
/* End of braced sequence */
if (unlikely(c != '}'))
goto rewind;
break; /* Might have more digits */
} else {
p--; /* Reprocess terminating character */
if (unlikely(p == escp+1))
goto rewind; /* No digits at all received */
p--; /* Process this character again */
}
EMIT(nval);
state = st_start;
break;
case st_hex:
case st_ucs:
if (nasm_isxdigit(c)) {
nval = (nval << 4) + numvalue(c);
if (--ndig)
break; /* Might have more digits */
} else {
p--; /* Process this character again */
}
/* Emit the output */
if (state == st_ucs)
if (unlikely(p <= escp))
EMIT(escp[-1]);
else if (state == st_ucs)
EMIT_UTF8(nval);
else
EMIT(nval);
@ -424,23 +441,6 @@ 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,11 +451,10 @@ 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 == '\"'.
*/
p++; /* Skip initial quote */
while ((c = *p++) && c != bq)
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);
}
@ -466,11 +465,8 @@ 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) {
/* Point at the terminating character */
if (ep)
*ep = (char *)p - 1;
}
return (char *)q - str;
}
#undef EMIT
@ -505,7 +501,11 @@ char *nasm_skip_string(const char *str)
char bq;
const char *p;
char c;
enum unq_state state;
enum unq_state {
st_start,
st_backslash,
st_done
} state;
bq = str[0];
p = str+1;
@ -539,20 +539,13 @@ 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 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.)
* 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.
*/
if (c == '^')
c = *p++;
state = c ? st_start : st_done;
break;

View file

@ -1,5 +1,35 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2009 The NASM Authors - All Rights Reserved */
/* ----------------------------------------------------------------------- *
*
* 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.
*
* ----------------------------------------------------------------------- */
#ifndef NASM_QUOTE_H
#define NASM_QUOTE_H
@ -28,3 +58,4 @@ char *nasm_skip_string(const char *str);
#define STR_NASM '`'
#endif /* NASM_QUOTE_H */

View file

@ -1,5 +1,35 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2016 The NASM Authors - All Rights Reserved */
/* ----------------------------------------------------------------------- *
*
* 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.
*
* ----------------------------------------------------------------------- */
/*
* rdstrnum.c

View file

@ -1,5 +1,35 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2018 The NASM Authors - All Rights Reserved */
/* ----------------------------------------------------------------------- *
*
* 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.
*
* ----------------------------------------------------------------------- */
/*
* nasmlib.c library routines for the Netwide Assembler

View file

@ -1,5 +1,35 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2020 The NASM Authors - All Rights Reserved */
/* ----------------------------------------------------------------------- *
*
* 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.
*
* ----------------------------------------------------------------------- */
/*
* srcfile.c - keep track of the current position in the input stream.

View file

@ -1,5 +1,35 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2020 The NASM Authors - All Rights Reserved */
/* ----------------------------------------------------------------------- *
*
* 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.
*
* ----------------------------------------------------------------------- */
/*
* These functions are used to keep track of the source code file and name.

View file

@ -1,5 +1,35 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2024 The NASM Authors - All Rights Reserved */
/* ----------------------------------------------------------------------- *
*
* 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.
*
* ----------------------------------------------------------------------- */
#include "compiler.h"
@ -318,6 +348,15 @@ 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,5 +1,35 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2009 The NASM Authors - All Rights Reserved */
/* ----------------------------------------------------------------------- *
*
* 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.
*
* ----------------------------------------------------------------------- */
/*
* stdscan.h header file for stdscan.c

View file

@ -1,5 +1,35 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2009 The NASM Authors - All Rights Reserved */
/* ----------------------------------------------------------------------- *
*
* 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.
*
* ----------------------------------------------------------------------- */
/*
* strfunc.c

View file

@ -1,5 +1,35 @@
# SPDX-License-Identifier: BSD-2-Clause
# Copyright 1996-2025 The NASM Authors - All Rights Reserved
## --------------------------------------------------------------------------
##
## 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.
##
## --------------------------------------------------------------------------
# The token parameters are in the order:
# TOKEN_TYPE, t_inttwo, t_flags, t_integer
@ -160,10 +190,6 @@ 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,6 +1,36 @@
#!/usr/bin/perl
# SPDX-License-Identifier: BSD-2-Clause
# Copyright 1996-2020 The NASM Authors - All Rights Reserved
## --------------------------------------------------------------------------
##
## 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.
##
## --------------------------------------------------------------------------
#
# Generate a perfect hash for token parsing

View file

@ -1,5 +1,35 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 2025 The NASM Authors - All Rights Reserved */
/* ----------------------------------------------------------------------- *
*
* 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.
*
* ----------------------------------------------------------------------- */
/*
* This needs to be in a separate file because zlib.h conflicts
@ -27,7 +57,7 @@ static void nasm_z_free(void *opaque, void *ptr)
nasm_free(ptr);
}
char *uncompress_stdmac(macros_t *sm)
char *uncompress_stdmac(const macros_t *sm)
{
z_stream zs;
void *buf = nasm_malloc(sm->dsize);
@ -40,7 +70,7 @@ char *uncompress_stdmac(macros_t *sm)
zs.zalloc = nasm_z_alloc;
zs.zfree = nasm_z_free;
if (inflateInit2(&zs, 15) != Z_OK)
if (inflateInit2(&zs, 0) != Z_OK)
panic();
if (inflate(&zs, Z_FINISH) != Z_STREAM_END)

View file

@ -1,445 +0,0 @@
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,73 +43,93 @@ sub add_alias($$) {
}
}
sub read_warnings($) {
my($infile) = @_;
sub find_warnings {
my $infile = $_;
open(my $in, '<', $infile) or die "$0:$infile: $!\n";
return unless (basename($infile) =~ /^\w.*\.[ch]$/i);
open(my $in, '<', $infile)
or die "$0: cannot open input file $infile: $!\n";
my $in_comment = 0;
my $nline = 0;
my $this;
my @doc;
while (defined(my $l = <$in>)) {
$nline++;
$l =~ s/\s+$//;
if ($l ne '') {
$l =~ s/^\s*\#(\s.*)?$//;
$l =~ s/\s+\\\#(\s.*)?$//;
next if ($l eq '');
chomp $l;
if (!$in_comment) {
$l =~ s/^.*?\/\*.*?\*\///g; # Remove single-line comments
if ($l =~ /^.*?(\/\*.*)$/) {
# Begin block comment
$l = $1;
$in_comment = 1;
}
}
if ($l =~ /^([\w\-]+)\s+\[(\w+)\]\s+(.*)$/) {
my $name = $1;
my $def = $2;
my $help = $3;
if ($in_comment) {
if ($l =~ /\*\//) {
# End block comment
$in_comment = 0;
undef $this;
} elsif ($l =~ /^\s*\/?\*\!(\-|\=|\s*)(.*?)\s*$/) {
my $opr = $1;
my $str = $2;
my $cname = uc($name);
$cname =~ s/[^A-Z0-9_]+/_/g;
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;
$this = {name => $name, cname => $cname,
def => $def, help => $help,
doc => [], file => $infile, line => $nline};
my $cname = uc($name);
$cname =~ s/[^A-Z0-9_]+/_/g;
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};
$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++;
}
} else {
push(@warnings, $this);
# Every warning name is also a valid warning alias
add_alias($name, $this);
$nwarn++;
undef $this;
}
} 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, @infiles) = @ARGV;
my($what, $outfile, @indirs) = @ARGV;
if (!defined($outfile)) {
die "$0: usage: [c|h|doc] outfile infiles...\n";
die "$0: usage: [c|h|doc] outfile indir...\n";
}
foreach my $file (@infiles) {
read_warnings($file);
}
find({ wanted => \&find_warnings, no_chdir => 1, follow => 1 }, @indirs);
exit(1) if ($err);
@ -121,7 +141,8 @@ sub sort_warnings {
}
@warnings = sort sort_warnings @warnings;
my @warn_noall = grep { !($_->{name} eq 'all') } @warnings;
my @warn_noall = @warnings;
pop @warn_noall if ($warn_noall[$#warn_noall]->{name} eq 'all');
my $outdata;
open(my $out, '>', \$outdata)
@ -131,16 +152,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 " NULL";
print $out "\tNULL";
foreach my $warn (@warnings) {
print $out ",\n \"", $warn->{name}, "\"";
print $out ",\n\t\"", $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 { %-39s WARN_IDX_%-31s }",
printf $out "%s\n\t{ %-27s WARN_IDX_%s }",
$sep, "\"$alias\",", $aliases{$alias}->{cname};
$sep = ',';
}
@ -148,20 +169,20 @@ if ($what eq 'c') {
printf $out "const char * const warning_help[%d] = {\n",
$#warnings + 2;
print $out " NULL";
print $out "\tNULL";
foreach my $warn (@warnings) {
my $help = quote_for_c(remove_markup($warn->{help}));
print $out ",\n \"", $help, "\"";
print $out ",\n\t\"", $help, "\"";
}
print $out "\n};\n\n";
printf $out "const uint8_t warning_default[%d] = {\n",
$#warn_noall + 2;
print $out " WARN_INIT_ON"; # for entry 0
print $out "\tWARN_INIT_ON"; # for entry 0
foreach my $warn (@warn_noall) {
print $out ",\n WARN_INIT_", uc($warn->{def});
print $out ",\n\tWARN_INIT_", uc($warn->{def});
}
print $out "\n};\n\n";
printf $out "uint8_t warning_state[%d]; /* Current state */\n",
printf $out "uint8_t warning_state[%d];\t/* Current state */\n",
$#warn_noall + 2;
} elsif ($what eq 'h') {
my $filename = basename($outfile);
@ -176,30 +197,29 @@ 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 " WARN_IDX_%-31s = %3d, /* not suppressible */\n", 'NONE', 0;
printf $out "\tWARN_IDX_%-23s = %3d, /* not suppressible */\n", 'NONE', 0;
my $n = 1;
foreach my $warn (@warnings) {
printf $out " WARN_IDX_%-31s = %3d%s /* %s */\n",
printf $out "\tWARN_IDX_%-23s = %3d%s /* %s */\n",
$warn->{cname}, $n,
($n == $#warnings + 1) ? " " : ",",
remove_markup($warn->{help});
$warn->{help};
$n++;
}
print $out "};\n\n";
print $out "enum warn_const {\n";
printf $out " WARN_%-35s = %3d << WARN_SHR", 'NONE', 0;
printf $out "\tWARN_%-27s = %3d << WARN_SHR", 'NONE', 0;
$n = 1;
foreach my $warn (@warn_noall) {
printf $out ",\n WARN_%-35s = %3d << WARN_SHR", $warn->{cname}, $n++;
printf $out ",\n\tWARN_%-27s = %3d << WARN_SHR", $warn->{cname}, $n++;
}
print $out "\n};\n\n";
print $out "struct warning_alias {\n";
print $out " const char *name;\n";
print $out " enum warn_index warning;\n";
print $out "\tconst char *name;\n";
print $out "\tenum 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",
@ -207,36 +227,46 @@ 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[NUM_WARNINGS];\n",
printf $out "extern uint8_t warning_state[NUM_WARNINGS];\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;
print $out "\n#endif /* $guard */\n";
} elsif ($what eq 'doc') {
my %wsec = ('on' => [], 'off' => [], 'err' => [],
'group' => [], 'legacy' => []);
my %whatdef = ( 'on' => 'Enabled',
'off' => 'Disabled',
'err' => 'Enabled and promoted to error' );
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 = ("group alias for:\n\n");
push(@doc, map { "\\c $_\n" } @plist);
$wtxt = $wsec{'group'};
@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");
} elsif ($pfx ne $warn->{name}) {
my $awarn = $aliases{$warn->{name}};
@doc = ($awarn->{help}."\n\n",
"\\> Alias for \\c{".$warn->{name}."}.\n");
$wtxt = $wsec{'legacy'};
"\\> \\c{$pfx} is a backwards compatibility alias for \\c{".
$warn->{name}."}.\n");
} else {
@doc = ($warn->{help}."\n\n");
my $docdef = $whatdef{$warn->{def}};
my $newpara = 1;
@doc = ($warn->{help}."\n\n",
"\\> \\c{".$warn->{name}."} ");
my $newpara = 0;
foreach my $l (@{$warn->{doc}}) {
if ($l =~ /^\s*$/) {
$newpara = 1;
@ -248,45 +278,33 @@ if ($what eq 'c') {
}
push(@doc, $l);
}
$wtxt = $wsec{$warn->{def}};
if (defined($docdef)) {
push(@doc, "\n", "\\> $docdef by default.\n");
}
}
push(@indexinfo, "\\IR{w-$pfx} warning class, \\c{$pfx}\n");
push(@$wtxt, "\\b \\I{w-$pfx} \\c{$pfx}: ", @doc, "\n");
push(@outtxt, "\\b \\I{w-$pfx} \\c{$pfx}: ", @doc, "\n");
}
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'}};
print $out "\n", @indexinfo, "\n", @outtxt;
}
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,10 +5,9 @@ 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_ADD_LANGFLAGS([-g3])
PA_ARG_DISABLED([gdb], [disable gdb debug extensions],,
[PA_ADD_LANGFLAGS([-ggdb])])
[PA_ARG_DISABLED([gdb], [disable gdb debug extensions],
[PA_ADD_LANGFLAGS([-g3])], [PA_ADD_LANGFLAGS([-ggdb3],[-g3])])
PA_ARG_ENABLED([debug], [optimize for debugging],
[PA_ADD_LANGFLAGS([-Og],[-O0])
[PA_ADD_LANGFLAGS([-Og],[-O0])
$1],
[$2])])

View file

@ -7,24 +7,15 @@ dnl but that could change in the future -- to force disabled by default,
dnl set to "no".
dnl --------------------------------------------------------------------------
AC_DEFUN([PA_OPTION_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],
[AC_BEFORE([$0],[AC_PROG_AR])dnl
AC_BEFORE([$0],[AC_PROG_RANLIB])dnl
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(CC_AR, gcc-ar)
AR="${CC_AR:-$AR}"
AC_CHECK_TOOL(CC_RANLIB, gcc-ranlib)
RANLIB="${CC_RANLIB:-$RANLIB}"])])])
[AC_CHECK_TOOL(AR, [gcc-ar], [ar], [:])
AC_CHECK_TOOL(RANLIB, [gcc-ranlib], [ranlib], [:])])])])

View file

@ -46,14 +46,7 @@ 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
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"
ACLOCAL_PATH="${ACLOCAL_PATH}${ACLOCAL_PATH:+:}`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,5 +1,35 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2025 The NASM Authors - All Rights Reserved */
/* ----------------------------------------------------------------------- *
*
* 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.
*
* ----------------------------------------------------------------------- */
/*
* common.c - code common to nasm and ndisasm
@ -15,15 +45,6 @@
*/
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
*/

View file

@ -1,109 +0,0 @@
/* 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);
}

View file

@ -1,76 +0,0 @@
/* 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,5 +1,35 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 2016 The NASM Authors - All Rights Reserved */
/* ----------------------------------------------------------------------- *
*
* 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.
*
* ----------------------------------------------------------------------- */
/*
* config/msvc.h
@ -25,12 +55,6 @@
#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
@ -39,25 +63,9 @@
# 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
@ -70,9 +78,6 @@
/* 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
@ -85,13 +90,6 @@
# 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
@ -109,25 +107,6 @@
/* 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
@ -183,18 +162,6 @@
# 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,5 +1,35 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 2016 The NASM Authors - All Rights Reserved */
/* ----------------------------------------------------------------------- *
*
* 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.
*
* ----------------------------------------------------------------------- */
/*
* config/unknown.h

View file

@ -1,5 +1,35 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 2016 The NASM Authors - All Rights Reserved */
/* ----------------------------------------------------------------------- *
*
* 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.
*
* ----------------------------------------------------------------------- */
/*
* config/watcom.h

View file

@ -1,8 +1,7 @@
dnl Process this file with autoconf 2.71 or later to produce
dnl a configure script.
AC_PREREQ([2.71])
m4_define([VERSION],m4_normalize(m4_include([version])))
AC_INIT([nasm],VERSION,[https://bugs.nasm.us/],[nasm],[https://www.nasm.us/])
AC_INIT
AC_CONFIG_SRCDIR([config/config.h.in])
AC_CONFIG_HEADERS([config/config.h])
AC_PREFIX_PROGRAM(nasm)
@ -91,10 +90,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
@ -148,7 +147,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
@ -196,6 +195,7 @@ 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,6 +243,7 @@ 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
@ -276,7 +277,6 @@ 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 travis.mak])
AC_CONFIG_FILES([Makefile doc/Makefile misc/Makefile test/Makefile])
AC_OUTPUT

View file

@ -1,5 +1,35 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2025 The NASM Authors - All Rights Reserved */
/* ----------------------------------------------------------------------- *
*
* 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.
*
* ----------------------------------------------------------------------- */
/*
* disasm.c where all the _work_ gets done in the Netwide Disassembler
@ -109,48 +139,35 @@ 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)
{
#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);
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;
}
}
@ -563,14 +580,11 @@ static int matches(const uint8_t *data, const struct prefix_info *prefix,
opx->segment |= SEG_SIGNED;
break;
case4(0300):
if (!is_hint_nop(*data))
return 0;
case4(020):
opx->offset = *data++;
opx->disp_size = 8;
break;
case4(020):
case4(024):
opx->offset = *data++;
opx->disp_size = 8;
@ -1516,7 +1530,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(UNITY, t)) {
if (is_class(t, UNITY)) {
output[slen++] = '1';
} else if (o->segment & SEG_DFV) {
int fl;

View file

@ -1,5 +1,35 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2025 The NASM Authors - All Rights Reserved */
/* ----------------------------------------------------------------------- *
*
* 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.
*
* ----------------------------------------------------------------------- */
/*
* disasm.h header file for disasm.c
@ -87,8 +117,4 @@ const uint8_t *parse_prefixes(struct prefix_info *pf, const uint8_t *data,
_op; \
} while (0)
/* Error module */
void usage(void);
#endif

View file

@ -1,46 +0,0 @@
/* 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,5 +1,35 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2025 The NASM Authors - All Rights Reserved */
/* ----------------------------------------------------------------------- *
*
* 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.
*
* ----------------------------------------------------------------------- */
/*
* ndisasm.c the Netwide Disassembler main module
@ -18,12 +48,41 @@
#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 bool skip(off_t *posp, off_t dist, FILE *fp);
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;
int main(int argc, char **argv)
{
@ -32,27 +91,21 @@ int main(int argc, char **argv)
char outbuf[256];
char *pname = *argv;
char *filename = NULL;
uint64_t nextsync, synclen;
size_t lenread;
uint32_t nextsync, synclen, initskip = 0L;
int lenread;
int32_t lendis;
bool autosync = false;
int bits = 16, b;
bool eof;
bool eof = false;
iflag_t prefer;
bool rn_error;
uint64_t offset, dataread, datamax;
off_t fileoffs, initskip;
int64_t offset;
FILE *fp;
_progname = argv[0];
reset_global_defaults(0);
nasm_ctype_init();
iflag_clear_all(&prefer);
offset = 0;
datamax = UINT64_C(-1);
initskip = 0;
offset = 0;
init_sync();
while (--argc) {
@ -67,7 +120,7 @@ int main(int argc, char **argv)
p++;
break;
case 'h':
usage();
fputs(help, stderr);
return 0;
case 'r':
case 'v':
@ -88,23 +141,6 @@ 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) {
@ -247,8 +283,8 @@ int main(int argc, char **argv)
}
if (!filename) {
usage();
return 1;
fprintf(stderr, help, pname);
return 0;
}
if (strcmp(filename, "-")) {
@ -263,12 +299,8 @@ int main(int argc, char **argv)
fp = stdin;
}
reset_global_defaults(bits);
fileoffs = 0;
dataread = 0;
if (!skip(&fileoffs, initskip, fp))
return 1; /* EOF before header */
if (initskip > 0)
skip(initskip, fp);
/*
* This main loop is really horrible, and wants rewriting with
@ -278,42 +310,35 @@ int main(int argc, char **argv)
q = p = buffer;
nextsync = next_sync(offset, &synclen);
lenread = 0;
eof = false;
while (lenread > 0 || (dataread < datamax && !eof && !feof(fp))) {
size_t to_read = buffer + sizeof(buffer) - p;
do {
int32_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);
dataread += lenread;
fileoffs += lenread;
p += lenread;
eof |= !lenread; /* help along systems with bad feof */
}
if ((nextsync || synclen) && offset == nextsync) {
if (lenread == 0)
eof = true; /* help along systems with bad feof */
} else
lenread = 0;
p += lenread;
if ((nextsync || synclen) &&
(uint32_t)offset == nextsync) {
if (synclen) {
fprintf(stdout, "%08"PRIX64" skipping 0x%"PRIX64" bytes\n",
fprintf(stdout, "%08"PRIX64" skipping 0x%"PRIX32" bytes\n",
offset, synclen);
offset += synclen;
dataread += synclen;
eof |= skip(&fileoffs, synclen, fp);
skip(synclen, fp);
}
q = p = buffer;
nextsync = next_sync(offset, &synclen);
}
while (p > q && (p - q >= INSN_MAX || lenread == 0)) {
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 = disasm(q, INSN_MAX, outbuf, sizeof(outbuf),
bits, offset, autosync, &prefer);
if (!lendis || lendis > (p - q)
|| ((nextsync || synclen) &&
(uint32_t)lendis > nextsync - offset))
lendis = eatbyte(*q, outbuf, sizeof(outbuf), bits);
output_ins(offset, q, lendis, outbuf);
q += lendis;
@ -325,7 +350,7 @@ int main(int argc, char **argv)
p -= (q - buffer);
q = buffer;
}
}
} while (lenread > 0 || !(eof || feof(fp)));
if (fp != stdin)
fclose(fp);
@ -337,8 +362,7 @@ static void output_ins(uint64_t offset, const uint8_t *data,
int datalen, const char *insn)
{
int bytes;
int addrwidth;
addrwidth = fprintf(stdout, "%08"PRIX64" ", offset);
fprintf(stdout, "%08"PRIX64" ", offset);
bytes = 0;
while (datalen > 0 && bytes < bpl) {
@ -347,57 +371,42 @@ static void output_ins(uint64_t offset, const uint8_t *data,
datalen--;
}
fprintf(stdout, "%*s %s\n", (bpl - bytes) << 1, "", insn);
fprintf(stdout, "%*s%s\n", (bpl + 1 - bytes) * 2, "", insn);
while (datalen > 0) {
fprintf(stdout, "%*s", addrwidth, "-");
fprintf(stdout, " -");
bytes = 0;
while (datalen > 0 && bytes < bpl) {
fprintf(stdout, "%02X", *data++);
bytes++;
datalen--;
}
putchar('\n');
fprintf(stdout, "\n");
}
}
/*
* Skip a certain amount of data in a file, either by seeking if
* possible, or if that fails then by reading and discarding.
* Returns true if successful, false on EOF; updates posp.
*/
static bool skip(off_t *posp, off_t dist, FILE *fp)
static void skip(uint32_t dist, FILE * fp)
{
if (!dist)
return true;
char buffer[256]; /* should fit on most stacks :-) */
/*
* Got to be careful with fseek: at least one fseek I've tried
* doesn't approve of SEEK_CUR (WHICH ONE?). Weird...
* doesn't approve of SEEK_CUR. So I'll use SEEK_SET and
* ftell... horrible but apparently necessary.
*/
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;
}
if (fseek(fp, dist + ftell(fp), SEEK_SET)) {
while (dist > 0) {
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 */
uint32_t len = (dist < sizeof(buffer) ?
dist : sizeof(buffer));
if (fread(buffer, 1, len, fp) < len) {
perror("fread");
exit(1);
}
dist -= len;
}
}
return true;
}

View file

@ -1,5 +1,35 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 2025 The NASM Authors - All Rights Reserved */
/* ----------------------------------------------------------------------- *
*
* 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.
*
* ----------------------------------------------------------------------- */
#include "disasm.h"
#include "nasmlib.h"

View file

@ -1,5 +1,35 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2009 The NASM Authors - All Rights Reserved */
/* ----------------------------------------------------------------------- *
*
* 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.
*
* ----------------------------------------------------------------------- */
/*
* sync.c the Netwide Disassembler synchronisation processing module
@ -11,6 +41,9 @@
#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)
@ -21,12 +54,12 @@
static struct Sync {
uint64_t pos;
uint64_t length;
uint32_t length;
} *synx;
static size_t max_synx, nsynx;
static uint32_t max_synx, nsynx;
static inline void swap_sync(size_t dst, size_t src)
static inline void swap_sync(uint32_t dst, uint32_t src)
{
struct Sync t = synx[dst];
synx[dst] = synx[src];
@ -40,35 +73,31 @@ void init_sync(void)
nsynx = 0;
}
void add_sync(uint64_t pos, uint64_t length)
void add_sync(uint64_t pos, uint32_t length)
{
size_t i;
static bool synx_oom = false;
uint32_t i;
if (nsynx >= max_synx) {
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;
if (max_synx >= SYNC_MAX_SIZE) /* too many sync points! */
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 >>= 1) {
if (synx[i >> 1].pos > synx[i].pos)
swap_sync(i >> 1, i);
for (i = nsynx; i > 1; i /= 2) {
if (synx[i / 2].pos > synx[i].pos)
swap_sync(i / 2, i);
}
}
uint64_t next_sync(uint64_t position, uint64_t *length)
uint64_t next_sync(uint64_t position, uint32_t *length)
{
while (nsynx > 0 && synx[1].pos + synx[1].length <= position) {
size_t i, j;
uint32_t i, j;
swap_sync(nsynx, 1);
nsynx--;

View file

@ -1,7 +1,37 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2009 The NASM Authors - All Rights Reserved */
/* ----------------------------------------------------------------------- *
*
* 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.
*
* ----------------------------------------------------------------------- */
/*
/*
* sync.h header file for sync.c
*/
@ -9,7 +39,7 @@
#define NASM_SYNC_H
void init_sync(void);
void add_sync(uint64_t position, uint64_t length);
uint64_t next_sync(uint64_t position, uint64_t *length);
void add_sync(uint64_t position, uint32_t length);
uint64_t next_sync(uint64_t position, uint32_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 \i{MS-DOS} or \i{Windows 3.x}. It
when writing 16-bit code to run under \c{MS-DOS} or \c{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,3 +835,5 @@ 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{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
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
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. Specifically,
the stack pointer (\c{RSP}) needs to be 16-byte aligned just before the
\c{CALL} instruction.
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.
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 defining them as macros; similarly,
possible to use those names by definiting them as macros; similarly,
if one wants to use numeric names for the low 8 registers, define them
as macros. The standard macro package \c{altreg} (see \k{pkg_altreg})
can be used for this purpose.
@ -62,8 +62,6 @@ 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
@ -97,9 +95,7 @@ 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).
\S{id64disp} 64-bit Displacements
within 2 GB of the instruction itself (see below.)
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},
@ -186,16 +182,3 @@ 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,31 +1,20 @@
# -*- makefile -*-
# SPDX-License-Identifier: BSD-2-Clause
# Copyright 1996-20xx The NASM Authors - All Rights Reserved
#
# UNIX Makefile for NASM documentation
#
PACKAGE_NAME = @PACKAGE_NAME@
PACKAGE_TARNAME = @PACKAGE_TARNAME@
@SET_MAKE@
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@
@ -63,9 +52,6 @@ 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:
@ -84,17 +70,14 @@ 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_F) "$(srcdir)/$$f" html/; done
$(MAKE) $(htmltarget)
for f in $(HTMLAUX); do $(CP_UF) "$(srcdir)/$$f" html/; done
$(MAKE) html/nasmdoc0.html
RDSRC = $(RUNPERL) $(srcdir)/rdsrc.pl -I$(srcdir) -M$(@F).dep
$(htmltarget): $(ALLSRCS) rdsrc.pl
html/nasmdoc0.html: $(ALLSRCS) rdsrc.pl
$(RM_F) html/*.html
$(RDSRC) -ohtml html $<
@ -135,28 +118,20 @@ nasmdoc.pdf.xz: nasmdoc-raw.pdf
$(XZ) -9e < $< > $@
clean:
-$(RM_F) *.rtf *.hpj *.texi *.gid *.ipf *.dip *.dep
-$(RM_F) *.rtf *.hpj *.texi *.gid *.ipf *.dip
-$(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_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
install: all
$(MKDIR_P) $(DESTDIR)$(htmldir)
$(INSTALL_DATA) html/* $(DESTDIR)$(htmldir)
$(MKDIR_P) $(DESTDIR)$(docdir)
$(INSTALL_DATA) nasmdoc.pdf nasmdoc.txt $(DESTDIR)$(docdir)
#
# Dummy rules that changes make behavior

View file

@ -15,5 +15,6 @@ 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 Google Roboto and Roboto Mono fonts,
available for free at: https://github.com/googlefonts/
6. For best results, the Adobe fonts Source Sans Pro and Source Code
Pro, available for free at:
https://github.com/adobe-fonts

View file

@ -1,6 +1,36 @@
#!/usr/bin/perl
# SPDX-License-Identifier: BSD-2-Clause
# Copyright 1996-2017 The NASM Authors - All Rights Reserved
## --------------------------------------------------------------------------
##
## 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.
##
## --------------------------------------------------------------------------
#
# Parse AFM metric file, returns a reference to fontdata

View file

@ -10,195 +10,6 @@ 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}).
@ -256,28 +67,6 @@ 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
@ -2928,7 +2717,7 @@ an error.
specification warning when sizes agree).
\H{cl-0.9x} NASM 0.90-0.97
\H{cl-0.9x} NASM 0.9 Series
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,38 +402,26 @@ global variables).
Unlike \c{GLOBAL}, \c{STATIC} does not allow object formats to accept
private extensions mentioned in \k{global}.
\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]}
\H{mangling} \i\c{(G|L)PREFIX}, \i\c{(G|L)POSTFIX}: Mangling Symbols
\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
\c{PREFIX}, \c{GPREFIX}, \c{LPREFIX}, \c{POSTFIX}, \c{GPOSTFIX}, and
\c{LPOSTFIX} 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{[SUFFIX]}, \c{[GSUFFIX]}, \c{[POSTFIX]}, \c{[GPOSTFIX]}: Append
the argument to all \c{EXTERN}, \c{COMMON}, \c{STATIC}, and
\c{GLOBAL} symbols.
\b\c{POSTFIX}|\c{GPOSTFIX}: Append the argument to all \c{EXTERN},
\c{COMMON}, \c{STATIC}, and \c{GLOBAL} symbols.
\b\c{[LSUFFIX]}, \c{[LPOSTFIX]}: Append the argument to all other symbols
\b\c{LPOSTFIX}: Append the argument to all other symbols
such as local labels and backend defined symbols.
These directives are also implemented as pragmas, and using
\c{%pragma} syntax can be restricted to specific backends (see
\k{pragma}):
These are macros implemented as pragmas, and using \c{%pragma} syntax
can be restricted to specific backends (see \k{pragma}):
\c %pragma macho lprefix L_
@ -455,19 +443,13 @@ 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
@ -567,8 +549,6 @@ 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
@ -592,7 +572,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 bracketed primitive form, (\c{[FLOAT]}).
has avoided the use of the brackeded 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.
@ -622,15 +602,3 @@ 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,6 +1,36 @@
#!/usr/bin/perl
# SPDX-License-Identifier: BSD-2-Clause
# Copyright 1996-2017 The NASM Authors - All Rights Reserved
## --------------------------------------------------------------------------
##
## 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.
##
## --------------------------------------------------------------------------
#
# Try our best to find a specific PostScipt font in the system.
@ -41,7 +71,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,6 +1,36 @@
#!/usr/bin/perl
# SPDX-License-Identifier: BSD-2-Clause
# Copyright 1996-2020 The NASM Authors - All Rights Reserved
## --------------------------------------------------------------------------
##
## 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.
##
## --------------------------------------------------------------------------
#
# Format the documentation as PostScript

View file

@ -26,9 +26,8 @@
\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
@ -116,7 +115,8 @@
\IA{case-insensitive}{case sensitive}
\IA{character constants}{character constant}
\IR{codeview debugging format} CodeView debugging format
\IR{continuation} continuation line
\IR{continuation line} continuation line
\IC{continuation line}{preprocessor, 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,7 +124,6 @@
\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
@ -195,8 +194,6 @@
\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}
@ -254,14 +251,10 @@
\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
\IR{uninitialized} uninitialized storage
\IA{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
@ -294,24 +287,8 @@
\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,6 +1,36 @@
#!/usr/bin/perl
# SPDX-License-Identifier: BSD-2-Clause
# Copyright 1996-2024 The NASM Authors - All Rights Reserved
## --------------------------------------------------------------------------
##
## 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.
##
## --------------------------------------------------------------------------
#
# inslist.pl produce inslist.src

View file

@ -93,10 +93,11 @@ 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{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{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.
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,
@ -131,7 +132,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
@ -370,9 +371,24 @@ 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 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}.
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
When broadcasting decorator is used, the opsize keyword should match
the size of each element.
@ -394,7 +410,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.)
@ -436,12 +452,13 @@ 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 in
backquotes (\c{`...`}). Single or double quotes are equivalent to
NASM (except of course that surrounding the constant with single
quotes allows double quotes to appear within it and vice versa); the
contents of those are represented verbatim. Strings enclosed in
backquotes support C-style \c{\\}-escapes for special characters.
The following \i{escape sequences} are recognized by backquoted strings:
\c \' single quote (')
@ -462,24 +479,6 @@ 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.
@ -488,8 +487,6 @@ 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
@ -516,7 +513,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
@ -539,14 +536,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
little endian.
littleendian.
For example:
@ -710,13 +707,13 @@ characters.
\S{expbor}: \i\c{||}: \i{Boolean OR} Operator
The \c{||} operator gives a boolean OR: it evaluates to 1 if either side of
the expression is nonzero, otherwise 0.
The \c{||} operator gives a boolean OR: it evaluates to 1 if both sides of
the expression are nonzero, otherwise 0.
\S{expbxor}: \i\c{^^}: \i{Boolean XOR} Operator
The \c{^^} operator gives a boolean XOR: it evaluates to 1 if exactly one side of
The \c{^^} operator gives a boolean XOR: it evaluates to 1 if any one side of
the expression is nonzero, otherwise 0.
@ -864,12 +861,30 @@ 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}.
The \c{WRT} keyword is also used in far (inter-segment) calls and jumps. It's
synonymous to the
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
\c call far procedure
\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.
syntax which is documented in \k{farcall}.
\H{strict} \i\c{STRICT}: Inhibiting Optimization
@ -992,7 +1007,6 @@ 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}),
\c{..symtab} is used to emit the COFF symbol table index (see \k{win32wrt}).
of the current image in the \c{win64} output format (see \k{win64pic}).
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{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{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{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} and \k{egprs}.
See also \k{reg64}.
\H{pkg_smartalign} \i\c{smartalign}\I{align, smart}: Smart \c{ALIGN} Macro
The \c{smartalign} standard macro package provides an \i\c{ALIGN}
The \c{smartalign} standard macro package provides for 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 \i\c{FLAT} and \i\c{OFFSET} keywords are recognized and ignored.
\b The \c{FLAT} and \c{OFFSET} keywords are recognized and ignored.
\b The \i\c{PTR} keyword signifies a memory reference, as if the
\b The \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,dword ptr flat:foo ; memory reference
\c mov eax,dowrd ptr flat:foo ; memory reference
\c mov eax,offset foo ; address
\c mov eax,foo ; address (ambiguous syntax in MASM)
\b The \i\c{SEGMENT} ... \i\c{ENDS} syntax:
\b The \c{SEGMENT} ... \c{ENDS} syntax:
\c segname SEGMENT
\c ...
\c segname ENDS
\b The \i\c{PROC} ... \i\c{ENDP} syntax:
\b The \c{PROC} ... \c{ENDP} syntax:
\c procname PROC [FAR]
\c ...
@ -171,16 +171,13 @@ 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 \i\c{TBYTE} keyword as an alias for \c{TWORD} (see \k{qsother}).
\b The \c{TBYTE} keyword as an alias for \c{TWORD} (see \k{qsother}).
\b The \i\c{END} directive is ignored.
\b The \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:
@ -196,9 +193,3 @@ 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,174 +1,119 @@
body {
font-family: "roboto", "source sans pro", "clear sans", "liberation sans",
font-family: "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: 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;
font-size: 2em;
margin: 0;
}
span.subtitle {
font-size: 1.25em;
font-style: italic;
}
code, pre {
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;
font-family: "source code pro", "liberation mono", "monospace";
font-size: 80%;
}
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;
}
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;
li.toc1 {
padding-top: 0.7em;
font-weight: bold;
}
ol.toc2 > li {
li.toc2 {
padding-top: 0.3em;
}
ol.toc2 li {
padding-left: 0.4em;
font-weight: normal;
}
div.toc span.node {
display: none;
}
div.index li {
.index li {
list-style-type: none;
display: flex;
flex-direction: row;
justify-content: space-between;
}
div.index .term {
.index .term {
display: inline-block;
text-align: left;
vertical-align: top;
flex: 3 3 0;
}
div.index .ref {
.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 */
nav {
ul.navbar {
display: none;
}
@media print {
a {
color: inherit;
}
nav {
ul.navbar div.title {
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;
}
div.toc, div.chapter, div.appendix {
-webkit-column-gap: 4em;
-moz-column-gap: 4em;
column-gap: 4em;
}
@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.index {
-webkit-column-gap: 1em;
-moz-column-gap: 1em;
column-gap: 1em;
}
@media only screen and (min-width: 135em) {
div.contents {
-webkit-column-count: 3;
-moz-column-count: 3;
column-count: 3;
}
}
@media screen {
/* Setting an explicit margin to keep the navbar from moving */
body {
padding: 0;
@ -198,53 +143,39 @@ nav {
background-clip: content-box;
}
nav {
ul.navbar {
display: block;
position: sticky;
top: 8px;
width: 100%;
margin: 0;
padding: 0;
overflow: hidden;
background: #336 url("nasmlogw.png") no-repeat right center;
background-size: contain;
float: left;
white-space: collapse;
}
nav ul {
margin: 0;
padding: 0;
display: inline-block;
white-space: nowrap;
list-style-type: none;
background: #336 url("nasmlogw.png") no-repeat right center;
background-size: contain;
}
nav li {
margin: 0;
padding: 0;
display: inline-block;
ul.navbar li {
float: left;
}
nav li a {
margin: 0;
ul.navbar li.last {
border-right: none;
}
ul.navbar a {
border-right: 1px solid #bbb;
display: block;
text-align: center;
padding: 0.75em 0.75em;
text-decoration: none;
color: white;
white-space: nowrap;
background-color: #336;
text-align: center;
padding: 1em 1.5em;
text-decoration: none;
}
nav li.navthis a {
background-color: #55c;
}
nav li a:hover {
ul.navbar a:hover {
background-color: #448;
}
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 {
.index li:hover {
background: #eef;
}
}

View file

@ -1,9 +1,36 @@
\# 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
\#
@ -39,8 +66,6 @@ source.}
\& lang.src
\& syntax.src
\& preproc.src
\& stdmac.src
@ -67,22 +92,12 @@ source.}
\& ndisasm.src
\# --- 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
\# Keep the changelog as Appendix C if at all possible, otherwise
\# the website machinery needs to be changed.
\& 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 DOS \c{.EXE} files like \c{debug} will. It just
not understand \c{DOS .EXE} files like \c{debug} will. It just
disassembles.
\H{ndisrun} \I{options, disassembler}Running NDISASM
\H{ndisrun} 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 \c{-b} switch is present, NDISASM works in 16-bit mode
by default. The \c{-u} switch (for USE32) also invokes 32-bit mode.
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.
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
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
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 \c{-o} option allows you to declare a different origin for the
The \i\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 \c{-s} option: they are measured
Sync points are specified using the \i\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 \c{-a} (for automatic sync) or \c{-i} (for intelligent
switches \i\c{-a} (for automatic sync) or \i\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,14 +153,16 @@ suppress disassembly of the data area.
\S{ndisother} Other Options
The \c{-e} option skips a header on the file, by ignoring the first N
The \i\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 \c{-k} option is provided with two comma-separated numeric
The \i\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,9 +109,8 @@ with \i\c{vstart=}.
start address.
\b Arguments to \c{org}, \c{start}, \c{vstart}, and \c{align=} are
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.
critical expressions. See \k{crit}. E.g. \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.
@ -180,7 +179,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
@ -327,10 +326,6 @@ 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
@ -515,41 +510,6 @@ 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,
@ -645,14 +605,13 @@ 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 onlyif the related code
\c ; (FirstFnc) is linked
\c ... ; Data linked only if the related code (FirstFnc) is linked
\c
The defaults assumed by NASM if you do not specify the above
@ -672,42 +631,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 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
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
\c{/safeseh} command line option.
Without regard to this run-time check, it's natural to expect
Without regard to this run-time check merits it's natural to expect
NASM to be capable of generating modules suitable for \c{/safeseh}
linking. From the developer's viewpoint the problem is two-fold:
linking. From 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;
The former can be easily achieved with any NASM version by adding the
following line to the source code:
Former can be easily achieved with any NASM version by adding following
line to source code:
\c $@feat.00 equ 1
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).
As of version 2.03 NASM adds this absolute symbol automatically. If
it's not already present to be precise. I.e. if for whatever reason
developer would choose to assign another value in source file, it would
still be perfectly possible.
Registering 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
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
table." Its typical use would be:
\c section .text
@ -740,18 +699,19 @@ 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 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.
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.
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
@ -759,33 +719,6 @@ 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}
@ -816,7 +749,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 the linker will refuse to link it, showing:
is not 64-bit savvy. Most notably linker will refuse to link it with
\c 'ADDR32' relocation to '.text' invalid without /LARGEADDRESSAWARE:NO
@ -825,15 +758,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 scenes is that the effective address in \c{lea}
is encoded relative to instruction pointer, in a perfectly
What happens behind the scene is that effective address in \c{lea} is
encoded relative to instruction pointer, or in perfectly
position-independent manner. But this is only part of the problem!
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:
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:
\c lea rbx,[rel dsptch]
\c add rbx,[rbx+rax*8]
@ -844,11 +777,11 @@ But not to worry, it's trivial to fix:
\c ...
NASM version 2.03 and later provides another alternative, \c{wrt
..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:
..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:
\c lea rbx,[rel dsptch]
\c mov eax,[rbx+rax*4]
@ -859,10 +792,10 @@ statement with these image-relative references:
\c dsptch: dd case0 wrt ..imagebase
\c dd case1 wrt ..imagebase
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.
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.
It should be noted that \c{wrt ..imagebase} is defined as 32-bit
operand only:
@ -874,61 +807,65 @@ operand only:
\S{win64seh} \c{win64}: Structured Exception Handling
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
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
top of the stack.
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).
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.
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.
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.
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:
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:
\c default rel
\c section .text
@ -963,36 +900,36 @@ showing how to deploy a custom exception handler for a leaf function:
\c section .drectve info
\c db '/defaultlib:user32.lib /defaultlib:msvcrt.lib '
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.
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.
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:
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:
\c function:
\c mov rax,rsp ; copy rsp to volatile register
@ -1014,11 +951,11 @@ unwinding procedure. Consider the following example:
\c mov rsp,r11 ; destroy frame
\c ret
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:
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:
\c EXCEPTION_DISPOSITION handler (EXCEPTION_RECORD *rec,ULONG64 frame,
\c CONTEXT *context,DISPATCHER_CONTEXT *disp)
@ -1040,9 +977,9 @@ language-specific exception handler would look like this:
\c return ExceptionContinueSearch;
\c }
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.
As custom handler mimics leaf function, corresponding \c{UNWIND_INFO}
structure does not have to contain any information about stack frame
and its layout.
\H{cofffmt} \i\c{coff}: \i{Common Object File Format}
@ -1159,38 +1096,6 @@ 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
@ -1282,8 +1187,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-terminated strings
(with the \c{strings} attribute). A size specifier is required unless
elements can be either fixed-sized objects or null-terminatedstrings
(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
@ -1442,15 +1347,6 @@ 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,31 +146,6 @@ 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
@ -210,13 +185,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 case sensitive: after
Macros defined with \c{%define} are \i{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}. See however \k{ppcase}.
\c{bar}.
There is a mechanism which detects when a macro call has occurred as
a result of a previous expansion of the same macro, to guard against
@ -316,7 +291,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 case-insensitive counterpart \c{%ixdefine}.
it's \I{case sensitive}case-insensitive counterpart \c{%ixdefine}.
Suppose you have the following code:
@ -511,7 +486,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 case-insensitive
\c{%assign} command (and its \I{case sensitive}case-insensitive
counterpart \i\c{%iassign}, which differs from \c{%assign} in
exactly the same way that \c{%idefine} differs from \c{%define}).
@ -637,8 +612,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 single-line macro to some
value (either a string or a numeric value). When producing a string
All the string operators define or redefine a value (either a string
or a numeric value) to a single-line macro. When producing a string
value, it may change the style of quoting of the input string or
strings, and possibly use \c{\\}-escapes inside \c{`}-quoted strings.
@ -705,7 +680,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
@ -784,7 +759,7 @@ treats an empty argument list as a single empty argument.
\S{f_depend} \i\c\{%depend()} Function
The \c{%depend()} function takes a quoted string as argument, adds it
he \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.
@ -794,31 +769,6 @@ 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
@ -843,7 +793,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; see however \k{ppcase}.
insensitively.
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
@ -913,45 +863,6 @@ 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
@ -1100,24 +1011,6 @@ 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,
@ -1576,7 +1469,7 @@ iterated through in reverse order.
\S{concat} \i{Concatenating Macro Parameters}
NASM can concatenate macro parameters and macro indirection constructs
with other surrounding text. This allows you to declare a family
on to other text surrounding them. This allows you to declare a family
of symbols, for example, in a macro definition. If, for example, you
wanted to generate a table of key codes along with offsets into the
table, you could code something like
@ -1666,7 +1559,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
@ -1881,8 +1774,7 @@ 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 case-insensitive; see
however \k{ppcase}.
\c{%ifidni} is similar to \c{%ifidn}, but is \i{case-insensitive}.
For example, the following macro pushes a register or number on the
stack, and allows you to treat \c{IP} as a real register:
@ -2066,14 +1958,12 @@ 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} construct exists.
the \c{%!}\e{variable} directive exists.
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
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
identifier. See \k{getenv}.
See also the the \c{%env()} function (\k{f_env}).
\S{if_caveat} Backwards Compatibility Caveat
@ -2265,8 +2155,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{UNTIL} macro
would need to be able to refer to a label which the \c{REPEAT} macro
\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
had defined. However, for such a macro you would also want to be
able to nest these loops.
@ -2290,7 +2180,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
@ -2322,9 +2212,9 @@ above could be implemented by means of:
and invoked by means of, for example,
\c mov di,string
\c mov cx,string
\c repeat
\c add di,3
\c add cx,3
\c scasb
\c until e
@ -2462,7 +2352,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 an \c{%error} if they're
calling \c{endif} before \c{if}) and issues a \c{%error} if they're
not.
In addition, the \c{endif} macro has to be able to cope with the two
@ -2812,9 +2702,6 @@ 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,14 +23,13 @@ sub font {
return map { /^(.*?)-*$/; $1 } @f;
}
my $text = ['Roboto', 'SourceSans', 'SourceSans3',
my $text = ['SourceSans', 'SourceSans3',
'SourceSansPro', 'SourceSansPro3',
'LiberationSans', 'Arial', 'Helvetica'];
my $code = ['RobotoMono', 'SourceCodePro', 'LiberationMono', 'Courier'];
my $code = ['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);
@ -38,10 +37,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, $bold);
my @HCode = font($code, $semi);
my @BText = font($text, $regular);
my @BItal = font($text, $italic);
my @BCode = font($code, $medium);
my @BCode = font($code, $regular);
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->catfile($p, $exe);
my $e = File::Spec->catpath($p, $exe);
$gsp = $e if (-f $e && -x _);
}
}

View file

@ -1,6 +1,36 @@
#!/usr/bin/perl
# SPDX-License-Identifier: BSD-2-Clause
# Copyright 1996-2025 The NASM Authors - All Rights Reserved
## --------------------------------------------------------------------------
##
## 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.
##
## --------------------------------------------------------------------------
# Read the source-form of the NASM manual and generate the various
@ -177,7 +207,7 @@ if ($out_format eq 'txt') {
print "$outfile: producing text output...\n";
&write_txt;
} elsif ($out_format eq 'html') {
$outfile = 'nasm00.html';
$outfile = 'nasmdoc0.html';
print "$outfile: producing HTML output...\n";
&write_html;
} elsif ($out_format eq 'dip') {
@ -837,183 +867,68 @@ sub word_txt {
sub html_filename($) {
my($node) = @_;
$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();
(my $number = lc($xrefnodes{$node})) =~ s/.*-//;
my $fname="nasmdocx.html";
substr($fname,8 - length $number, length $number) = $number;
return $fname;
}
sub write_html {
# Create the navbar list
html_navbar_generate();
# This is called from the top level, so I won't bother using
# my or local.
# 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...";
html_preamble('contents');
print "<h2>Table of Contents</h2>\n";
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";
$level = 0;
$ollevel = 0;
sub toc_close_tags($) {
my($plevel) = @_;
while ($plevel < $level) {
print "</li>\n";
if ($level-- <= $ollevel) {
print "</ol>\n";
$ollevel--;
}
}
}
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;
my $lastlevel = $level;
while ($tstruct_level{$node} < $level) {
print "</li>\n</ol>\n";
$level--;
}
while ($plevel > $level) {
$level++;
my $cclass = ($level == 1) ? " $ctype" : '';
print "<ol class=\"toc${level}${cclass}\"", ">\n";
$ollevel = $level;
while ($tstruct_level{$node} > $level) {
print "<ol class=\"toc", ++$level, "\">\n";
}
if ($lastlevel >= $level) {
print "</li>\n";
}
$level = $tstruct_level{$node};
if ($level == 1) {
$link = $fname = html_filename($node);
} else {
# Use the preceding filename plus a marker point.
$link = $fname . "#$xrefnodes{$node}";
}
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;
$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";
}
toc_close_tags(0);
html_postamble();
while ($level--) {
print "</li>\n</ol>\n";
}
print "</div>\n";
print "</body>\n";
print "</html>\n";
select STDOUT;
close TEXT;
# 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;
open TEXT, '>', File::Spec->devnull();
select TEXT;
undef $html_nav_last;
undef $html_nav_next;
$in_list = 0;
$in_bquo = 0;
@ -1030,27 +945,46 @@ sub write_html {
$endtag = '';
if ($ptype eq 'chap' || $ptype eq 'appn') {
# Chapter/appendix heading. Begin a new file.
$pflags =~ /^\w+ (.*) :(.*)/;
if ($ptype eq "chap") {
# Chapter heading. Begin a new file.
$pflags =~ /chap (.*) :(.*)/;
$title = "Chapter $1: ";
$xref = $2;
$title = "$2 $1:&ensp;";
$title =~ s/-\S+//;
$title =~ s/^(.)/\U$1/;
html_postamble();
&html_postamble; select STDOUT; close TEXT;
$html_nav_last = $chapternode;
$chapternode = $nodexrefs{$xref};
html_preamble($chapternode);
$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";
$ww = &word_html($i);
$title .= $ww unless $ww eq "\001";
}
$h = "<h2 id=\"$xref\">$title</h2>\n";
print $h;
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";
} elsif ($ptype eq "head" || $ptype eq "subh") {
# Heading or subheading.
$pflags =~ /.... (.*) :(.*)/;
$hdr = ($ptype eq "subh" ? "h4" : "h3");
$title = $1 . ".&ensp;";
$title = $1 . " ";
$xref = $2;
foreach $i (@$pname) {
$ww = &word_html($i);
@ -1125,14 +1059,59 @@ 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();
&html_postamble; select STDOUT; close TEXT;
print "\n writing index file...";
html_preamble('index');
print "<h2>Index</h2>\n";
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_index;
html_postamble();
print "</div>\n\n</body>\n</html>\n";
select STDOUT;
close TEXT;
}
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,89 +102,41 @@ sections of interest, avoiding excessively long listings.
Use this option to specify listing output details.
\c{-L} options for general use are:
Supported options are:
\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{-Lb} show builtin macro packages (standard and \c{%use})
\b \c{-Ld} show byte and repeat counts in decimal, not hex
\b \c{-Le} show the preprocessed output
\b \c{-Le} show the preprocessed input
\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{-Lf} ignore \c{.nolist} and force listing output
\b \c{-Lm} show multi-line macro calls with expanded parameters
\b \c{-Lp} output a list file every pass, in case of errors
\b \c{-Lp} output a list file in every pass, in case of errors
\b \c{-Ls} show all single-line macro definitions
\b \c{-Lt} list the full output from \c{TIMES} and \c{ALIGN}
directives
\b \c{-Lw} flush the output after every line (very slow, mainly useful
to debug NASM crashes)
\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.
\b \c{-L+} enable \e{all} listing options except \c{-Lw} (very verbose)
These options can be enabled or disabled at runtime using the
\c{%pragma list options} directive:
\c %pragma list options [+|-|*]{!|flags}...
\c{+}, \c{-} and \c{*} adds, removes, or restores to the command-line
default the flags that follow.
\c %pragma list options [+|-]flags...
For example, to turn on the \c{d} and \c{m} flags but disable the
\c{s} flag:
\c %pragma list options +dm -s
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 *!
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.
\S{opt-M} The \i\c{-M} Option: Generate \i{Makefile Dependencies}
@ -318,7 +270,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{MS-DOS} it can be difficult (though there are ways) to
Under \I{DOS}\c{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
@ -338,7 +290,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{MS-DOS}. To
than \c{stderr}, so it can be redirected under \I{DOS}\c{MS-DOS}. To
assemble the file \c{myfile.asm} and pipe its output to the \c{more}
program, you can type:
@ -561,9 +513,6 @@ 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,
@ -575,45 +524,23 @@ For command-line compatibility with Yasm, the form \i\c{--v} is also
accepted for this option starting in NASM version 2.11.05.
\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
\S{opt-pfix} The \i\c{--(g|l)prefix}, \i\c{--(g|l)postfix} Options.
\S{opt-pfix} The \I{--prefix}\c{--[gl]prefix} and \c{--[gl]postfix} Options
The \c{--gprefix} option prepends the given argument
The \c{--(g)prefix} options prepend 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{--gpostfix} and \c{--lpostfix} options append
the argument, in a manner similar to the \c{--[gl]prefix} options.
\c{--(g)postfix} and \c{--lpostfix} options append
the argument in the exactly same way as the \c{--xxprefix} options does.
Running this:
\c nasm -f macho --gprefix _
is equivalent to placing the directive \c{%pragma macho gprefix _}
is equivalent to place the directive with \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
@ -625,39 +552,20 @@ 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
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:
A preprocess statement can be accepted with this option. The example
shown in \k{opt-pragma} is the same as running this:
\c nasm -f macho --before "%pragma macho gprefix _"
\IR{--bits} \c{--bits} option
\S{opt-limit} The \i\c{--limit-X} Option
\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
This option 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,
\c{unlimited}, \c{maximum}, or \c{default}.
amount of compute time. Each limit can be set to a positive number or
\c{unlimited}.
\b\c{--limit-passes}: Number of maximum allowed passes. Default is
\c{unlimited}.
@ -677,15 +585,12 @@ 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 maximum allowed
\b\c{--limit-eval}: This number sets the boundary condition of 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
@ -695,31 +600,18 @@ 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
@ -876,10 +768,14 @@ 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'. As of NASM 2.15, the MASM syntax is also supported.
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.
In addition to all of this, macros and directives work completely
differently to MASM. See \k{preproc} and \k{directive} for further
@ -887,5 +783,4 @@ details.
\S{masm-compat} MASM compatibility package
The MASM compatibility macro package can be used to improve MASM
compatibility. See \k{pkg_masm}.
See \k{pkg_masm}.

View file

@ -12,10 +12,7 @@ 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. 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.
MSYS2 (\w{https://www.msys2.org/}) is such a development environment.
In a POSIX environment, run:
@ -26,16 +23,15 @@ 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 a handful of other
For non-POSIX environments, a set of Makefiles for some other
environments are also available; please see the file
\c{Mkfiles/README}. These makefiles are generally considered
unreliable, as we have very little ability to test them.
\c{Mkfiles/README}.
The \c{.zip} version of the source archive has DOS/Windows line
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}).
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}).
\H{buildtools} Optional Build Tools
@ -68,9 +64,9 @@ To build the documentation:
\b Either Ghostscript (\w{https://www.ghostscript.com/}) or Adobe
Acrobat Distiller (untested.)
\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}).
\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/}).
To build the Unix man pages:
@ -138,3 +134,14 @@ 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 generate exactly the same code, the second
Note that the above lines are generate exactly the same code, the second
line is used just to give an indication of the order that the separate
values will be present in memory.
@ -184,20 +184,6 @@ 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
@ -227,20 +213,6 @@ 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,

View file

@ -1,434 +0,0 @@
\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.

View file

@ -1,168 +0,0 @@
;;; 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?__

View file

@ -1,21 +0,0 @@
#!/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"

View file

@ -1,423 +0,0 @@
#!/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);

33
headers/c Normal file
View file

@ -0,0 +1,33 @@
/* ----------------------------------------------------------------------- *
*
* 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.
*
* ----------------------------------------------------------------------- */

33
headers/doc Normal file
View file

@ -0,0 +1,33 @@
\# --------------------------------------------------------------------------
\#
\# 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.
\#
\# --------------------------------------------------------------------------

33
headers/mac Normal file
View file

@ -0,0 +1,33 @@
;; --------------------------------------------------------------------------
;;
;; 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.
;;
;; --------------------------------------------------------------------------

33
headers/perl Normal file
View file

@ -0,0 +1,33 @@
## --------------------------------------------------------------------------
##
## 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,5 +1,35 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 1996-2025 The NASM Authors - All Rights Reserved */
/* ----------------------------------------------------------------------- *
*
* 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.
*
* ----------------------------------------------------------------------- */
/*
* bytesex.h - byte order helper functions
@ -215,7 +245,7 @@ struct unaligned32 {
} __attribute__((packed));
static inline uint32_t getu32(const void *p)
{
return le32toh(((const struct unaligned32 *)p)->v);
return l32toh(((const struct unaligned32 *)p)->v);
}
static inline uint32_t setu32(void *p, uint32_t v)
{
@ -253,7 +283,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 le32toh(*pp);
return l32toh(*pp);
}
static inline uint32_t setu32(void *p, uint32_t v)
{

View file

@ -1,5 +1,35 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 2007-2025 The NASM Authors - All Rights Reserved */
/* ----------------------------------------------------------------------- *
*
* 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.
*
* ----------------------------------------------------------------------- */
/*
* compiler.h
@ -69,30 +99,6 @@
# 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>
@ -177,10 +183,23 @@ 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
@ -188,10 +207,14 @@ size_t strlcpy(char *, const char *, size_t);
# 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 explicit construct !!x instead of relying on
implicit conversions or casts. */
Instead, use the bool() constructor-style macro defined below. */
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
@ -303,18 +326,12 @@ 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.
*/
#ifdef HAVE___BUILTIN_EXPECT
# define likely(x) __builtin_expect(!!(x), true)
# define unlikely(x) __builtin_expect(!!(x), false)
#if HAVE___BUILTIN_EXPECT
# define likely(x) __builtin_expect(bool(x), true)
# define unlikely(x) __builtin_expect(bool(x), false)
#else
# 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))
# define likely(x) bool(x)
# define unlikely(x) bool(x)
#endif
/*
@ -465,15 +482,4 @@ 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,5 +1,35 @@
/* SPDX-License-Identifier: BSD-2-Clause */
/* Copyright 2020 The NASM Authors - All Rights Reserved */
/* ----------------------------------------------------------------------- *
*
* 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.
*
* ----------------------------------------------------------------------- */
/*
* dbginfo.h - debugging info structures

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