Est. 1999 Advanced

FASM

A self-assembling, multi-pass x86 and x86-64 assembler created by Tomasz Grysztar in 1999, prized for its powerful preprocessor, compact size, and ability to produce executables for DOS, Windows, Linux, and bare-metal targets directly without a linker.

Created by Tomasz Grysztar

Paradigm Assembly, Imperative, Low-level
Typing None (untyped)
First Appeared 1999
Latest Version FASM 1.73.x series (ongoing); fasmg generalized assembler released around 2015

FASM, short for Flat Assembler, is a free, open-source x86 and x86-64 assembler created by Polish programmer Tomasz Grysztar and first released in 1999. It is renowned in low-level programming circles for three qualities: it is self-hosting (FASM is written in FASM), it is self-contained (it produces final executables for DOS, Windows, and Linux without needing an external linker), and it has one of the most expressive macro and preprocessor systems of any mainstream assembler.

While newer projects have largely shifted to NASM, GAS, or higher-level systems languages, FASM retains a devoted following in the demoscene, OSDev, reverse-engineering, and tiny-executable communities – domains where every byte of output and every cycle of assembly time matter.

History and Origins

Tomasz Grysztar began work on FASM in the late 1990s, reportedly while studying mathematics in Poland. The DOS-era assembler landscape was dominated by Borland’s TASM and Microsoft’s MASM, both commercial and tied to specific vendors. Grysztar wanted an assembler that was:

  • Free and open source, with a permissive license
  • Self-hosting, so it could bootstrap on any system where it already ran
  • Multi-pass and resolving, so forward references and computed sizes could be handled cleanly without linker tricks
  • Small – the original DOS executable was only tens of kilobytes

The first public release in 1999 targeted DOS and produced flat binaries and MZ executables. Over the following years FASM grew Windows PE, Linux ELF, and (later) Mach-O output, and added support for x86-64 long mode.

A defining moment came when Grysztar rewrote FASM in its own assembly language. From that point on, the canonical source of FASM has been a set of .asm files that FASM itself assembles into the next version of FASM. This self-hosting property is more than a curiosity: it forces the language and toolchain to remain stable, complete, and pleasant to use, because the author lives inside it every day.

Design Philosophy

FASM’s design rests on a few unusual choices that distinguish it from peers like NASM and MASM.

Multi-pass resolving assembler

Unlike traditional one-pass or two-pass assemblers, FASM runs as many passes as needed until the output stabilizes. This means instruction encodings, jump distances, and computed sizes can all depend on each other and FASM will iteratively converge on a consistent solution. Programmers can write code like jmp somewhere without worrying whether the short or near form is needed – FASM will pick the smallest encoding that works.

No linker required

FASM emits final executables directly. Format directives such as format PE, format ELF executable 3, format MZ, and format binary instruct the assembler to write the appropriate headers, sections, and relocations itself. For OSDev work this is invaluable: a bootloader is just format binary plus instructions, with no toolchain glue.

A macro language that rivals the host language

FASM’s preprocessor supports symbolic constants, conditional assembly, recursive macros (macro), structured equate definitions (struc), and a sophisticated match directive for pattern matching on token streams. In practice, FASM macros can implement high-level control flow, calling conventions, object-like structures, and even small DSLs – all evaluated at assembly time with zero runtime cost.

Flat memory model bias

The “flat” in Flat Assembler reflects Grysztar’s preference for the modern flat 32-bit and 64-bit memory models over the segmented 16-bit memory models that older assemblers were built around. FASM still supports segmented code, but its idioms and defaults assume a flat address space.

Key Features

  • x86 and x86-64 instruction support, including modern SSE, AVX, AVX2, and (in recent versions) AVX-512 extensions
  • Output formats: flat binary, MZ (DOS), COM, PE (Windows 32/64-bit, including DLLs), and ELF (Linux 32/64-bit, executables and object files); additional formats such as Mach-O are reportedly available via fasmg packages
  • Self-hosting: FASM’s source is FASM
  • Powerful macro system: macro, struc, irp, irps, match, rept, while, conditional assembly, and symbolic-constant arithmetic
  • No external linker required for most targets
  • Small, fast, single-binary toolchain – a few hundred kilobytes with no runtime dependencies
  • FASMW, a Windows IDE edition with editor, syntax highlighting, and one-key assemble-and-run

Example

A minimal Linux x86-64 “Hello, World!” in FASM showing the format-directive style:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
format ELF64 executable 3
entry start

segment readable executable
start:
    mov eax, 1            ; sys_write
    mov edi, 1            ; stdout
    lea rsi, [msg]
    mov edx, msg_len
    syscall

    mov eax, 60           ; sys_exit
    xor edi, edi
    syscall

segment readable
msg     db 'Hello, World!', 10
msg_len = $ - msg

This source assembles directly into a runnable ELF executable – no linker, no C runtime, no startup files.

Evolution

FASM development is unusual in that it has been almost entirely a single-author project for over two decades. Tomasz Grysztar has authored the vast majority of releases himself, with community contributions arriving largely as macro libraries, format packages, and example programs rather than core changes.

Major evolutionary steps include:

  • Self-hosting rewrite in the early 2000s, cementing FASM’s identity
  • Windows PE and Linux ELF output, broadening it from a DOS tool to a cross-platform assembler
  • x86-64 long mode support added in the mid-2000s
  • FASMW IDE for Windows users who preferred an integrated environment
  • fasmg (generalized FASM), released around 2015, which decouples FASM’s macro engine from the x86 instruction set, allowing community-maintained instruction packages for other architectures (ARM, RISC-V, 6502, and others) while retaining the same preprocessor model
  • Ongoing instruction-set updates for new x86 extensions like AVX-512

The original FASM 1.x line continues to be maintained alongside fasmg, since many users rely on its specific behavior and binary output.

Current Relevance

FASM is no longer a mainstream production tool, but it occupies durable niches:

  • OSDev hobbyists writing bootloaders and toy kernels appreciate the linker-free workflow
  • Demosceners competing in size-restricted categories (256 bytes, 1k, 4k intros) use FASM to squeeze every redundant byte out of their executables
  • Reverse engineers and security researchers use FASM for shellcode and small loaders where output bytes must be controlled exactly
  • Educators and curious programmers use FASM as a way to learn x86 assembly without committing to a vendor toolchain
  • KolibriOS and MenuetOS, two of the most striking demonstrations of what assembly can still achieve, continue to develop in FASM

The official forum at board.flatassembler.net has been continuously active since the early 2000s – a remarkable feat of community longevity for a single-author assembler.

Why It Matters

FASM is a living counterargument to the assumption that low-level tools must be sprawling, vendor-controlled, or write-only. A single author, working in his own assembler, has produced and maintained a toolchain that:

  • Bootstraps itself on every platform it targets
  • Builds entire operating systems
  • Fits, with full Windows IDE, in a download smaller than most modern web pages
  • Has remained backwards-compatible across more than two decades

For students of programming-language design, FASM is also a vivid demonstration of how far a thoughtfully designed macro system can stretch the expressiveness of even the lowest-level language. Many of the patterns FASM macros enable – structured-control DSLs, calling-convention abstractions, type-like struc definitions – prefigure ideas that higher-level languages later treated as first-class features.

In a software ecosystem that trends toward larger, more abstracted, and more disposable tools, FASM stands out as a reminder that small, sharp, and durable is still possible – even at the level of bytes and registers.

Timeline

1999
Tomasz Grysztar releases the first version of FASM (Flat Assembler) for DOS, designed as a fast, self-assembling x86 assembler with a built-in macro language
2000
FASM gains support for producing native Windows PE executables and Linux ELF binaries directly, without an external linker
2001
FASM becomes self-hosting: the assembler is rewritten in its own assembly language and can build itself on every supported platform
2003
FASMW, the Windows IDE edition with an integrated editor and one-click assemble-and-run workflow, is released around this time
2004
The community forum at board.flatassembler.net is reportedly active by this period, becoming the long-running hub for FASM development, examples, and user contributions
2006
Long-mode (x86-64) support is introduced around this time, allowing FASM to assemble 64-bit code for Windows, Linux, and bare-metal targets
2009
KolibriOS, a tiny x86 operating system written almost entirely in FASM, reportedly reaches a broadly usable state and continues to be developed using FASM as its primary toolchain
2015
Tomasz Grysztar begins releasing fasmg, a generalized assembler that retains FASM's macro philosophy but abstracts the instruction set, enabling targeting of architectures beyond x86
2020
Continued maintenance of the 1.x series adds support for newer x86 instruction-set extensions (reportedly including AVX-512) and refinements to macro handling, while fasmg sees ongoing community-contributed instruction-set packages
2024
FASM remains in active development with regular point releases, retaining its reputation as one of the smallest self-hosting assemblers and a favorite for OSDev, demoscene, and reverse-engineering work

Notable Uses & Legacy

KolibriOS

An open-source, x86 operating system written almost entirely in FASM assembly. The kernel, drivers, GUI, and most applications are assembled with FASM; the entire system fits on a 1.44 MB floppy

MenuetOS

A pre-emptive, multi-threaded operating system for x86 and x86-64 written from scratch in FASM. The 64-bit edition fits on a single floppy and demonstrates FASM's suitability for full-stack systems development

Demoscene productions

FASM is widely used for size-coded demos and intros (256-byte, 1k, 4k categories) on Windows and DOS, valued for its precise control over output bytes and absence of linker overhead

Reverse engineering and exploit research

Researchers use FASM to write shellcode, proof-of-concept exploits, and small loaders because it produces clean flat binaries and supports inline data layout with byte-level precision

OSDev community

Hobbyist operating system developers frequently choose FASM for bootloaders, kernels, and bare-metal experiments thanks to its ability to emit raw binary output without runtime or linker dependencies

Language Influence

Influenced By

TASM MASM Assembler

Influenced

fasmg FASMARM

Running Today

Run examples using the official Docker image:

docker pull
Last updated: