gpt4 book ai didi

assembly - 如何将 x86 GCC 风格的 C 内联汇编转换为 Rust 内联汇编?

转载 作者:行者123 更新时间:2023-11-29 07:53:35 34 4
gpt4 key购买 nike

我在 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 处为 rdxrax 提供了一个无效的操作数错误orq 指令。用 Rust 重写上述 C 内联汇编的正确方法是什么?

最佳答案

Rust 构建在 LLVM 之上,因此可以从 LLVM 或 Clang 的工作中收集到很多像这样的低级细节。

  1. 如果要指定特定的寄存器,则使用寄存器名称作为约束:"={rax}"(result)。基于the GCC documentationa 约束是“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() })
}

来源:

关于assembly - 如何将 x86 GCC 风格的 C 内联汇编转换为 Rust 内联汇编?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48098907/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com