Macro asm_block::asm_block

source ·
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) _,
);