Rust 构建在 LLVM 之上,因此可以从 LLVM 或 Clang 的工作中收集到很多像这样的低级细节。
如果要指定特定寄存器,则使用寄存器名称作为约束:"={rax}"(result)
。基于海湾合作委员会文档 https://gcc.gnu.org/onlinedocs/gcc/Machine-Constraints.html, the 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
我建议得到out一旦可行,就可以进行内联汇编。
各函数的组装:
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() })
}
Sources:
- 不稳定的书章asm https://doc.rust-lang.org/unstable-book/language-features/asm.html.
- The LLVM 内联汇编参考 https://llvm.org/docs/LangRef.html#inline-assembler-expressions.
- 我的图书馆jetscii https://github.com/shepmaster/jetscii/blob/master/src/lib.rs and cupid https://github.com/shepmaster/jetscii/blob/master/src/lib.rs.