lpsantil / mininasm

NASM-compatible mini assembler for 8086, 186 and 286, able to run on DOS and on modern systems

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

mininasm: NASM-compatible mini assembler for 8086, 186 and 286, able to run
on DOS and on modern systems
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
mininasm is a minimalistic NASM-compatible assembler targeting the Intel
8086 (and 8088 and 186 and 286). It's implemented in C, and it can be
compiled to DOS (8086 instructions only) and to modern systems. It aims to
be an extremely lightweight, compatible, drop-in replacement of NASM (for
the subset of NASM syntax it supports), so that it runs on an 1983 IBM PC
running PC DOS 2.0, enabling software development without cross-compilation.

Most modern assembly developers targeting the 8086, 186 or 286 should choose
NASM rather than mininasm, as long as NASM works for them and it runs on their
host system. That's because NASM provides more abstractions (e.g. macros and
more preprocessor), output file formats and assembly instructions, and it's
faster. The reasons why mininasm may be chosen instead of NASM:

* mininasm uses much less memory in all categories: constant, per-label,
  per-macro. mininasm memory usage doesn't depend on the size of the
  output file. If there is >= 2 MiB memory free, then NASM is good enough
  for most uses. mininasm can already work with 64 KiB of free conventional
  memory on DOS (the size of mininasm.com included).
* mininasm behavior is documented and deterministic even when NASM isn't,
  e.g. signed integer division, `align' if the alignment is not a power of 2.
* mininasm is easier to compile than NASM: any standard C compiler (C89 or
  later) can compile it, and it works even with 16-bit ints.
* mininasm aims to generate binary output files identical to NASM 0.98.39
  (released on 2005-01-20) with the default settings (`-O0'), also with
  `-O999'. Thus there will be no surprises when compiling the same source file
  decades later. Upgrading NASM instead may change the output file, and it
  happened many times in the past.

mininasm is released as C (C89 or later) source (mininasm.c,
bbprintf.c, bbprintf.h, see compilation instructions near the beginning of
mininasm.c) on https://github.com/pts/mininasm and there are also
binary releases for DOS 8086, Linux i386 (also runs on Linux amd64) and
Win32, on https://github.com/pts/mininasm/releases . The minimalism of
mininasm is reflected in the size of the released executable programs: about
21 KiB each, while the corresponding NASM 0.98.39 would be more than
260 KiB.

For a case study and step-by-step examples of converting NASM source code to
mininasm, see the commit history of https://github.com/pts/insight-mininasm .
It converts the NASM source code of Insight real-mode DOS 16-bit debugger,
version 1.24 so that it works with both NASM 0.98.39 and mininasm, and the
output program file insight.com (32935 bytes) of both is identical to the
one in the official Insight binary release, achieving full reporoducibility.

mininasm (as well as NASM with `bits 16') can be used to develop for these kind
of targets conveniently:

* DOS 16-bit .com programs (this is the most convenient, because there are
  no file headers and no relocations)
* DOS 16-bit .exe programs with the memory model small or compact
* DOS 16-bit .sys device drivers
* Win16 (Windows 16-bit, e.g. Windows 3.x) .exe programs
* Win16 (Windows 16-bit, e.g. Windows 3.x) .dll libraries
* OS/2 1.x 16-bit .exe programs
* 16-bit x86 boot sector and master boot record (MBR) programs
* ELKS 8086 16-bit programs
* Minix 1.x and 2.x 8086 16-bit programs
* Coherent 3.x 8086 16-bit programs
* Xenix 86 2.x 8086 16-bit programs (Xenix 286 3.x can also run them)
* PC/IX 1.0 8086 16-bit programs
* Venix/86 2.1 8086 16-bit programs
* CP/M-86 16-bit programs
* disk images (which are mostly empty, except for some headers)

Please note that mininasm doesn't contain a linker, it doesn't work with
extenal linkers, and it can't reorder sections in its binary output. This
means that in the assembly source file the sections must be written in this
order: file headers (with `db' and `dw' instructions), code (.text), data
(.data), uninitialized data (.bss).

Similarities between mininasm and NASM:

* mininasm implements a small subset of NASM (with a few extras), trying
  to be compatible with NASM 0.98.39 (released on 2005-01-20, the last NASM
  with 32-bit integers, newer releases had 64-bit integers), rather than
  the most recent NASM. The goal is that the same assembly source code should
  work identically (generating identical binary output) with mininasm and
  NASM, provided that mininasm supports all the NASM features used.

* `bits 16' and `use16' are supported.

* `cpu 8086', `cpu 186', `cpu 286' are supported.

* All 8086 and 186 instructions (including prefixes) and opcodes are
  supported, except for floating point. All 286 instructions and opcodes
  are supported, except for protected mode and floating point.
  Instructions with multiple binary encodings are encoded identically as
  NASM 0.98.39 at the same optimization level (`-O0' or `-O999').

* Binary output (`-f bin' command-line flag) is supported.

* Local labels (starting with a period `.') are supported. The local label's
  final name is derived from concatenation of the last global label (not
  starting with period `.') and the local label. If the label starts with
  `..@', then it is a global label, but defining it keeps the ``last global
  label'' intact.

* Generating a listing file (`-l ...' command-line flag) is supported, but
  the listing file is different from what NASM generates.

* Optimization flags `-O0' (default, no optimization, as is for NASM
  0.98.39, but not in most newer versions) and `-Ox' (same as `-O999',
  all NASM optimizations enabled) are supported, and produce identical
  binary output to NASM. Please note that NASM 0.98.39 doesn't support `-Ox'
  (but NASM 0.99.06 already does), so for a compatible behavior of enabling
  all NASM optimizations, specify `-O999', which works in mininasm and
  NASM >=0.98.39.

* Command-line parsing is the same, as long as only `-f ...',
  `-l <listing-file>', `-o <output-file>', `-D<macro>=<value>',
  `-w[-+]<warning>' and `<assembly-source-file' are specified.

* The following directives (and data instructions) are supported:

        %define
        %assign
        %undef
        %if
        %ifdef
        %ifndef
        %ifidn __OUTPUT_FORMAT__, ...
        %ifnidn __OUTPUT_FORMAT__, ...
        %else
        %endif
        %include
        %line
        incbin
        times
        use16
        bits 16
        cpu 8086
        cpu 186
        cpu 286
        equ
        db
        dw
        dd
        align
        resb
        resw
        resd
        section .bss align=1
	absolute $

* Size qualifiers `byte' and `word' are supported, and behave identically
  to NASM. (A lot of manual testing at multiple optimization levels has been
  put into this.) The `strict' size qualifier prefix is also supported for
  immediates.

* Instructions, directives, register names and size qualifiers are case
  insensitive. Labels, macro names and string literals are case sensitive.

* Integers (in immediates, displacements, data instructions, expressions
  etc.) are 32-bit, just like in NASM 0.98.39. Newer versions of NASM
  have 64-bit integers.

* The following arithmetic operators are supported:

        |	Bitwise OR
        ^	Bitwise XOR
        &	Bitwise AND
        ~	Unary bitwise NOT
        <<	Shift to left
        >>	Shift to right (unsigned, as in NASM 0.98.39, unlike in newer versions of NASM)
        +	Addition
        -	Subtraction
        * 	Multiplication
        /	Division (unsigned)
        //	Division (signed)
        %	Modulo (unsigned)
        %%	Modulo (signed)
        (expr)	Parenthesis
        -	Unary negation
        +       Unary addition (no-op).

* The following integer literal syntaxes are supported:

        0b0000_0100	Binary, you can use underscore (it will be ignored)
        00000100b       Binary.
        0xabcd		Hexadecimal.
        $0abcd		Hexadecimal (after $ the first digit must be a number)
        0abcdh          Hexadecimal.
        0o567		Octal.
        567o		Octal.
        98		Decimal.
        'a'		Character constant (single-byte only).
        "a"		Character constant (single-byte only).
        $$		Start address.
        $		Current address.

* A small subset of single-line macro definitions is supported, see below.

Differences between mininasm and NASM:

* ++ mininasm has deterministic behavior (same as NASM on i386) if some
  arguments of division (`//') or modulo (`%%') are negative. NASM on other
  host system architectures may behave differently.

* ++ In general, mininasm does deterministic output no matter what the host
  system architecture is, thus mininasm is more suited as a cross-compiler
  than NASM.

* ++ The memory usage of mininasm is not limited by the input or output file
  sizes, thus files up to 2 GiB - 1 byte work flawlessly. (Larger files may
  run into operating system or ABI limitations.)

* In mininasm, there is an `%include' recursion limit (depending on the
  length of the filenames), a source line size limit of 255 bytes (not
  counting the trailing whitespace + optional comment + LF line terminator),
  an expression depth limit of 100 (not counting unary operators and some
  open parentheses), a label--macro combined limit (limited by available
  memory, count depends on name length).

* In mininasm, there is only support for 8086/8088 processors (`bits 16',
  `cpu 8086', no floating point) and 186 (`cpu 186', no floating point)
  and 286 (`cpu 286', no protected mode, no floating point) no 8087 etc.
  floating point instructions, no 32-bit instructions (`bits 32', in
  protected mode), no 64-bit instructions (`bits 64', in long mode).

* Only the binary output format (`-f bin' command-line flag) is supported,
  others (e.g. `-f elf', `-f obj', `-f win32') aren't.

* Only `db', `dw' and `dq' are the supported data instructions (so no `dq'
  or `dt').

* Floating point literals are not supported.

* Label definitions without (a leading `$' or a trailing `:') are supported
  only for `equ', `times', `db', `dw', `dd', `resb', `resw', `resd'.

* `section' definitions are not supported, except for `absolute $' and
  `section .bss align=1', both of which can be used to start the .bss, i.e.
  the uninitialized data part after the end of the output file.

  In both NASM and mininasm, `absolute $' doesn't change `$', while
  `section .bss align=1' resets it to `$$' (because it enters a new section).

  In both NASM and mininasm, the string `.bss' is case sensitive.
  
  Unlike in NASM, in mininasm it's not possible to switch back to
  `section .text'.

* All label values are integers, there are no section-relative values. This
  makes mininasm more permissive, e.g. `db $ * 3' works in mininasm, but
  only `db ($ - $$) * 3' works in NASM, because `$' is section-relative in
  NASM.

* Only some of the NASM directives are supported (see above).

* Only some of the NASM arithmetic operators are supported (see above).

* Only some of the NASM integer literal syntaxes are supported (see above).

* Single-line macros (e.g. with `%define' and `%assign') must have an
  integer value, and must not take any macro arguments.

* For `%define' (but not for `%assign'), the macro value must be an integer
  literal possibly prefixed by a sequence of unary `+', `-' and/or `~'.
  Alternatively, a macro can define to itself (e.g. `%define NAME NAME'),
  to make a difference for `%ifdef'. So e.g. `%define good' (without
  a value) is not supported.

* Macros defined in the command-line (with `-D...') behave like `%define',
  but cannot be changed or undefined. (This is to simplify state restoration
  between assembly passes in mininasm.) They also must have a value as an
  integer literal (possibly prefixed by unary operators) as a value.

* A macro and a label must not have the same name, except if the
  macro is defined to itself as `%define NAME NAME'.

* Multi-line macros (e.g. `%macro' and `%endm') are not supported.

* Comparison operators (e.g. `==') and logical operators (e.g. `&&') are not
  supported in `%if' expressions.

* Source lines longer than 255 bytes (not counting the trailing whitespace +
  optional comment + LF line terminator) are not allowed, and will be
  reported as error.

* mininasm reports an error for some register operations of the wrong size
  (e.g. `dec byte bx' and `dec word bh'), while NASM reports only a warning.

* If the input file is at least 2 GiB long, and it contains an `%include',
  then it may get processed incorrectly.

* The `strict' modifier in `strict byte' and `strict word' is alloed
  only for immediate arguments.

* mininasm doesn't display any warnings, the NASM `-w[-+]<warning>'
  command-line flags are ignored.

* The recommended flag for NASM 0.98.39 is `-w+orphan-labels', and for
  orphan labels mininasm reports an error.

* Command-line flags are case insensitive.

* mininasm doesn't display a useful help message.

* Shifts larger than 31 are not allowed (to avoid unspecified NASM
  behavior).

* It's OK to define local labels without defining a global label first.

* `%ifidn' and `%ifnidn' in mininasm are useful only for checking 
  `%ifidn __OUTPUT_FORMAT__, bin' (always true in mininasm, but may be false
  in NASM).

* In mininasm some instructions using labels or macros are not allowed
  before a non-zero `org'. These are the instructions whose optimized size
  may depend on the label and the origin (`org' value) for optimization. 
  For example, `add bx, mylabel' is not allowed before a non-zero `org'
  with -O9, but `add bx, strict word mylabel' is allowed. This is mostly to
  avoid creating a differently optimized output file than NASM.

Optional improvements in mininasm over NASM (disabled by default):

* Optimization of the `lea' instruction (enable with flag `-OL').

* Optimization of effective addresses with segment prefixes (enable with
  flag `-OG').

* Optimization of integers in immediates and effective address displacements
  (enable with flag `-OI').

* Turning on all NASM optimizations (`-Ox') and non-NASM optimizations
  with flag `-OA'.

mininasm is based on Tinyasm (https://github.com/nanochess/tinyasm), with
the following improvements:

* The listing file generated by Tinyasm contains the original comments
  and whitespace. (Being omitted from the outpout of mininasm is because
  of an implementation detail in mininasm.)
* It supports 32-bit numbers. (However, it doesn't support the 32-bit
  or 64-bit instructions, and it can't generate 32-bit DOS programs.)
* `bits 16' works.
* It supports `%define MACRO VALUE'. (It doesn't support macros with
  arguments or multiline macros. It supports numeric value only, see
  details below.)
* Its output (stderr, output file, listing file) doesn't depend on the host,
  not even for integer overflow (e.g. number of bytes reported), this it's a
  true cross-assembler.
* When compiled for DOS with dosmc, it needs only 64 KiB of memory (but it
  can use more, up to 636 KiB, out of which labels get 595 KiB), whereas
  Tinyasm needs 128 KiB (and cannot use more than ~50 KiB of memory for
  labels).
* When compiled for DOS with dosmc, it uses memory more efficiently, and thus
  it is able to compile an assembly input file with >55000 labels (see file
  most.asm). Most other 16-bit DOS assemblers support less than 8000 labels
  (e.g. A86 4.05 supports ~7200 labels, TASM 4.1 supports ~7400 labels,
  MASM 5.10a supports ~11800 labels, NASM 0.98.39 lite supports ~8000 labels).
* It depends on fewer runtime (libc) functions, so it can be compiled to a
  DOS .com file smaller than Tinyasm.
  Savings: about 17.1 KiB .com program instead of 30 KiB .com program
  with `owcc -bcom -Os'. (However, the size is now more: a bit less than
  20 KiB, because new features have been added.)
* It depends on fewer runtime (libc) functions, so it can be compiled to a
  Linux i386 executable program smaller than Tinyasm. Currently
  mininasm.li3 is about 19.4 KiB, and tinasm.xstatic (similar to Tinyasm)
  is about 52.8 KiB.
* Its behavior is adjusted for better compatibility with NASM 0.98.39.
  The most important difference is that it supports 16-bit integers, but
  NASM 0.98.39 supports 32-bit integers. See more differences between
  mininasm and NASM above.
* Its stack use has a constant upper bound (e.g. no recursive function
  calls), it never crashes because of large input.
* It has some new (NASM-compatible) features such as 'multicharacter' string
  literals, the unary `~' operator, 0o... octal integer literal syntax.
* The `>>', `/', `//', `%' and `%%' operators have a deterministic behavior
  (matching NASM on the i386) no matter what the host system architecture is.
  This is also an improvement over NASM.
* mininasm is an optimizing assembler, with its -O9 flag, it implements the
  same optimizations as NAsM. With its -OA flag, it implements some
  additional optimizations.
* It supports the `strict' size qualifier prefix for immediates.
* It supports `%define', `%assign' and `%undef' in a limited way (rather
  than not at all).
* mininasm supports the 2-argument form of `align'.
* In mininasm, `%ifdef' doesn't trigger for labels, only for macros.
* mininasm doesn't abort optimization after 5 passes, but it lets it go
  through as long as the output file size increases (see the proof below
  that it converges). Tinyasm fails to generate any output file after 5
  passes, unsure if it would converge.
Output file size limits of various assemblers:

* mininasm doesn't have a output file size limit. (This means is that the
  file size can be up to 2 GiB - 1 byte, and available memory is not a
  limiting factor.) See demo/fat12/floppy.nasm for a demo.
* Tinyasm doesn't have an output file size limit, like mininasm.
* Watcom Assembler (WASM) doesn't have an output file size limit.
* NASM stores each output byte in memory.
* JWasm for OMF .obj output doesn't have an output file size limit, but
  for -bin output it stores all output bytes in memory, and it silently
  overflows to video memory (0xa0000) on DOS.
* A72 doesn't have an output file size limit, but it can't easily repeat:
  it doesn't have `dup' or `times', and it's also very slow.
* A86 can co about 32256 output bytes correctly, doesn't report error on
  more, but output file incorrect and/or truncated.
* Wolfware Assembler can do 10799 bytes, fails for more.
* Turbo Assembler (TASM) 4.1 stores each output byte in memory, limit is
  about 450 KiB. But it has efficient encoding of `db ... dup (value)'
  in the .obj file, and it stores those bytes in memory RLE-compressed.
* Microsoft Assembler (MASM) 6.00B stores each output byte in memory.
  It has the /VM switch to use virtual memory (more than 640 KiB) on DOS.
* FASM stores output bytes in memory quite inefficiently (about 41.874
  bytes of memory usage per output byte, tested with `nop' instructions).

Possible future mininasm features:

* It will support 286 protected mode instructions.
  This hasn't been implemented yet.
* It will support 287 floating point instructions.
  This hasn't been implemented yet.

Host system compatibiliy of mininasm:

* mininasm.c, the C source code of the command-line mininasm tool can be
  compiled to many platforms without any configuration, even for platforms
  which have only a 16-bit int (but a >=32 bit long is needed, but that's
  mandated by the C standard). See the comment near the beginning of
  mininasm.c for example compilation command-lines with famous compilers.

* The implementation carefully avoids platform-specific behavior for large
  shifts (i.e. >=32 bit positions are explicitly disallowed) and negative
  number division (always rounds towards zero), thus mininasm generates the
  same output files no matter which host platform it is running on.

* mininasm.c is written in ANSI standard C (C89), and it uses only the
  following C library functions: for I/O: open(), creat(), close(), read(),
  write(), lseek(), remove(); for characters: isalpha(), isdigit(),
  isspace(), isxdigit(), for strings: strcmp(), strcpy(), strlen(), for
  dynamic memory: malloc(), for exiting: exit(). It also uses long and
  unsigned long division.

* Known modern compilers that can compile mininasm.c: GCC, Clang, TCC (Tiny
  C), OpenWatcom C compiler, dosmc (https://github.com/pts/dosmc). Older
  DOS compilers such as Turbo C++, Borland C++ and Microsoft C also work.

* mininasm.com (compilation output of mininasm.c with dosmc) and
  minnnasm.com (compilation output of minnnasm.nasm with NASM or mininasm)
  work with DOS 2.0 or newer (such as IBM PC DOS 2.00 released in 1983,
  MS-DOS 3.00, FREEDOS 1.2, command prompt of 32-bit Microsoft Windows),
  on an IBM PC compatible computer with an Intel 8086 or newer processor (such
  as 186, 286, 386, 486, Pentium or newer) or a suitable emulator (such as
  QEMU, pcjs.org). It also works on DOS emulators such as DOSBox,
  EMU2 (https://github.com/dmsc/emu2) and
  kvikdos (https://github.com/pts/kvikdos). The minimum free memory
  requirement is 64 KiB, but it can use up to 636 KiB of conventional memory
  if available.

* Input and output files work for up to 2 GiB minus 1 byte, but may be
  limited more by the operating system or the filesystem. Typical input
  assembly files are less than 1 MiB, typical output program binary files
  are less than 64 KiB. (There are no checks in mininasm to make it fail
  cleanly on files reaching the 2 GiB size.)

* mininasm uses very little stack space, because its functions have only a
  few small local variables, and it doesn't use function recursion.

* mininasm uses very little memory compared to other assemblers.
  Memory usage is constant + the memory used by labels + the memory
  used by macros; the size of the input and output files doesn't matter.
  More specific memory usage for mininasm.com:

  * the constant is less than 25 KiB (this includes mininasm.com
    code, read-only data, stack and fixed-size global variables)
  * per label usage is 10 bytes + the label length, e.g. the label `_start:'
    uses 10 + 6 == 16 bytes (the `:' is excluded from the length)
  * per macro usage is 21 bytes + 2 * the macro name length, e.g. the
    macro `BASE' uses 21 + 2 * 4 == 29 bytes

For compatibility, the mininasm repository also contains tinasm (source
code: tinasm.c), which aims to be compatible with Tinyasm, with the
following changes:

* Critical bugfixes: tinasm works when Tinyasm crashes or generates
  incorrect code.
* Portability improvements (to more systems and C and C++ compilers).
* Deterministic cross-compilation using dosmc.
* Its stack use has a constant upper bound (e.g. no recursive function
  calls), it never crashes because of large input.
* Numbers are always 16-bit, no matter the host system.
* Its output (stderr, output file, listing file) doesn't depend on the host,
  not even for integer overflow (e.g. number of bytes reported), this it's a
  true cross-assembler.
* On DOS, it can use more than ~20 KiB memory (up to ~595 KiB) for labels,
  when compiled with the OpenWatcom C compilar with the compact memory
  model.
* The `%' and `/' operators treat their inputs as unsigned integers
  consistently. (In Tinyasm, only `%' is signed.)
* (Otherwise, tinasm should behave identically to Tinyasm.)

The mininasm repository also contains minnnasm (source code:
https://github.com/pts/mininasm/blob/master/minnnasm.nasm), which is a
full-featured self-hosting fork of mininasm for DOS 8086 host only,
implemented in a subset of NASM assembly language, thus it's able to compile
(assemble) itself on DOS: by doing so it produces a DOS .com executable
binary bit-by-bit identical to what is produced by NASM (>= 0.98.39) and
mininasm (https://github.com/pts/mininasm). One of the development goals of
minnnasm is to improve the compatibility of mininasm with NASM: it's source
code is relatively complex NASM-compatible assembly code.

mininasm uses so little memory that it can compile minnnasm.nasm to
minnnasm.com (i.e. almost itself) by using only 64 KiB of DOS conventional
memory (including mininasm.com, the PSP and all mininasm data, excluding the
memory used by DOS itself and DOS file buffers).

Info about other assemblers:

* x86 assembler and linker comparison: https://pmwiki.xaver.me/drdoswiki/index.php?n=Main.DevelAsm

* x86 assembler comparison: https://www.japheth.de/JWasm/AsmCmp.html

* PC-72 assembler A72 a72.com: https://github.com/swanlizard/a72

  Discussion: https://www.bttr-software.de/forum/board_entry.php?id=17005

  Open source, tiny, can create .com and .bin only.

  A 8086 assembler without bells, whistles, gongs, or macros. It's a
  bare-bones single-segment symbolic assembler that will take standard
  Intel-format assembly and turn it into a COM file executable under DOS.
  R.Swan writes: "I wrote it for my own sake because I wanted to write
  assembly without having to use a bunch of directives and extraneous garbage
  in order to even just start writing, and to have binary code I could fully
  control and predict." Released to the public domain.

* Some other assemblers (source and binary download) targeting DOS:
  http://www.ibiblio.org/pub/micro/pc-stuff/freedos/files/devel/asm/

* Many more assemblers listed here:
  https://board.flatassembler.net/topic.php?t=5949

* More assemblers listed here:
  https://tldp.org/HOWTO/Assembly-HOWTO/other.html

* JWasm is an assembler compatible with MASM v6.

  Latest JWasm releases (v2.16pre2 on 2022-07-28):
  https://github.com/Baron-von-Riedesel/JWasm/releases

Known self-hosting assemblers (i.e. those which can compile their own assembly
source code) for x86:

* FASM (works on 32-bit and 64-bit x86): https://flatassembler.net/

* Asmc: https://github.com/nidud/asmc

* LZASM (closed source, works on 32-bit x86):
  http://web.archive.org/web/20071024143102/http://lzasm.hotbox.ru/

* A86 (closed source): https://eji.com/a86/

* NGASM (closed source): http://www.bestdiskrecovery.com/ (link broken),
  http://www.bestdiskrecovery.com/ngasm/index.html (link broken)

* A72: https://github.com/swanlizard/a72

* Venksi assembler:
  http://www.ibiblio.org/pub/micro/pc-stuff/freedos/files/devel/asm/venksi/

* Wolfware Assembler:
  http://www.ibiblio.org/pub/micro/pc-stuff/freedos/files/devel/asm/wasm/mitlicense/

* minnnasm.nasm in mininasm:
  https://github.com/pts/mininasm/blob/master/minnnasm.nasm

* TMA:
  https://www.sac.sk/download/utilprog/ta980705.zip
  https://www.sac.sk/download/utilprog/ta980717.zip

* intasm == intelasm == Intel Assembler:
  http://exmortis.narod.ru/comp_src/intasm52.zip

* XASM:
  https://www.sac.sk/download/utilprog/xasm312.zip
  https://web.archive.org/web/20070823101949/http://xasm.webpark.pl/xasm/files/xasm312.zip
  https://web.archive.org/web/20060813152752/http://xasm.webpark.pl/xasm/files/xasm2pde.zip

  Both XASM 3.x and 2.x are self-hosting. The source code of XASM 2.3 has been
  released along with the binary in xasm2pde.zip.

* Rosasm by René Tournois (Betov): (all download links dead)

  Runs on Win32, targets Win32 (32 bits). IDE only, no command-line.

Not self-hosting assemblers:

* NASM (open source, written in C).

* YASM (open source, written in C).

* WASM (open source, written in C).

* JWasm (open source, written in C).

* vasm (open source, written in C).

* as86 (open source, written in C):
  https://github.com/lkundrak/dev86/tree/master/as

  It was used targeting ELKS, with the bcc C compiler:
  https://github.com/lkundrak/dev86/tree/master/bcc

* ASM86 by Digital Research (open source, written in PL/M):
  https://www.cpm.z80.de/download/ccpmv31.zip  

* RASM86 by Digital Research (closed source, programming language unknown).

Below are excerpts from the README of Tinyasm.

,--------.,--.
'--.  .--'`--',--,--, ,--. ,--.,--,--. ,---. ,--,--,--.
   |  |   ,--.|      \ \  '  /' ,-.  |(  .-' |        |
   |  |   |  ||  ||  |  \   ' \ '-'  |.-'  `)|  |  |  |
   `--'   `--'`--''--'.-'  /   `--`--'`----' `--`--`--'
                      `---'
Tinyasm 8086/8088 assembler
by Oscar Toledo G. Oct/02/2019

https://nanochess.org/
https://github.com/nanochess/tinyasm

Tinyasm is a small assembler for 8086/8088 programs,
and it can work over a real PC XT machine. It requires
at least 128K of memory, maybe more.

It came to my attention that several people wanted to
assemble my boot sector games over real PC XT machines.

Unfortunately, nasm doesn't run over 8086/8088 processors,
and I couldn't find a compatible assembler!

So what does a programmer when doesn't find the required
tool? Start to code his own tool!

It took me 3 days to start from zero and get a working
assembler compatible with the nasm syntax, plus all the
directives I've used in my boot sector programs.

Using the same command line syntax as nasm:

  tinyasm -f bin rogue.asm -o rogue.img -l rogue.lst

There is also the -d option for defining labels:

  -dCOM_FILE
  -dCOM_FILE=1

It returns a non-zero error code when the assembled
file generates errors.

Thanks to tkchia for making it portable to ia16-elf-gcc,
removing DeSmet C warnings, and making it to return
error codes.

Thanks to humbertocsjr for contributing the INCBIN
command.


This assembler won't win a speed test ;) because the
internal implementation uses a linear search for the
instruction set, and it is also implemented as a kind
of regular expression subset for easier coding.


>> DEBUG NOTES <<

If you're building boot sector games with Tinyasm, then you
need the following info to load the game inside the boot
sector of a floppy disk.

You need to have DEBUG in your disk (included with the DOS
disks).

Do the following (replace filename as desired):

        DEBUG ROGUE.IMG
        	Extract now your working disk and insert a blank one!!!
        A300
        MOV AX,0301
        MOV BX,0100
        MOV CX,1
        MOV DX,0
        INT 13
        JB 300
        INT 20
        RIP
        300
        G
        	Now the boot sector is replaced with the program!!!


>> BUILDING THE ASSEMBLER >>

You can build your own executable for Tinyasm using the
C compiler Desmet C, version 3.1h available graciously at:

    http://www.desmet-c.com/

The compiler has many bugs and limitations, but it works for
Tinyasm purposes, and it's freely available.

Supposedly it should support ANSI C, but I couldn't fit a
standard ANSI C function definition, so I had to code again
in C K&R for the first time in maybe 20 years!

You can find the "e.bat" file to assemble the compiler.

I provide an executable on the Git to save you some time.

There are test cases in the 'test' subdirectory that are
runnable with the "test.bat" file.

There is a test for the full instruction set of 8086/8088
(the same listing that appears in my book Programming Boot
Sector Games).

The test cases come from my own programs:

        https://github.com/nanochess/fbird
        https://github.com/nanochess/invaders
        https://github.com/nanochess/pillman
        https://github.com/nanochess/bootBASIC
        https://github.com/nanochess/bootOS
        https://github.com/nanochess/bootRogue


>> ATTENTION <<

Would you like to learn 8086/8088 programming? Then you
must get my new book Programming Boot Sector Games including
a 8086/8088 crash course!

Now available from Lulu:

  Soft-cover
    http://www.lulu.com/shop/oscar-toledo-gutierrez/programming-boot-sector-games/paperback/product-24188564.html

  Hard-cover
    http://www.lulu.com/shop/oscar-toledo-gutierrez/programming-boot-sector-games/hardcover/product-24188530.html

  eBook
    https://nanochess.org/store.html

These are some of the example programs documented profusely
in the book:

  * Guess the number.
  * Tic-Tac-Toe game.
  * Text graphics.
  * Mandelbrot set.
  * F-Bird game.
  * Invaders game.
  * Pillman game.
  * Toledo Atomchess.
  * bootBASIC language.

After the success of my first book, if you need even
More Boot Sector Games then you must get this book!

  Soft-cover
    http://www.lulu.com/shop/oscar-toledo-gutierrez/more-boot-sector-games/paperback/product-24462035.html

  Hard-cover
    http://www.lulu.com/shop/oscar-toledo-gutierrez/more-boot-sector-games/hardcover/product-24462029.html

These are some of the example programs documented profusely
in the book:

  * Follow the Lights
  * bootRogue
  * bricks
  * cubicDoom
  * bootOS

About

NASM-compatible mini assembler for 8086, 186 and 286, able to run on DOS and on modern systems

License:Other


Languages

Language:Assembly 77.7%Language:C 19.9%Language:Shell 1.5%Language:Perl 0.8%Language:Batchfile 0.1%Language:DIGITAL Command Language 0.0%