Last Updated on February 2, 2026 by Vivekanand
Windows assembly development requires the native Microsoft toolchain—Windows does NOT include GNU tools like as and ld by default. This guide covers the essential tools you need to start writing low-level code using MASM (ml64.exe) for x64 and armasm64.exe for ARM64 architectures.
Unlike Unix-like systems where GNU assembler is standard, Microsoft provides completely different tools distributed through Visual Studio. Whether you’re doing kernel development or security research, understanding these tools is essential. For practical examples, see my Hello World: Windows Edition post.

Table of Contents
Default Tools via Visual Studio
The toolchain consists of assemblers and linkers provided by Microsoft. These tools produce PE (Portable Executable) format binaries.
For x64 (AMD64):
ml64.exe— Microsoft Macro Assembler (MASM) for 64-bit x64 development.link.exe— Microsoft Linker that creates executables from object files.
For ARM64 (AArch64):
armasm64.exe— Microsoft ARM64 Assembler for ARM-based systems like Surface Pro X.link.exe— Microsoft Linker (same tool, targeting ARM64).
Where to get the tools?
- Download Visual Studio 2019/2022 (Community edition is free)
- Select “Desktop development with C++” workload
- For ARM64: Also install “MSVC v143 – VS 2022 C++ ARM64 build tools”
How to access the tools?
The tools are not in your PATH by default. Use one of these methods:
- Developer Command Prompt for VS — Sets up all paths automatically.
- Developer PowerShell for VS — PowerShell variant with paths configured.
- vcvarsall.bat — Script for manual configuration.
Setting Up Environment
Run these batch files from Command Prompt:
# For x64 development
"C:Program FilesMicrosoft Visual Studio2022CommunityVCAuxiliaryBuildvcvars64.bat"
# For ARM64 cross-compilation
"C:Program FilesMicrosoft Visual Studio2022CommunityVCAuxiliaryBuildvcvarsamd64_arm64.bat"
# For ARM64 native
"C:Program FilesMicrosoft Visual Studio2022CommunityVCAuxiliaryBuildvcvarsarm64.bat"
Toolchain Comparison: MASM vs GNU
Understanding the differences between MASM and GNU assembler is crucial for cross-platform developers.
Basic Differences
| Feature | MASM (ml64) | GNU (as/ld) |
|---|---|---|
| Assembler | ml64.exe | as |
| Linker | link.exe | ld |
| Syntax | Intel | AT&T (default) |
| Object Format | COFF/PE | ELF |
Syntax Differences
| Aspect | MASM | GNU AS |
|---|---|---|
| Register | rax | %rax |
| Immediate | mov rax, 5 | movq $5, %rax |
| Operand order | dest, src | src, dest |
| Memory | [rax+8] | 8(%rax) |
MASM Directive Comparison
| Feature | MASM64 | GNU AS |
|---|---|---|
| Code section | .code | .text |
| Data section | .data | .data |
| External | EXTERN | .extern |
| Public | PUBLIC | .global |
| Procedure | PROC/ENDP | Labels only |
Key Takeaways
The Microsoft toolchain takes a distinctly different approach. While GNU tools use AT&T syntax by default, MASM uses Intel syntax which many find more readable.
- Use Developer Command Prompt to ensure tools are in your PATH
- MASM uses Intel syntax while GNU uses AT&T
- PE/COFF format instead of ELF
- armasm64.exe for ARM64 targets
For calling conventions, see my Calling Conventions guide. Ready to code? Check out my Hello World tutorial.

