macro_rules! asm_block {
() => { ... };
(; $($token: tt)*) => { ... };
($first: ident : $($token: tt)*) => { ... };
($first: ident @ $($token: tt)*) => { ... };
($first: ident . $($token: tt)*) => { ... };
(: $($token: tt)*) => { ... };
(@ $($token: tt)*) => { ... };
(. $first: tt $($token: tt)*) => { ... };
({$($token_inside: tt)*} $($token: tt)*) => { ... };
([$($token_inside: tt)*] $($token: tt)*) => { ... };
(($($token_inside: tt)*) $($token: tt)*) => { ... };
($first: tt $($token: tt)*) => { ... };
}
Expand description
Translate tokens to a string containing assembly.
This evaluates to a &'static str
. Most input should be transformed as-is in to a
string, but there will likely be extra whitespaces or shrunken whitespaces.
How it Works
This macro follows very simple rules and mostly relies on the whitespace leniency of the underlying assembler.
Transformation rules:
- Convert
;
to\n
. - No space before and after
@
,:
. - Must have a space after
.<ident>
. - Not violating the previous rule, no space before
.
. - Concatenate everything inside a pair of
{
and}
without any space. - Transcribe all the other tokens as-is (by
stringify!
), and add a space afterwards.
This should work for most assembly code.
Example
use asm_block::asm_block;
macro_rules! f {
($a: tt, $b: tt, $c: tt, $d: tt, $k: tt, $s: literal, $t: literal, $tmp: tt) => {
asm_block! {
mov $tmp, $c;
add $a, $k;
xor $tmp, $d;
and $tmp, $b;
xor $tmp, $d;
lea $a, [$a + $tmp + $t];
rol $a, $s;
add $a, $b;
}
};
}
asm!(
f!(eax, ebx, ecx, edx, [ebp + 4], 7, 0xd76aa478, esi),
f!({a}, {b}, {c}, {d}, {x0}, 7, 0xd76aa478, {t}),
f!({a:e}, {b:e}, {c:e}, {d:e}, [{x} + 4], 7, 0xd76aa478, {t:e}),
a = out(reg) _,
b = out(reg) _,
c = out(reg) _,
d = out(reg) _,
x0 = out(reg) _,
x = out(reg) _,
t = out(reg) _,
);