๐ A spirit that lifts fallen assembly back into the light
A matching decompiler: assembly in, C / C++ / Pascal out, aiming for source that recompiles byte-identical to the original object. Designed for retro game decompilation.
Check the playground to see it in action or the benchmark report to see its current performance.
![]() Explore the benchmark overview |
![]() Check its performance per function |
โ๏ธ What is Matching Decompilation?
Matching decompilation is the art of converting assembly back into C source code that, when compiled, produces byte-for-byte identical machine code. Itโs popular in the retro gaming community for recreating the source code of classic games. For example, Super Mario 64 and The Legend of Zelda: Ocarina of Time have been fully match-decompiled.
m2c is a great tool built over years of reverse engineering experience from many contributors, and its learnings were very helpful for asmlift.
But I wanted to explore a different approach: using AI to design, from scratch, a modular matching decompiler, plus using an AI loop to automatically iterate on the decompiler itself.
The driving question is: what if, instead of using AI to match a single function, we used AI to build a machine that matches functions programmatically?
asmlift is the result of this exploration.
๐ Check
asmlift-101.mdfor an introduction on how asmlift is designed and how decompilers works.
1. Install @asmlift/cli:
# globally, so you can run `asmlift` from anywhere on your system
npm install -g @asmlift/cli
# or inside a decomp project, as a dev dependency you run with `npx asmlift`
npm install --save-dev @asmlift/cli2. Configure decomp.yaml by adding platform and, optionally, add tools.asmlift.compiler and tools.asmlift.target. Check for more examples here.
# example decomp.yaml snippet for a GBA project
platform: gba
tools:
asmlift:
# Optional. Used only for disambiguation when multiple toolchains are available.
# Possible values: agbcc, ido7.1, gcc2.7.2kmc, mwcc_242_81
target: agbcc
# Optional. The project's built ELF. asmlift reads its symbol table and debug info to
# name the globals and struct fields the assembly only addresses, recover callee
# signatures, and adopt the project's address-cast macro names. How to produce a good
# one is covered in the CLI documentation linked below.
elf: rom.elf
# Optional. Used only for the `--score-against`
compiler: |
arm-none-eabi-cpp -nostdinc -I tools/agbcc/include {{inputPath}} -o {{outputPath}}.i
./tools/agbcc/bin/agbcc {{outputPath}}.i -o {{outputPath}}.s -mthumb-interwork -O2 -fhex-asm
arm-none-eabi-as -mcpu=arm7tdmi -mthumb-interwork {{outputPath}}.s -o {{outputPath}}3. Decompile and verify in one step:
asmlift build/src/gfx.s --name ReadUnalignedU16 --score-against build/src/gfx.os32 ReadUnalignedU16(u8 * a0) {
return *a0 | a0[1] << 8;
}
asmlift: [config] target agbcc (platform 'gba' in ./decomp.yaml)
asmlift: [score] unsigned: 0 (match)
๐ Check
packages/clito learn about all the configuration options and flags ofasmlift.
| Package / app | What it is |
|---|---|
packages/core (@asmlift/core) |
The decompile pipeline |
packages/cli (@asmlift/cli) |
The user-facing CLI package |
packages/toolchains |
The pinned calibration toolchains. Used only for the tests and benchmark |
packages/bench-schema |
The shared benchmark contract: result/manifest types + feature vocabulary |
apps/web |
The webapp including the Playground and the Benchmark |
apps/benchmark |
The asmlift and m2c harness |
MIT (LICENSE) for the whole monorepo, with two carve-outs:
apps/webis GPL-2.0-only, since it importsagbcc.- The game-derived benchmark data is not covered by either license. Check the original game repositories for their licensing.


