An assembler formatter for Go / Plan 9 assembly, GAS syntax, and RISC-V code
English | 简体中文
asmfmt formats assembly source in the same spirit that gofmt formats Go
code.
It is primarily aimed at Go / Plan 9 assembly, and also supports a growing subset of GAS-style syntax used in ELF-oriented codebases, including RISC-V.
Status: STABLE. Default output is intended to remain stable unless a bug is
being fixed.
This repository is actively maintained as a fork of
klauspost/asmfmt. It keeps the original
formatter behavior where practical, while continuing development for use cases
that are no longer moving upstream.
asmfmt is useful when you want assembly code to be easier to review and keep
consistent across a codebase.
It can:
- normalize indentation,
- align operands and end-of-line comments,
- clean up blank lines and semicolon-separated statements,
- preserve historical default behavior when no config is present,
- run as either a CLI tool or a Go library.
Install the CLI from Go toolchain:
go install github.com/Mi-AIoT/asmfmt/cmd/asmfmt@latestAlternatively, you can download pre-built binaries directly from the GitHub Releases page. For beta/nightly features, download the latest master branch build from the beta pre-release.
You can also upgrade the tool automatically to the latest version, a beta version, or a specific release tag using the self-upgrade flag:
asmfmt -update latestTo override the repository or the update endpoint (e.g. for testing or local mirrors), use the ASMFMT_UPGRADE_REPO and ASMFMT_UPDATE_URL environment variables.
If you are depending on this fork as a Go module, check the current go.mod
module path first. The CLI install path and the library import path may differ
until the module path is moved from the upstream origin.
Format a file in place:
asmfmt -w path/to/file.sPreview changes as a diff:
asmfmt -d path/to/file.sFormat a directory tree:
asmfmt ./...asmfmt only processes .s files. Do not run it on non-assembly inputs.
Input:
TEXT foo(SB),$0
MOVQ AX,BX //comment
loop:ADDQ $1,AX;JMP loopOutput:
TEXT foo(SB), $0
MOVQ AX, BX // comment
loop:
ADDQ $1, AX
JMP loopFor larger examples, see testdata.
For the full CLI reference, detailed option explanations, configuration keys, and editor integration setup, please refer to the User Manual.
# Format a file in place
asmfmt -w path/to/file.s
# Format with a specific configuration
asmfmt -config /path/to/asmfmt.toml ./...asmfmt automatically searches for a configuration file in the following order:
- The nearest
.asmfmt.tomlwalking upward from the directory of the file being formatted. ~/.asmfmt.toml/etc/asmfmt.toml
For a fully commented configuration template, see .asmfmt.toml.example.
asmfmt includes an integrated code style linter to check assembly files against RISC-V and general GAS style rules.
Run the linter with the -lint flag:
asmfmt -lint path/to/file.sYou can configure linter rules and severity levels in the [lint] section of .asmfmt.toml. See Lint Rules Reference Manual for the list of rules, and the User Manual for configuration details.
asmfmt primarily targets Go / Plan 9 assembly and also supports a conservative
subset of GAS-like syntax.
Covered and tested areas include:
- Go / Plan 9 indentation and alignment rules
- GAS directives commonly used in RISC-V assembly such as
.section,.attribute,.option,.insn, relocation helpers, CFI directives, data directives, and symbol visibility directives - GAS macro blocks such as
.macro,.irp,.irpc,.rept,.if,.else, and matching end directives - GAS comments using
#,//, block comments, and ARM/GAS@line comments when the source is detected as GAS-like - RISC-V operand forms such as
%hi(...),%lo(...),%pcrel_hi(...),%pcrel_lo(...), local numeric labels like1b, CSR operands, vector operands, compressed mnemonics, and.insnencodings
Unknown directives and unknown lowercase mnemonics are preserved
conservatively. asmfmt will still clean up surrounding whitespace and
alignment, but it does not try to validate or normalize unknown syntax beyond
safe formatting behavior.
This fork is intended to be maintained independently.
Current goals:
- keep the original formatter stable for existing users,
- continue improving GAS and RISC-V coverage,
- accept fixes and features without waiting on upstream activity,
- keep configuration and CLI behavior predictable.
The project still inherits design and historical behavior from the upstream implementation, but documentation and releases in this repository describe the forked project rather than the original upstream repository.
Default behavior includes:
- tabs for indentation and spaces for alignment,
- operand alignment,
- end-of-line comment alignment,
- trailing whitespace removal,
- blank-line cleanup,
- label normalization onto their own lines,
- comment spacing cleanup,
- single-line block comment conversion when safe,
- semicolon cleanup and splitting where the detected style permits it.
If you need deterministic behavior across a mixed codebase, set
source_style explicitly instead of relying on auto-detection.
asmfmt is a formatter, not an assembler or linter.
It does not aim to:
- validate opcode legality,
- reject unknown directives or vendor mnemonics,
- require binutils or another assembler at runtime,
- guarantee semantic equivalence by default,
- rewrite unrelated Plan 9 formatting behavior to match GAS conventions.
asmfmt can also be used as a Go package:
package main
import (
"bytes"
"fmt"
"github.com/klauspost/asmfmt"
)
func main() {
src := bytes.NewBufferString("TEXT foo(SB),$0\nMOVQ AX,BX\n")
out, err := asmfmt.Format(src)
if err != nil {
panic(err)
}
fmt.Print(string(out))
}For configurable formatting, use asmfmt.FormatWithOptions(...).
Note: the current library import path is still the upstream module path shown above. If this fork adopts its own module path later, the import path in this example will need to change accordingly.
Common commands:
go test ./...
go vet ./...
gofmt -w .Refresh golden files after an intentional formatting change:
go test -run TestRewrite -updateMore focused regression commands and contribution workflow details are described in AGENTS.md.