提供使用Rust的内联汇编查询Intel CPU功能的示例

Bar*_*rry 7 x86 assembly inline-assembly rust

我想在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);
}
Run Code Online (Sandbox Code Playgroud)

She*_*ter 6

如果您觉得有必要忽略我的以下建议,您可以复制我的旧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)
}
Run Code Online (Sandbox Code Playgroud)

没有必要将任何标记标记为破坏,因为所有受影响的寄存器都标记为输出.还提供了所有输入值.


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

  1. 它已经写好了.多次:

  2. 编写内联汇编需要每晚编译器,并且可能永远不会稳定.这真是只对有用极其小众的情况下,如自举一个操作系统或嵌入式系统,所有倾倒寄存器的状态,和其他非常低级别的细节,这种intrinsic不包括(尚未?).

  • @Shepmaster:当然,我在你的回答中看到的问题是OP不太了解如何使用cpuid,更多关于如何使用内联汇编; cpuid只是学习内联汇编的借口.或者以其他方式说,他们问的是如何钓鱼,而不是要求鱼,而你的答案则以"不要自己钓鱼,这里有鱼"为开头,这是没有用的.相反,答案应该解决OP程序集的问题(如果我理解正确的话,输出/ clobbers),并且可能最后提到cpuid存在内在函数/板条箱. (4认同)