asm-lsp: a language server for NASM, GAS and Go assembly
Language server for NASM/GAS/GO Assembly
At a glance
- What is it?
- asm-lsp is a Rust language server that adds hovering, autocompletion, signature help, go to definition and view references to assembly files, across x86, ARM, RISCV, z80, AVR and 6502 and the Gas, Go, Masm, Nasm, ca65, AVR and FASM assemblers. Diagnostics come from a real compiler, which is both its strength and its main operational dependency.
- Who is it for?
- asm-lsp suits a developer who reads or writes assembly regularly, works in an editor with LSP support, and is willing to point the server at the same compiler the build uses, since that is what produces the diagnostics. It suits less well a team that only occasionally touches assembly or that cannot run gcc, clang or a chosen assembler on the machine editing the files.
- Can I use it commercially?
- Yes. BSD-2-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 107 days ago.
- What is it written in?
- Mainly Rust, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
Assembly files with hover, completion and references
asm-lsp is a language server for assembly code. The stated goal is to provide hovering, autocompletion, signature help, go to definition and view references for assembly files written in the GAS, NASM or Go assembly flavours, across the x86, x86_64, ARM, RISCV, z80, AVR and 6502 instruction sets and the Gas, Go, Masm, Nasm, ca65, AVR and FASM assemblers.
The second use case in the README is the more interesting one for most people. The tool is described as a reference when reading the assembly output of a program, so you can query what each command does and decide whether the compiler is producing what you wanted or whether you need to tweak the source for optimisation. That is a different job from writing assembly from scratch. It is the job of someone reading a disassembly or a compiler's output and needing the semantics of each mnemonic at hand.
The implementation is Rust, published on crates.io as asm-lsp, and the repository is a Cargo workspace with three members: the server itself in asm-lsp, asm_docs_parsing, and xtask. The docs_store directory holds the parsed documentation that powers hover, and samples and demo directories carry example projects and the animated demonstrations of each feature.
The feature list is exactly the language server protocol set, so anything that speaks LSP gets the value. That includes the client configuration, which is a single section in your editor's settings.json.
"asm-lsp": {
"command": "asm-lsp",
"filetypes": [
"asm", "s", "S"
]
}The filetypes list is where the flavour of assembly is declared to the editor, and the command is the server binary. Editors that do not speak LSP will get nothing, which is worth checking before you invest in the setup.
Installing with cargo or taking a precompiled binary
The install path is the standard Rust one, and the README gives three variants. From crates.io:
cargo install asm-lspFrom the GitHub repository, which gets the latest code rather than the published crate:
cargo install --git https://github.com/bergercookie/asm-lsp asm-lspOr from a local checkout:
cargo install --path asm-lspFor people who would rather not build, the project publishes precompiled binaries on its releases page, which you download and uncompress.
The Rust version requirement is stated in a way that is worth reading carefully. The README carries a badge showing MSRV 1.82.0, but the note underneath says the minimum supported Rust version is 1.88.0, and that this may change on the master branch. The two numbers disagree, and the prose is the more recent statement, so take 1.88.0 as the floor and expect it to move. The workspace itself is on edition 2024, which is consistent with a recent toolchain requirement.
The Cargo workspace metadata also tells you the version the tree is on, 0.10.1, and the two authors, Nikos Koukis and Will Lillis, with a BSD-2-Clause licence. The published crate versions tell a slower story: v0.9.0 on 2024-09-04, v0.10.0 on 2025-02-03 and v0.10.1 on 2025-10-20, while the last push to the repository was on 2026-07-08. In other words, the working tree is ahead of the newest release, and the git install path is how you get that newer code.
Diagnostics come from invoking a real compiler
This is the design decision that separates asm-lsp from a parser that only knows grammar. By default, diagnostics are enabled and the server attempts to invoke gcc, and then clang, to produce them. If the compiler config field is set, it uses the compiler you name instead. The error messages you see in the editor are therefore the assembler's own, not a reimplementation of them.
The configuration lives in a .asm-lsp.toml file that you can place in the project root or in ~/.config/asm-lsp/, with project configs overriding global ones:
[default_config]
# Configure documentation available for features like hover and completions
assembler = "go"
instruction_set = "x86/x86-64"
[opts]
# The `compiler` field is the name of a compiler/assembler on your path
# (or the absolute path to the file) that is used to build your source files
# This program will be used to generate diagnostics
compiler = "zig" # need "cc" as the first argument in `compile_flags.txt`
diagnostics = true
default_diagnostics = trueDifferent configurations can be defined per sub-directory or per file through project blocks, and source files not covered by any project block fall back to the default configuration if one is given. The example in the README shows an arm-project sub-directory using gas with the arm instruction set, and a compile_flags_txt list of flags for that project.
For finer control there is a second path. A compile_commands.json or compile_flags.txt file in the project root or its build directory enables inline diagnostics and lets you specify extra include directories used by the hover features. The README points at Bear for generating one, since Bear recognises the nasm, yasm and fasm assemblers and records each file's include directories and defines, which is the same information asm-lsp reads. If neither file is present, the server falls back to a default compile command, and that fallback can be switched off with the default_diagnostics field set to false.
gen-config writes the TOML for you, with validation
Hand-writing the config is described as fine but error-prone as projects grow, so the project ships an interactive generator. Running asm-lsp gen-config walks you through creating a config with informative prompts and extra validation checks.
$ asm-lsp gen-config --help
Generate a .asm-lsp.toml config file
Usage: asm-lsp gen-config [OPTIONS]
Options:
-o, --output-dir <OUTPUT_DIR> Directory to place .asm-lsp.toml into. (Default is the current directory)
-g, --global-cfg Place the config in the global config directory
-p, --project-path <PROJECT_PATH> Path to the project this config is being generated for. (Default is the current directory)
-w, --overwrite Overwrite any existing .asm-lsp.toml in the target directory
-q, --quiet Don't display the generated config file after generation
-h, --help Print helpThe options cover the two places a config can live, global or project, and the flags that make the command safe to run repeatedly in a script, --overwrite and --quiet. The global flag writes to the global config directory, which the README identifies as ~/.config/asm-lsp/.
One behaviour is worth knowing before you point it at a machine you care about. If the server reads a configuration file it considers invalid, it displays an error message and exits. A malformed .asm-lsp.toml in the project root does not degrade gracefully, it stops the server, and the editor will report a server that fails to start. Generating the file with the tool rather than by hand reduces that risk, since the generator performs validation checks as it goes.
The project root has to contain a .git directory
There is a requirement in the README that is easy to miss and produces a confusing failure. The lsp searches for a .git directory to locate the root of your project, and the README asks you to run git init if your project is not already configured as a git repository.
The reason is structural rather than arbitrary. The server resolves which configuration file applies by finding the project root, and it determines that root by looking for the .git directory. In a directory that is not a repository, the root resolution has nothing to anchor on, so the config lookup and the per-project overrides both break. In a monorepo with several projects, this is also the mechanism that decides where the boundary sits between a project block and the default configuration.
The practical consequences are worth stating plainly. Working on a scratch file in a temporary directory means the server has no root, so per-project configuration will not apply. Unzipping a source archive and opening it without a git init will produce a server that starts but does not behave as configured. And if your organisation keeps sources outside version control for licensing reasons, you need to create a repository anyway.
The instruction set and assembler options are also enumerated in the README, and the lists are longer than the feature summary at the top suggests. The instruction_set field accepts x86, x86-64, the combined x86/x86-64, arm, arm64, riscv, z80, 6502, avr and mips. The assembler field accepts gas, go, masm, nasm, ca65, avr, fasm and mars. If your combination is missing, the project asks you to file an issue, with the note that they would be happy to add new options.
No published VSCode extension, and a version gap on crates.io
There is no packaged editor extension. The README states that the project has not published any VSCode extension package yet, and that a development extension exists in the editors/code directory with setup instructions. So for a VSCode user the path is either to run the development extension from source or to configure the server by hand in the editor settings, and for other editors it is the manual route. That is the single most likely reason an adoption stalls, since the setup is otherwise a few lines of JSON.
The release cadence is the other point to weigh. Versions 0.9.0, 0.10.0 and 0.10.1 came out in September 2024, February 2025 and October 2025, and the last push was on 2026-07-08. A project with a year-long gap between tagged releases and about three months of silence since the last commit is not dormant, but it is not on a monthly schedule either, and the version on crates.io trails the working tree.
For a tool that people install once and keep in their editor for years, that is usually acceptable, because the server talks to editors over a stable protocol and the assembly dialects it supports are stable. It is less acceptable if you need a new assembler flavour, since the supported list only grows when someone files the issue the README asks for.
The licence is BSD-2-Clause, as recorded in the workspace package metadata and in the LICENSE file. That is a permissive licence with no copyleft obligations, which suits a developer tool that will sit inside a company toolchain. The workspace lint configuration is strict, with clippy pedantic, nursery and cargo groups warned and dbg_macro, todo and all denied, and it borrows a subset of the allowances from the tree-sitter codebase, which explains the mental model behind the code.
Editorial conclusion
asm-lsp suits a developer who reads or writes assembly regularly, works in an editor with LSP support, and is willing to point the server at the same compiler the build uses, since that is what produces the diagnostics. It suits less well a team that only occasionally touches assembly or that cannot run gcc, clang or a chosen assembler on the machine editing the files. Before adopting it, confirm the assembler and instruction set pair you need appears in the .asm-lsp.toml options, remember that the project root must contain a .git directory for the server to find it, and note that the last push was on 2026-07-08 with the newest tagged release being v0.10.1 from 2025-10-20.
Frequently asked questions
How do I install asm-lsp?
With cargo install asm-lsp for the published crate, cargo install --git https://github.com/bergercookie/asm-lsp asm-lsp for the latest code, or cargo install --path asm-lsp from a local checkout. Precompiled binaries are also published on the project's releases page.
Which assemblers and instruction sets does asm-lsp support?
The README lists the x86, x86_64, ARM, RISCV, z80, AVR and 6502 instruction sets and the Gas, Go, Masm, Nasm, ca65, AVR and FASM assemblers. The configuration options additionally allow mips and mars.
How does asm-lsp produce diagnostics?
By default the server invokes gcc and then clang to generate diagnostics, and it uses the compiler named in the compiler config field if you set one. The diagnostics therefore come from the assembler itself rather than from a reimplementation.
Why does asm-lsp need a .git directory?
The server searches for a .git directory to locate the root of your project, which is how it decides which configuration applies. The README asks you to run git init if the project is not already a git repository.
Is there an asm-lsp VSCode extension?
Not yet. The README states that no VSCode extension package has been published, and points to a development extension in the editors/code directory with setup instructions instead.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/bergercookie-asm-lsp)Was this useful?