我正在尝试在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);
}
答案 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)
}
由于所有受影响的寄存器都标记为输出,因此无需将任何内容标记为已破坏。还提供了所有输入值。
话虽这么说,不要写这段代码。
已经写好了。多次:
标准库包含用于所有重要CPU功能的intrinsics。在这种情况下,请使用core::arch::x86::__cpuid
/ core::arch::x86_64::__cpuid
。这些也可以在std
中使用,但由于某些原因而没有记录。
像我自己的箱子一样:cupid
编写内联汇编需要一个夜间编译器,并且可能永远不会稳定。它实际上仅对 extremely 特殊情况有用,例如引导OS或嵌入式系统,转储所有寄存器的状态以及其他内在函数无法覆盖的非常低级的细节(还好吗?)。