如何将x86 GCC风格的C内联汇编转换为Rust内联汇编? [英] How do I translate x86 GCC-style C inline assembly to Rust inline assembly?
问题描述
我在C中具有以下内联汇编:
I have the following inline assembly in C:
unsigned long long result;
asm volatile(".byte 15;.byte 49;shlq $32,%%rdx;orq %%rdx,%%rax"
: "=a" (result) :: "%rdx");
return result;
我试图用Rust重写它:
I tried to rewrite it in 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内联汇编的正确方法是什么?
It doesn't recognize the =a
constraint an it gives me an invalid operand error for rdx
and rax
at shlq
and orq
instructions. What is the proper way to rewrite the above C inline assembly in Rust?
推荐答案
Rust建立在LLVM之上,因此可以从LLVM或Clang的工作中收集到很多这样的底层细节.
Rust is built on top of LLVM, so a lot of low-level detail like this can be gleaned from what LLVM or Clang do.
-
如果要指定特定的寄存器,请使用寄存器名称作为约束:
"={rax}"(result)
.根据 GCC文档,a
约束是一个"寄存器.
If you want to specify a specific register, you use the register name as the constraint:
"={rax}"(result)
. Based on the GCC documentation, thea
constraint is the "a" register.
文学作品必须以$$
寄存器必须以%
let result: u64;
unsafe {
asm!(".byte 15
.byte 49
shlq $$32, %rdx
orq %rdx, %rax"
: "={rax}"(result)
:
: "rdx"
: "volatile"
);
}
result
如果我正确理解了有关rdtsc
的讨论,您也可以这样做:
If I'm understanding the discussion about rdtsc
correctly, you can also do:
let upper: u64;
let lower: u64;
unsafe {
asm!("rdtsc"
: "={rax}"(lower),
"={rdx}"(upper)
:
:
: "volatile"
);
}
upper << 32 | lower
我建议在可行的情况下尽快取消内联汇编的 .
I advise getting out of inline assembly as soon as it's practical.
每个功能的组装:
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内部函数的相同代码.这需要 different 不稳定属性:
For completeness, here is the same code using the LLVM intrinsic. This requires a different unstable attribute:
#![feature(link_llvm_intrinsics)]
extern "C" {
#[link_name = "llvm.x86.rdtsc"]
fn rdtsc() -> u64;
}
fn main() {
println!("{}", unsafe { rdtsc() })
}
来源:
-
asm
. - LLVM内联程序集引用.
- 我的图书馆 jetscii 和
- The unstable book chapter on
asm
. - The LLVM inline assembly reference.
- My libraries jetscii and cupid.
这篇关于如何将x86 GCC风格的C内联汇编转换为Rust内联汇编?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!