如何在使用rust asm!inline assembly时传入&str

q1qsirdb  于 5个月前  发布在  其他
关注(0)|答案(2)|浏览(75)

我想让这个函数操作指定名称的寄存器,但asm!宏似乎不支持它?

pub fn read_cpuid(reg: &str) -> u64 {
    let val: u64;
    unsafe {
        asm!("mrs {}, {}", 
            out(reg) val,
            reg
        );
    }
    val
}

字符串
错误消息如下:

error: expected one of `clobber_abi`, `const`, `in`, `inlateout`, `inout`, `lateout`, `options`, `out`, or `sym`, found `r`


如果我把r改为用reg传递,它仍然不起作用。

use core::arch::asm;
pub fn read_cpuid(r: &str) -> u64 {
    let val: u64;
    unsafe {
        asm!("mrs {}, {}", 
            out(reg) val,
            in(reg) r
        );
    }
    val
}
error: cannot use value of type `*const str` for inline assembly
note: only integers, floats, SIMD vectors, pointers and function pointers can be used as arguments for inline assembly

的字符串
我现在只能用枚举来解决,但是这种方法的可扩展性太差了,有没有更好的办法?

dffbzjpn

dffbzjpn1#

显式寄存器是字符串 * 文字 *,因此它们不能来自函数参数,变量甚至常量,但它们必须在调用asm!宏时直接输入。
这是有意义的,因为编译器必须根据所选择的寄存器发出不同的二进制代码,因此必须在编译时知道所选择的寄存器。

b5buobof

b5buobof2#

*const str是一个“胖”指针,这意味着它将str的长度存储在指向str开头的指针旁边。因此,它不能容纳在单个寄存器中。
使用str::as_ptr得到一个*const u8,它只是一个指针。

use core::arch::asm;

pub fn read_cpuid(r: &str) -> u64 {
    let val: u64;
    unsafe {
        asm!("mrs {}, {}", 
            out(reg) val,
            in(reg) r.as_ptr()
        );
    }
    val
}

字符串
这个错误信息不是很好。我建议opening an issue建议改进诊断。

相关问题