![](/img/trans.png)
[英]How do I translate AVR GCC-style C inline assembly to Rust inline assembly?
[英]How do I translate x86 GCC-style C inline assembly to Rust inline assembly?
我在C中有以下内联汇编:
unsigned long long result;
asm volatile(".byte 15;.byte 49;shlq $32,%%rdx;orq %%rdx,%%rax"
: "=a" (result) :: "%rdx");
return result;
我试着在Rust中重写它:
let result: u64;
unsafe {
asm!(".byte 15\n\t
.byte 49\n\t
shlq 32, rdx\n\t
orq rdx, rax"
: "=a"(result)
:
: "rdx"
: "volatile"
);
}
result
它无法识别=a
约束,它在shlq
和orq
指令中为rdx
和rax
提供了无效的操作数错误。 在Rust中重写上述C内联汇编的正确方法是什么?
Rust是建立在LLVM之上的,所以可以从LLVM或Clang那里收集到很多这样的低级细节。
如果要指定特定寄存器,请使用寄存器名称作为约束: "={rax}"(result)
。 根据GCC文档 , a
约束是“a”寄存器。
文字必须以$$
开头
寄存器必须以%
开头
let result: u64;
unsafe {
asm!(".byte 15
.byte 49
shlq $$32, %rdx
orq %rdx, %rax"
: "={rax}"(result)
:
: "rdx"
: "volatile"
);
}
result
如果我正确理解有关rdtsc
的讨论,您还可以:
let upper: u64;
let lower: u64;
unsafe {
asm!("rdtsc"
: "={rax}"(lower),
"={rdx}"(upper)
:
:
: "volatile"
);
}
upper << 32 | lower
我建议尽快退出内联组装。
每个功能的组装:
playground::thing1:
#APP
.byte 15
.byte 49
shlq $32, %rdx
orq %rdx, %rax
#NO_APP
retq
playground::thing2:
#APP
rdtsc
#NO_APP
shlq $32, %rdx
orq %rdx, %rax
retq
为了完整性,这里使用LLVM内在代码是相同的代码。 这需要不同的不稳定属性:
#![feature(link_llvm_intrinsics)]
extern "C" {
#[link_name = "llvm.x86.rdtsc"]
fn rdtsc() -> u64;
}
fn main() {
println!("{}", unsafe { rdtsc() })
}
资料来源:
asm
的不稳定的书章。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.