Assembly 如何将AVR GCC样式C内联程序集转换为Rust内联程序集? 我想把一些原来在C++中编写的ARDUNO代码翻译成锈,但这一行内联程序给我带来麻烦。 asm易失性( “lds r16,%[timer0]\n\t”// #如果已定义(\uuuu AVR\u ATmega2560\uuuuuuu) 添加r16,%[toffset]\n\t// #恩迪夫 “subi r16,%[tsync]\n\t”// andi r16,7\n\t// “调用TL\n\t”// “TL:\n\t”// #如果已定义(\uuuu AVR\u ATmega2560\uuuuuuu) “pop r17\n\t”//ATMEGA2560有一台22位PC! #恩迪夫 “pop r31\n\t”// “pop r30\n\t”// adiw r30,(LW-TL-5)\n\t// 添加r30、r16\n\t// //“adc r31,\uuuu0\u reg\uuuu\n\t”// “ijmp\n\t”// “LW:\n\t”// “没有\n\t”// “没有\n\t”// “没有\n\t”// “没有\n\t”// “没有\n\t”// “没有\n\t”// “没有\n\t”// //“没有\n\t”// “LBEND:\n\t”// : :[timer0]“i”(&TCNT0), [toffset]“i”((uint8)去抖动偏移量), [tsync]“i”((uint8_t)去抖动同步) :“r30”、“r31”、“r16”、“r17”);

Assembly 如何将AVR GCC样式C内联程序集转换为Rust内联程序集? 我想把一些原来在C++中编写的ARDUNO代码翻译成锈,但这一行内联程序给我带来麻烦。 asm易失性( “lds r16,%[timer0]\n\t”// #如果已定义(\uuuu AVR\u ATmega2560\uuuuuuu) 添加r16,%[toffset]\n\t// #恩迪夫 “subi r16,%[tsync]\n\t”// andi r16,7\n\t// “调用TL\n\t”// “TL:\n\t”// #如果已定义(\uuuu AVR\u ATmega2560\uuuuuuu) “pop r17\n\t”//ATMEGA2560有一台22位PC! #恩迪夫 “pop r31\n\t”// “pop r30\n\t”// adiw r30,(LW-TL-5)\n\t// 添加r30、r16\n\t// //“adc r31,\uuuu0\u reg\uuuu\n\t”// “ijmp\n\t”// “LW:\n\t”// “没有\n\t”// “没有\n\t”// “没有\n\t”// “没有\n\t”// “没有\n\t”// “没有\n\t”// “没有\n\t”// //“没有\n\t”// “LBEND:\n\t”// : :[timer0]“i”(&TCNT0), [toffset]“i”((uint8)去抖动偏移量), [tsync]“i”((uint8_t)去抖动同步) :“r30”、“r31”、“r16”、“r17”);,assembly,rust,avr,inline-assembly,Assembly,Rust,Avr,Inline Assembly,我最好的尝试是: const TCNT0:*mut u8=70 as*mut u8; 常量抖动_偏移量:u8=1; const DEJITTER_SYNC:i8=-2; 啊!( “lds r16,%[timer0] \t subi r16,%[tsync] \t andi r16,7 \不要打电话给TL \tTL: \t波普r31 \t pop r30 \隧道r30(LW-TL-5) \t添加r30、r16 \t ijmp \tLW: \不 \不 \不 \不 \不 \不 \不 \tLBEND:

我最好的尝试是:

const TCNT0:*mut u8=70 as*mut u8;
常量抖动_偏移量:u8=1;
const DEJITTER_SYNC:i8=-2;
啊!(
“lds r16,%[timer0]
\t subi r16,%[tsync]
\t andi r16,7
\不要打电话给TL
\tTL:
\t波普r31
\t pop r30
\隧道r30(LW-TL-5)
\t添加r30、r16
\t ijmp
\tLW:
\不
\不
\不
\不
\不
\不
\不
\tLBEND:
\t“
:
:“{timer0}”(&TCNT0),
“{toffset}”(DEJITTER_OFFSET),
“{tsync}”(数据同步)
:“r30”、“r31”、“r16”:“挥发性”);
我还远远不能编译。尝试编译时显示的错误是:

错误:无法为约束“{timer0}”分配输入注册表
-->/home/kirbylife/Proyectos/rvgax/src/lib.rs:53:9
|
53 |/asm!(
54 | | r“lds r16,${timer0}
55 | | subi r16,${tsync}
56 | | andi r16,7
...  |
77 | |“{tsync}”(去抖动同步)
78 | |:“r30”、“r31”、“r16”:“挥发性”);
| |_______________________________________^

我使用的是Cargo and rustc 1.38.0。

您的错误的直接含义是没有名为
timer0
toffset
tsync
的寄存器。根本原因是Rust中的
“{}”
语法表示约束的寄存器名,而不是符号名。换句话说,它对应于
”“
GCC中的东西,而不是
[]
东西。我看不到使用符号名称的方法,所以只需切换到数字名称即可。此外,它使用
$
而不是
%
来替换约束。请尝试以下方法:

const TCNT0:*mut u8=70 as*mut u8;
常量抖动_偏移量:u8=1;
const DEJITTER_SYNC:i8=-2;
啊!(
“lds r16,$0
\t苏比16兰特,2美元
\t andi r16,7
\不要打电话给TL
\tTL:
\t波普r31
\t pop r30
\隧道r30(LW-TL-5)
\t添加r30、r16
\t ijmp
\tLW:
\不
\不
\不
\不
\不
\不
\不
\tLBEND:
\t“
:
:“i”(&TCNT0),
“i”(去抖动偏移量),
“i”(去抖动同步)
:“r30”、“r31”、“r16”:“挥发性”);

(注意:未测试,因为我目前没有安装AVR Rust)

注意Rust
asm宏为空。在最近的编译器上,您尝试使用的宏名为
llvm\u asm。我没有使用最新版本的Rust,因此,我没有宏
llvm\u asm可用。我只是想提一下,您的方法可能不是未来的证明。不幸的是,我无法回答实际问题。GNU C中的
[timer0]
也不是寄存器名,它只是一个符号名,您可以使用它来代替
%0
。OP翻译它的方式(把它放在约束字符串中)显然是错误的,但你是否也在说Rust没有对应的,迫使你使用数字?@PeterCordes我只是想说后者(我在中没有看到对应的);我不是想暗示
[timer0]
是一个寄存器。我的意思是,Rust的音译是不正确的,因为它假设是这样。我不认为你是在暗示,但你确实暗示了OP的想法。这似乎不是解释他们丢弃了GNUC约束的错误部分(实际约束而不是符号名)的最清晰的方式。我想他们也不明白GNUC语法的意思。@PeterCordes我现在明白你的意思了。我对它进行了编辑,试图让它更清晰一点。