当前的 asm
语法已经被弃用,采用了更具有 Rust 特色的语法。不过,在汇编中使用常量仍然需要开启一个特性标记,并且只在夜间版中可用,如果我没记错的话。只需在主文件顶部添加 #![feature(asm_const)]
即可使用此功能。
pub const HCR_VALUE: u32 = 0xffff0000;
asm!(
"ldr x0, ={hcr}",
"...",
hcr = const HCR_VALUE,
out ("x0") _
);
更多信息可在此问题中找到。
通常情况下,您不希望在内联汇编中使用具有const操作数的ldr
:如果需要该值,则通常会要求编译器将常量已经存储在寄存器中。然后您不需要将其标记为out
寄存器,并且编译器将在asm语句之后仍知道该值保留在寄存器中。在非常大的汇编语句中,您可能会用完寄存器,或者在函数中,编译器将不会为您生成指令。
像"orr x1, x2, # {hcr}"
(硬编码寄存器)或and {foo}, {bar}, #{hcr}
(编译器选择的寄存器)等指令中,使用HCR_VALUE
作为布尔指令的立即数就是有意义的。 (按位布尔指令对于立即数使用位模式编码,可以使用具有一个连续块设置位或重复模式的常量进行编码,因此0xffff0000
可以直接使用,与0xffef0000
或类似的东西不同。)
当需要在寄存器中使用该值时,请尽可能要求编译器在您的asm语句之前执行:
asm!(
"use {reg} here where you would have used x0",
reg = in(reg) HCR_VALUE
);
这可能会产生与上面相同的编译结果。
如果您想将一个值放入特定的寄存器中,您可以:
asm!(
"...",
in ("x0") HCR_VALUE
);
.equ HCR_VALUE, 0xffff0000
这样的汇编行来将该名称定义为汇编时常量。将内联汇编视为只是让您在编译器将其馈送到汇编器之前将自己的内容放入编译器的汇编输出中;模板字符串除了替换%0
或%[operand_name]
之外,不能被编译器理解。 - Peter Cordes