c - 编译时asm中不可能的约束

标签 c assembly inline avr atmel

在我的 Atmel ASF 项目中,我试图构建以下内联汇编代码。但是我在编译时遇到了不可能的约束。

编译器指向这一行 __asm__ __volatile__, 我错过了什么吗?

#define OUTPORT PORTD
#define OUTBIT 3      // PD.3   
uint8_t rport ,rbits;
uint8_t *buf = message;
asm volatile(   "in     __tmp_reg__, __SREG__             \n\t" // 1  Save SREG for later
                "cli                                      \n\t" // 1  Clear interrupts
                "in     %[rport], %[port]                 \n\t" // 1  Move PORTB adress to rport

                : //Outputs
                [rport] "=&r" (rport)

                : //Inputs
                [port]    "I" (_SFR_IO_ADDR(OUTPORT))     // Adress to port register, 6-bit positive constant

                : //Clobber list (compiler must restore)

                "r0"                                       // This is __tmp_reg__
);
  1. 是什么破坏了这个构建?
  2. 我想知道 asm 语法是否不正确?我一直在关注this manual

最佳答案

PORTD 在 ATxmega128A4U 上位于地址 0x0660,如其 datasheet , 第 62 页。因此 in 指令无法访问该端口。 您应该改用 lds,并带有约束条件

[port]  "i" (_SFR_MEM_ADDR(OUTPORT))

注意小写的“i”。

附录:我刚刚尝试编译以下内容:

#include <avr/io.h>

void test(void)
{
    uint8_t rport;

    asm volatile(
        "in __tmp_reg__, __SREG__  \n\t"
        "cli                       \n\t"
        "lds %[rport], %[port]     \n\t"
        : [rport] "=&r" (rport)               // output
        : [port]  "i" (_SFR_MEM_ADDR(PORTD))  // input
        : "r0"                                // clobber
    );
}

使用带有选项 -mmcu=atxmega128a4u -c 的 avr-gcc 4.9.2 我得到了 正确生成的代码并且没有警告,即使使用 -Wall -Wextra

“i”约束是 documented 表示“立即整数操作数”,而 "I" means “常数大于 -1,小于 64”。

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

相关文章:

ubuntu - 无法在 0xe 访问内存,Ubuntu 上的 kdbg

assembly - 指令集在汇编中起什么作用?

html - 如何在 HTML 中显示 Base64 图像

c - C 中的左值和右值

linux - ASM HelloWorld程序

c - c中的内联函数问题

c - 在内联函数中获取静态变量的值?

c - 当我尝试声明包结构时出错?

c - 用 C 打印字母表中所有单词的集合

c - 静态函数和内联函数是否应该在 .h 文件中定义?