提供一个使用Rust的内联程序集查询Intel CPU功能的示例

时间:2018-08-15 00:48:31

标签: assembly x86 rust inline-assembly

我正在尝试在Rust中使用内联汇编。我包含的代码应该用于查询Intel CPU的功能,现在我只想在系统调用后获取ebx寄存器状态。

使用每晚编译的Rust编译器(必须使用asm!宏)来编译代码。运行程序时,我获得ebx寄存器的随机值和分段错误。我可以肯定我的asm!宏语法是错误的,但是此功能的文档非常薄弱。有谁对我可以改善的地方有任何指示?

#![feature(asm)]
fn main() {
    let result: u32;
    unsafe {
        asm!("mov eax, 07H;
              mov ecx, 0;
              cpuid;"
              : "={ebx}"(result)
              :
              : "eax, ebx, ecx, edx"
              : "intel"
        )
    }
    println!("ebx from cpuid is {}", result);
}

1 个答案:

答案 0 :(得分:6)

如果您觉得迫切需要忽略我的以下建议,则可以复制my old implementation of cpuid

fn cpuid(code: RequestType) -> (u32, u32, u32, u32) {
    let res1;
    let res2;
    let res3;
    let res4;

    unsafe {
        asm!("cpuid"
             : // output operands
             "={eax}"(res1),
             "={ebx}"(res2),
             "={ecx}"(res3),
             "={edx}"(res4)
             : // input operands
             "{eax}"(code as u32),
             "{ecx}"(0 as u32)
             : // clobbers
             : // options
             );
    }

    (res1, res2, res3, res4)
}

由于所有受影响的寄存器都标记为输出,因此无需将任何内容标记为已破坏。还提供了所有输入值。


话虽这么说,不要写这段代码

  1. 已经写好了。多次:

  2. 编写内联汇编需要一个夜间编译器,并且可能永远不会稳定。它实际上仅对 extremely 特殊情况有用,例如引导OS或嵌入式系统,转储所有寄存器的状态以及其他内在函数无法覆盖的非常低级的细节(还好吗?)。