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
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:
| |
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
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