mininasm icon indicating copy to clipboard operation
mininasm copied to clipboard

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

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 ', -o <output-file>', -D=', -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 dd' 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[-+]' 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