Reputation: 6570
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
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