繁体   English   中英

如何将x86 GCC样式的C内联汇编转换为Rust内联汇编?

[英]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约束,它在shlqorq指令中为rdxrax提供了无效的操作数错误。 在Rust中重写上述C内联汇编的正确方法是什么?

Rust是建立在LLVM之上的,所以可以从LLVM或Clang那里收集到很多这样的低级细节。

  1. 如果要指定特定寄存器,请使用寄存器名称作为约束: "={rax}"(result) 根据GCC文档a约束是“a”寄存器。

  2. 文字必须以$$开头

  3. 寄存器必须以%开头

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() })
}

资料来源:

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM