#assembly #jit #dynasm #directasm #dynasm-rs

dynasm-lib

A pure rust assembler, not a JIT. Used within direct-asm for maximum control over assembly.

1 unstable release

0.1.0-alpha Jul 2, 2020

#31 in #jit

Download history 98/week @ 2023-11-20 100/week @ 2023-11-27 73/week @ 2023-12-04 72/week @ 2023-12-11 13/week @ 2023-12-18 4/week @ 2023-12-25 13/week @ 2024-01-01 74/week @ 2024-01-08 54/week @ 2024-01-15 95/week @ 2024-01-22 75/week @ 2024-01-29 44/week @ 2024-02-05 64/week @ 2024-02-12 58/week @ 2024-02-19 84/week @ 2024-02-26 100/week @ 2024-03-04

307 downloads per month
Used in direct-asm

MPL-2.0 license

770KB
16K SLoC

A pure rust assembler, not a JIT. Used within direct-asm for maximum control over assembly.

This crate implements uniform parsing of assembly into directives, labels, expression and backends for some architectures (x86, x86_64, aarch64 WIP). It's not exactly Intel syntax (but somewhat close) since it should be possible to embed expressions from the environment, which we must treat as arbitrary opaque values that we can not manipulate directly.

There is no global state and we don't assume to be executed within a proc-macro but that is one possible embedding. In that case we can combine expressions but not evaluate them. So, e.g. to embed some A: u8 whose three lowest bits give an index into the top three bits of an output byte, we ask the environment to generate a new expression for (A & 0x7) << 5. This yields the right result after const eval without having inspected the value of A ourselves. With enough of these combinators we can do all necessary operations for assembling.

This is a heavy work in progress, any contribution is welcome. Parser, new arch, better diagnostics.

Restriction: Inserting pointers and other relocations from the environment is not easy or outright impossible. We can directly insert a pointer as is which would not permit a pure byte slice as an output and requires an actual struct or complicated enum instead. However, the pointer's location must later be replaced by the linker and it has a replacement value describing the location in MIR const eval so we can inspect its bytes or insert compound arithmetic expressions of it. That must be evaluated at runtime. (In a completely stupid move we would modify the linker script to do that arithmetic but we can't go that crazy yet, the basics should work before that. Another option would be a compiler interface and there is some sympathy for it but nothing official or concrete.)

Dependencies

~215KB