gpt4 book ai didi

c - 'asm' : __asm__ __volatile__ 中不可能的约束

转载 作者:行者123 更新时间:2023-11-30 15:07:07 35 4
gpt4 key购买 nike

几天以来我一直在尝试编写一个非常简单的内联汇编代码,但没有任何效果。我有 NetBeans 作为 IDE 和 MinGW 作为编译器。我最新的代码是:

uint16 readle_uint16(const uint8 * buffer, int offset) {
unsigned char x, y, z;
unsigned int PORTB;
__asm__ __volatile__("\n"
"addl r29,%0\n"
"addl r30,%1\n"
"addl r31,%2\n"
"lpm\n"
"out %3,r0\n"
: "=I" (PORTB)
: "r" (x), "r" (y), "r" (z)
);
return value;
}

但我每次都会收到相同的消息“错误:‘asm’中不可能存在约束”。我尝试将所有内容写在一行中或使用不同的 asm 引入。我不知道我还能做什么。

最佳答案

请注意,gcc 的内联汇编语法是

asm [volatile] ( AssemblerTemplate
: OutputOperands
[ : InputOperands
[ : Clobbers ] ])

汇编指令之后首先是输出操作数,然后是输入。

正如 @DavidWohlferd 所说,I 代表 "constant greater than −1, less than 64 "常量(“立即数”)。

虽然 out 指令实际上需要该范围内的常量值,但 PORTB 并不是该常量值。 (如果您查看 Controller 相应的 avr/ioXXXX.h 文件,您可以亲自看到这一点,您可能会在其中找到类似 #define PORTB _SFR_IO8(0x05) 的内容.)

此外,并非所有 IO 寄存器都可以通过 out/in 访问;特别是较大的 Controller 有超过 64 个 IO 寄存器,但只能访问前 64 个。然而,所有IO寄存器都可以通过lds/sts在其内存映射地址进行访问。因此,根据您要访问哪个 Controller 上的哪个寄存器,您可能根本无法使用 out 来访问该寄存器,但您始终可以使用 sts 代替。如果您希望代码可移植,则必须考虑到这一点,如建议的 here 所示。例如。

如果您知道 PORTB 是 Controller 上前 64 个 IO 寄存器之一,则可以使用

"I"(_SFR_IO_ADDR( PORTB ))out,否则使用

“m”( PORTB )sts

所以这个:

__asm__ __volatile__("\n"
"addl r29,%0\n"
"addl r30,%1\n"
"addl r31,%2\n"
"lpm\n"
"out %3,r0\n"
: /* No output operands here */
: "r" (x), "r" (y), "r" (z), "I" (_SFR_IO_ADDR( PORTB ))

);

应该可以让你摆脱“不可能的约束”错误。尽管代码仍然没有任何意义,主要是因为您使用“随机”、未初始化的数据作为输入。您破坏了 r29-r31 的注册,但没有声明它们,我完全不确定您对 lpm 之前的所有代码的意图是什么。

关于c - 'asm' : __asm__ __volatile__ 中不可能的约束,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38492250/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com