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