AsmLens
See the assembly your real compiler produces, with your project's flags, beside your code and linked line by line.
AsmLens brings the Compiler Explorer workflow into VS Code, with the one thing a website can never have: your include paths, defines, build type and compiler version. It finds your project's compile command, compiles the file you are editing on every save, and shows the result in a real editor pane where every source line and the instructions it produced share a colour.
Windows first. This release targets Windows: MSVC, clang-cl, LLVM clang and MinGW-w64 gcc/clang. Linux and macOS support is planned.
Quick start
- Open a C or C++ file. A CMake project, a folder with
compile_commands.json, a c_cpp_properties.json setup or a single loose .cpp all work, with no configuration.
- Press
Ctrl+Alt+A or click the AsmLens button in the editor title bar. The assembly opens beside your source.
- Save and move the cursor. The pane recompiles on save, and the block for the line under your cursor lights up.
You need VS Code 1.90 or later and a C/C++ compiler. If you have none, install Visual Studio Build Tools with Desktop development with C++, or MSYS2.
Features
Source and assembly, linked by colour
Each source line gets one of twelve hues, and every instruction it produced carries the same hue. The mapping comes from the compiler's own debug line tables (.loc and .cv_loc directives, MSVC ; Line markers), never from guesswork. Move the cursor in either pane and the linked block lights up in gold. Hover a source line to preview its instructions. Select a loop to see how many instructions it costs in the status bar.
A hollow dot in the gutter marks source lines that produced no instructions at the current optimization level, the quickest way to see what the optimizer removed.
Function scope that follows you
By default the pane shows only the function under your cursor and switches as you move between functions. Pick Function (Ctrl+Alt+F) jumps to any function in the translation unit, with instruction counts. Toggle to whole-file scope from the pane's title bar.
Diff modes
Compare two optimization levels (Ctrl+Alt+D), your unsaved edit against the saved file, your working copy against Git HEAD, or two different compilers on the same flags. Compiler-generated labels are normalized and functions aligned by name, so only real changes light up. The status bar sums it up as instructions added and removed and functions changed, for example +7 −16 · 2 fn.
Turn on Toggle Optimization Remarks to see the compiler's own notes inline: vectorized (VF=8), not inlined: definition unavailable, loop not vectorized: call instruction cannot be vectorized. It works with clang -Rpass (or YAML optimization records), gcc -fopt-info, and MSVC /Qvec-report:2. Missed optimizations can be mirrored to the Problems panel.
Instruction documentation on hover
Hover any mnemonic for its description, operand forms, affected flags, the registers it uses and the source line it came from. The x86-64 and AArch64 references are bundled and work offline.
Binary mode
Show Disassembled Object compiles to an object file and disassembles it with llvm-objdump, GNU objdump or dumpbin. You get addresses, raw encoding bytes, padding and relocations: what the assembler actually chose.
Compiler Explorer hand-off
Open in Compiler Explorer opens the current file on godbolt.org with the closest matching compiler, your flags and your filter settings. AsmLens asks before the first time, because this is the only action that sends your source anywhere.
Built for real projects
- Compiles your unsaved buffer: no need to save to see the effect of an edit (
asmlens.compileOn: "type" recompiles as you type).
- Never blocks the editor. Every compile runs in a child process with a timeout and is cancelled when superseded.
- Cached. Toggling a filter re-renders instantly, and switching back to a previous flag set is a cache hit.
- Demangled C++ names (Itanium and MSVC), with the mangled symbol on hover.
- Intel or AT&T syntax for GCC and Clang.
- Export the assembly with a header recording the exact command, or copy the compile command to reproduce a result in a terminal.
Supported compilers
| Toolchain |
Versions |
How AsmLens finds it |
Line mapping |
MSVC cl.exe (Visual Studio, Build Tools) |
19.20+ (VS 2019, VS 2022) |
vswhere.exe; the vcvarsall.bat environment is captured once and cached |
; File / ; Line markers |
| clang-cl (bundled with Visual Studio or LLVM) |
LLVM 8+ |
Visual Studio's LLVM component, C:\Program Files\LLVM\bin, PATH |
DWARF .loc or CodeView .cv_loc |
LLVM clang (clang, clang++) |
8+ |
C:\Program Files\LLVM\bin, PATH |
DWARF .loc or CodeView .cv_loc |
| MinGW-w64 gcc (MSYS2, winlibs, standalone) |
7+ |
PATH, C:\msys64\{ucrt64,mingw64,clang64}\bin |
DWARF .loc |
| MinGW-w64 clang (MSYS2 clang64, llvm-mingw, winlibs) |
8+ |
same as above |
DWARF .loc |
Demanglers are picked automatically: MSVC listing comments and undname.exe for MSVC names; llvm-cxxfilt or c++filt for Itanium names, with a built-in fallback when neither is installed.
How AsmLens finds your compile command
The first source that matches wins, and the status bar shows which one is active.
asmlens.compileCommand: an explicit command in your workspace settings, with ${file}, ${workspaceFolder} and ${config:…} substitution.
compile_commands.json: from asmlens.compileCommandsPath, the workspace root, or the newest build*/ directory. Both the arguments and command forms are supported, including response files.
- CMake Tools: the active configure preset's build directory and toolchain, including Visual Studio generators that don't write
compile_commands.json.
.vscode/c_cpp_properties.json: the active configuration's compiler, include paths, defines and standard.
- Header files: the
.c/.cpp in the same folder that includes the header is compiled instead, and the header's lines are linked.
- Fallback: the best discovered compiler with
-std=c++20 -O2 (MSVC: /std:c++20 /O2). The status bar warns that project flags aren't in use.
asmlens.optimizationOverride and asmlens.extraArgs are applied on top of whichever source wins.
Filters
Filters are applied after compiling, so toggling one is instant. Use View Options… in the pane's title bar to change several at once.
| Filter |
Setting |
Default |
Effect |
| Hide directives |
asmlens.filter.hideDirectives |
on |
Removes assembler directives |
| Hide unused labels |
asmlens.filter.hideUnusedLabels |
on |
Removes labels nothing jumps to; function labels stay |
| Hide comments |
asmlens.filter.hideComments |
on |
Removes comment-only lines |
| Hide library code |
asmlens.filter.hideLibraryCode |
on |
Removes functions that come entirely from other files (STL instantiations, header helpers) |
| Hide foreign source |
asmlens.filter.hideForeignSource |
off |
Inside kept functions, hides instructions inlined from other files |
| Text sections only |
asmlens.filter.textSectionsOnly |
on |
Hides data, BSS, debug and exception-table sections; read-only data used by shown code is kept |
| Hide unwind tables |
asmlens.filter.hideUnwindTables |
on |
Suppresses .cfi_* / .seh_* (recompiles) |
| Trim whitespace |
asmlens.filter.trimWhitespace |
on |
Normalizes indentation and operand spacing |
Commands
All commands are in the Command Palette under AsmLens.
| Command |
Default key |
What it does |
| Show Assembly |
Ctrl+Alt+A |
Opens (or focuses) the assembly pane beside the source |
| Show Assembly for Function at Cursor |
|
Opens the pane in function scope, following the cursor |
| Show Assembly for Whole File |
|
Opens the pane for the whole translation unit |
| Toggle Function / Whole-File Scope |
|
Switches the pane's scope |
| Pick Function |
Ctrl+Alt+F |
Lists every function with instruction counts |
| Recompile |
|
Recompiles, bypassing the cache |
| Go to Source Line |
F12 (in the pane) |
Jumps to the source line of the instruction under the cursor |
| Reveal in Assembly |
Ctrl+Alt+Right |
Scrolls the pane to the cursor's source line (in C/C++ editors with a pane this replaces VS Code's Move Editor into Next Group; rebind either if you use both) |
| View Options… |
|
Toggles several filters at once |
| Toggle Directives / Unused Labels / Library Code / Comments |
|
Flip one filter |
| Toggle Demangling |
|
Mangled or demangled symbol names |
| Toggle Inline Source Comments |
|
Interleaves source lines as comments |
| Set Assembly Syntax |
|
Intel or AT&T (GCC and Clang) |
| Set Optimization Override |
|
-O0 to -Ofast, or /Od to /Ox, for this workspace |
| Select Compiler |
|
Chooses from discovered toolchains or browses for one |
| Copy Compile Command |
|
Copies the exact command of the last compile |
| Copy Assembly for Selection |
|
Copies the assembly of the selected source lines |
| Open in Compiler Explorer |
|
Opens the file on godbolt.org (asks first) |
| Diff Two Optimization Levels |
Ctrl+Alt+D |
Side-by-side diff of two levels |
| Diff Against Saved File |
|
Your unsaved edit against the file on disk |
| Diff Against Git HEAD |
|
Your working copy against the last commit |
| Diff Two Compilers |
|
The same file and flags under two toolchains |
| Diff Custom Compile Options (JSON) |
|
Any two option sets |
| Toggle Optimization Remarks |
|
Inline compiler optimization remarks |
| Show Disassembled Object |
|
Binary mode with addresses, bytes and relocations |
| Export Assembly to File |
|
Saves the pane with a header recording the command |
| Show Raw Compiler Output |
|
The unfiltered assembly exactly as the compiler wrote it |
| Quick Actions… |
|
The status bar menu: scope, optimization, compiler, settings |
| Show Log |
|
The AsmLens output channel: commands, timings, compiler output |
| Clear Cache |
|
Empties the memory and disk compile caches |
| Reset Workspace Settings |
|
Removes every asmlens.* setting from this workspace |
| Report Issue |
|
Opens a pre-filled issue with version, OS and driver; the compile command (paths redacted) goes to the clipboard for you to review |
Every key binding can be changed in Keyboard Shortcuts.
Key settings
| Setting |
Default |
|
asmlens.compileOn |
save |
save, type (debounced by asmlens.typeDebounceMs) or manual |
asmlens.scope |
function |
Default pane scope: function follows the cursor, file shows everything |
asmlens.compileCommand |
|
Explicit command; overrides discovery |
asmlens.compileCommandsPath |
|
Where your compile_commands.json lives |
asmlens.compilerPath |
|
Compiler for files without project flags |
asmlens.optimizationOverride |
project default |
Replaces the project's optimization flag |
asmlens.extraArgs |
[] |
Appended to every compile |
asmlens.syntax |
intel |
intel or att (GCC and Clang) |
asmlens.view.followCursor |
true |
Scroll the pane with the cursor |
asmlens.view.inlineSource |
false |
Interleave source text as comments |
asmlens.remarks.enabled |
false |
Collect optimization remarks (slows compiles 10–30%) |
asmlens.msvc.vsInstallPath |
|
Pin one Visual Studio install when several exist |
asmlens.compileTimeoutMs |
30000 |
Kill compiles that take longer |
Band colours are theme colours (asmlens.band0 to asmlens.band11, asmlens.activeBand) with separate defaults for dark, light and high-contrast themes. Override them in workbench.colorCustomizations or with asmlens.colors.bandPalette. Search the Settings editor for asmlens to see everything.
Privacy and workspace trust
- Nothing leaves your machine. AsmLens runs your own compilers on your own files and makes no network requests. The instruction reference and the Compiler Explorer compiler table are bundled.
- The one exception is explicit. Open in Compiler Explorer opens a godbolt.org link in your browser containing your source and flags, and asks the first time, naming exactly what is sent.
- No telemetry by default. If you turn on
asmlens.telemetry (it also respects VS Code's telemetry.telemetryLevel), events are written only to the AsmLens log. Paths, source, flags and symbol names are never recorded.
- Restricted mode is safe. In an untrusted workspace, AsmLens ignores
compile_commands.json, c_cpp_properties.json and workspace-level compiler, command and argument settings, because each of them could run an arbitrary program. Compilers you configured in your user settings, or that AsmLens discovers itself, still work.
- Compilers never run through a shell. Commands are passed as argument arrays, so nothing in a project file can inject shell syntax.
- Temporary files stay temporary. Your unsaved buffer is written only to a private per-session temp folder, which is removed when VS Code closes.
Troubleshooting
Start with AsmLens: Show Log. It records the resolved command, working directory, timings, cache hits and everything the compiler printed. Set asmlens.logLevel to debug for the full argument list and environment.
"No C/C++ compiler found": install Visual Studio Build Tools (Desktop development with C++), LLVM, or MSYS2, then run AsmLens: Select Compiler. A compiler outside the usual locations can be set with asmlens.compilerPath.
"Could not initialize the MSVC environment": AsmLens runs vcvarsall.bat once to get MSVC's INCLUDE/LIB environment; the first capture takes a few seconds and is then cached. If you have several Visual Studio installs, pin one with asmlens.msvc.vsInstallPath; to target x86 or ARM64, set asmlens.msvc.vcvarsArch.
"main.cpp is not in compile_commands.json": re-run CMake's configure step with -DCMAKE_EXPORT_COMPILE_COMMANDS=ON (CMake Tools does this by default with the Ninja and Makefile generators). Meanwhile AsmLens automatically uses the flags of the nearest entry in the same folder, which is right most of the time, and says so in the status bar.
"Compiler produced no code for this file": inline functions, templates and header-only code are only emitted where they are used. Switch to whole-file scope, turn off Hide library code, or use Show Raw Compiler Output to see exactly what the compiler wrote.
Slow or huge output: template-heavy files can produce hundreds of thousands of lines. Function scope and Hide library code keep the pane fast; asmlens.compileTimeoutMs raises the time limit.
Reproduce a result in a terminal: Copy Compile Command copies the exact command line of the last compile, quoted for your shell.
Credits
AsmLens's default filters follow Compiler Explorer's. The instruction reference's operand forms come from Intel® XED and Arm®'s machine-readable A64 specification, and its descriptions are written for AsmLens. See THIRD_PARTY_NOTICES.md for licenses and attributions.
AsmLens is released under the MIT License. It is an independent project and is not affiliated with Compiler Explorer, Intel, Arm or Microsoft.