Carl Patenaude Poulin
Carl Patenaude Poulin

Reputation: 6570

Rust inline assembly template syntax

I have the following code in test.s:

call $8 + $8

Running nasm test.s compiles successfully. I'd expect the following equivalent Rust code to compile successfully, but it doesn't.

In test.rs:

#![feature(asm)]
fn main() {
    unsafe {
        asm! (
            "call $0 + $0"
            :
            : "i" (8)
            : "memory"
            : "volatile"
        )
    }
}

Output of rustc test.rs:

test.rs:4:9: 10:11 error: <inline asm>:1:12: error: invalid token in expression
        call $8 + $8
                  ^

Upvotes: 3

Views: 2721

Answers (1)

Alexandros
Alexandros

Reputation: 3064

This is what worked for me:

#![feature(asm)]
fn main() {
    unsafe {
        asm!( "call ${0:c} + ${0:c}"
            :
            : "i"(8)
            : "memory"
            : "volatile"
        )
    }
}

Here's the relevant documentation in the LLVM reference. By looking at the output of objdump, we can verify that our inline assembly has been emitted:

0000000000005190 <_ZN4main20hc3048743ecd04f53eaaE>:
    5190:   e8 7b ae ff ff          callq  10 <_ZN10sys_common11thread_info11THREAD_INFO5__KEY20h20efb688859d2c0dRhsE+0x10>
    5195:   c3                      retq   
    5196:   66 2e 0f 1f 84 00 00    nopw   %cs:0x0(%rax,%rax,1)
    519d:   00 00 00 

UPDATE: Here's an example of directly calling a function from inline assembly:

#![feature(asm)]

fn called_even_if_mangled() {
    println!("Just a regular function minding its own business");
}

fn main() {
    unsafe {
        asm!( "call ${0:c}"
            :
            : "i"(called_even_if_mangled)
            : "memory"
            : "volatile", "alignstack"
            // Omit "alignstack" and you'll get a segfault because of a
            // misaligned SSE load on some initialization code regarding
            // stdin.
        )
    }
}

But you should never ever do such a thing, unless you have a very good and compelling argument to do so (for example, because you're writing a JIT). I had to spend an hour debugging a mysterious segfault until I realized that I also had to put alignstack in the options section.

You have been warned.

Upvotes: 6

Related Questions