Flat Assembler is a [[BSD-2]] licensed [[x86 Assembly]] assembler written in [[x86 Assembly]].
- [Website](https://flatassembler.net/)
- [Source](https://github.com/tgrysztar/fasm) (mirror, only bulk updated periodically with releases)
- [Documentation](https://flatassembler.net/docs.php)
> FASM (flat assembler) is an assembler for x86 processors. It supports Intel-style assembly language on the IA-32 and x86-64 computer architectures.
\- FASM article[^1] on Wikipedia
# Notability
# Philosophy
## Semi-Closed Development
> The flat assembler is made by a single person - Tomasz Grysztar - as a hobby project
Development doesn't happen publicly and released tend to happen every couple of years.
Despite this, it is very popular in the hobby [[Operating Systems|Operating System]] community, presumably due to being small and easy to port.
## FASMARM
FASM also has an [[ARM]] version.
- https://arm.flatassembler.net/
## FASMg
In practice, FASMg is a pluggable assembler framework. It implements the bare minimum set of functionality to support the process of assembling. This allows functionality to be supplied via "macro-instruction packages", and as a result it can be made to support *arbitrary* instruction sets.
- [Landing Page](https://board.flatassembler.net/topic.php?t=19389) (forum post)
- [Source](https://flatassembler.net/fossil/repo/fasmg/timeline) (official [[Fossil]] repo)
- [Documentation](https://flatassembler.net/docs.php?article=fasmg)
- [Documentation](https://flatassembler.net/docs.php?article=fasmg_manual) (manual)
> this is not fasm 2, and it is not even an x86 assembler. But it does not implement an instruction set for any other specific architecture, either. It is just a bare assembly engine that only has instructions like DB or DD to generate and assemble various data.
> ...
> Different instruction sets can be implemented in form of macroinstructions ... when these macroinstructions need to be complex, the assembly is going to be much slower than it would be if instruction set was implemented natively into assembler - and this adds to the fact that fasm g in general is slower than fasm 1, so you should certainly not expect an amazing performance.
> ...
> instruction sets implemented in form of macroinstructions give great flexibility and can be really fun to play with.
> ...
> I created the macroinstruction packages that implement the instruction sets for 8086/80186 (including MZ output with relocations), 8051 (with Intel HEX output) and JVM (with .class file generator converted directly from my example for fasm 1)
\- Tomasz Grysztar, in the original announcement post[^8] on the FASM forums
FASMg was announced in 2015 and has current (as of [[2025-09-01]]) releases, so it is seeing active development.
### FASMg Language
The FASMg language itself is surprisingly robust. Itself mostly a subset of FASM's, with full support for variables, infix operators, and if/else conditionals (in macros).
### CALM
CALM stands for "Compiled Assembly-Like Macro". It is a sublanguage that allows the developer to define new instructions for FASMg to use.
> people have been suggesting another idea - to make a separate language that could be compiled into instruction handlers. Such definitions could even be processed and compiled at the time of assembly, so they might be as flexible as macro packages, while offering better performance.
\- Tomasz Grysztar, in the post[^10] introducing CALM
> The main reason for calling them "assembly-like" was the way the control flow is structured in the CALM sub-language. While the classic language of fasmg's macros is structured with nestable control blocks like IF / END IF or REPEAT / END REPEAT, CALM is different. There are only jumps and conditional jumps, and implementing any algorithm this way is going to have a flow that is assembly-like. Also commands like COMPUTE or ARRANGE have syntax intentionally designed to resemble x86 instructions, with destination being the first argument.
\- Tomasz Grysztar, in a reply[^9] to a forum post asking about the name
CALM is invoked with the `calminstruction` directive, and closed with `end calminstruction`. It provides several "commands" that allow newly-defined instructions to perform parsing and assembling operations based on a source file.
CALM instructions are compiled in memory and are around 6 times faster than macros that do the same task.
Here is an example of the [[8086]] `PUSH` instruction from the FASMg distribution:
```vhdl
calminstruction push? src*
call x86.parse_operand@src, src
check @src.size and not 2
jno main
err 'invalid operand size'
main:
check @src.type = 'mem'
jyes push_mem
check @src.type = 'reg'
jyes push_reg
check @src.type = 'sreg'
jyes push_sreg
err 'invalid operand'
exit
push_mem:
xcall x86.store_instruction@src, (0FFh),(110b)
exit
push_reg:
emit 1, 50h + @src.rm
exit
push_sreg:
emit 1, 6 + @src.rm shl 3
exit
end calminstruction
```
### FASMg Tools
- [Vim Syntax Support](https://github.com/pinicarus/gentoo-overlay/blob/master/app-vim/fasmg-syntax/files/fasmg.vim)
### FASMg Instruction Sets
#### Official
FASMg ships with a few instruction sets with varying levels of detail:
- [[x86 Assembly]]
- (with dedicated definitions for 8086, 8087, 80186, 80286, 80287, 80386, 80387, 80486, Pentium 5, Pentium 6, and [[AMD64]])
- [[MCS-51|8051]]
- [[AVR]] (as an almost-superset of the [[MCS-51|8051]])
- [[JVM]] (simple implementation)
#### Community
Several people have created instruction set definitions for other architectures as well:
- [[68000]] - https://github.com/fredrik-hjarner/fasm68k/tree/master
- [[6502]] - https://board.flatassembler.net/topic.php?t=18136
- e[[Z80]] - https://board.flatassembler.net/topic.php?t=19201
- [[8049]] - https://board.flatassembler.net/topic.php?t=18398
- [[8080]] - https://board.flatassembler.net/topic.php?t=18448
- [[ARM]] - https://github.com/lantonov/asmFish/tree/master/arm/include
## FASM2
FASM2 is an assembler that is *mostly* compatible with baseline FASM, built using [[#FASM g]], mostly using [[#CALM]].
> fasm 2 as a set of scripts and headers for fasmg
>
> The purpose of this preview is to demonstrate what I envisioned fasm 2 could be. I do not promise to keep working on it.
\- Tomasz Grysztar in FASM2's announcement post[^7] on the FASM forums
FASM2 was announced in [[2023]] and has current (as of [[2025-09-01]]) releases, so it is seeing active development.
# Platform Support
- Linux
- DOS
- Windows
- Unix/libc "all platforms that have support for the ELF object format and the C library"[^6]
- [[OpenBSD]]
- Zeta
## Third-Party
- [[Kolibri]][^4]
- [[MenuetOS]][^5]
- [[Octa OS]][^2] (defunct hobby OS)
- [[Solar OS]][^3] (proof-of-concept anyway, hobby OS, unrelated to Solaris)
# Features
## Dead Code Elimination
> An unusual FASM construct is defining procedures only if they are used somewhere in the code, something that in most languages is done per-object by the linker.
# Tips
# Resources
## Fresh IDE
Fresh is an [[EUPL|EUPL-1.2]] licensed IDE for FASM, written in FASM.
- [Download](https://fresh.flatassembler.net/index.cgi?page=content/2_download.txt)
- [Source](https://fresh.flatassembler.net/fossil/repo/fresh3/timeline) (Fresh v3)
- [Source](https://fresh.flatassembler.net/fossil/repo/fresh/timeline) (`freshlib` runtime, [[BSD-2]])
FreshLib is of interest due to having a large set of implemented algorithms and common tasks, for example a [[Base 64]] encoder/decoder in `freshlib/data/base64.asm`.
# References
[^1]: https://en.wikipedia.org/wiki/FASM
[^2]: https://web.archive.org/web/20150815035630/https://sites.google.com/site/octaviovegafernandez/octaos/
[^3]: http://www.oby.ro/os/about/os_about_team.htm
[^4]: https://kolibrios.org/en/
[^5]: https://www.menuetos.net/docs.htm
[^6]: https://flatassembler.net/download.php
[^7]: https://board.flatassembler.net/topic.php?t=22855
[^8]: https://board.flatassembler.net/topic.php?t=17952
[^9]: https://board.flatassembler.net/topic.php?t=23882
[^10]: https://board.flatassembler.net/topic.php?t=21324