我对内联汇编还是个新手,所以我需要你的帮助来确保我正确地使用它。我需要在我的C代码中添加汇编代码,它是用Risc-v工具链编译的。请考虑下面的代码:
int bar = 0xFF00;
int main(){
volatile int result;
int k;
k = funct();
int* ptr;
ptr = &bar;
asm volatile (".insn r 0x33, 0, 0, a4, a5, a3":
"=m"(*ptr), "=r"(result):
[a5] "m"(*ptr), [a3] "r"(k) :
);
}
...
我想做的是bar = bar+k
。实际上,我想更改bar
所在内存位置的内容。但是我编写的代码获取了bar
的地址,并将其添加到k
。有人知道问题出在哪里吗?
2条答案
按热度按时间x6yk4ghg1#
不幸的是,您误解了语法。
在汇编器字符串中,可以使用
%0
,%1
引用参数,其中数字是传递给asm
指令的第n个参数。或者,可以使用 symbolic name,%[myname]
引用[myname]"r"(k)
的参数。注意 symbolic name 和使用数字是一样的,名字本身并不意味着什么。在你的例子中,你可能会得到这样的印象,你强迫代码使用一个特定的处理器寄存器。(如果你真的需要使用它,还有另一种语法。)
例如,如果你写这样的东西:
IAR编译器将发出如下代码:
a0
被赋值为result
变量(使用符号名res
),a1
被赋值为ptr
变量(这里,符号名与变量名相同)。您可以在“汇编语言接口”一章的“IAR C/C++ Development Guide Compiling and linking for RISC-V”一书中阅读有关IAR内联汇编语法的更多信息。该书以PDF格式提供,您可以从IAR Embedded Workbench中访问。
bvk5enib2#
根据您问题中提供的代码片段,我尝试使用IAR C/C++编译器(RISC-V版)执行以下代码:
在这种情况下,
.insn
指令将生成add r,r,r
,它实际上是*ptr = *ptr + k
。"a3"
、="a3"
、"a4"
、"a5"
等)。此时,正如@PeterCordes在评论中指出的,GCC提供了一组不同的约束,因此需要不同的解决方案。然而,如果不需要明确说明寄存器,最好让编译器决定哪些寄存器可以直接使用。这样通常会带来更少的开销。*