A tiny, zero dependency assembler that currently supports x86 and amd64.
dasm
has a goal of acting as a lightweight, simple instructions for compilers.
If you want a higher-level library or something more comprehensive, there's other great solutions like Iced
or dynasm-rs
.
Code generation doesn't have to be hard. This just provides explicit functions for generating instructions.
No abstractions through macros, or some DSL you need to learn. Just functions.
Example
use dasm::tier::raw::amd64::*;
let rax = 0;
let rsi = 6; // Argument 2
let rdi = 7; // Argument 1
let asm = [
&mov_r64_r64(rax, rdi) as &[u8],
&add_r64_r64(rax, rsi),
&ret()
].concat();
// Allocate an executable memory block
let mmapped = dasm::mmap::Mmap::exec(&asm)
.expect("Failed to mmap");
// Simply cast that memory into a function to call it.
let adder: extern "C" fn(x: u64, y: u64) -> u64 = unsafe { std::mem::transmute(mmapped.as_ptr()) };
assert_eq!(adder(5, 200), 205);
There's also an example showcasing a tiny AOT compiled lisp at examples/tinylisp
.
All of the other solutions are either too big for my usecase (LLVM
), too complex (Cranelift
) or have too many abstractions.
Sometimes, you don't need all of that - you just need to write some assembly.
That's what dasm
is for.
Of course - No shade to any other library. Anyone can use the tool they prefer.