我希望用内联汇编替换32位值的最高字节,然后使用spi interace将缓冲区写入FRAM内存:
#define _load_op_code(op_code, addr)\
__asm__ __volatile__ (\
" ldi %D0, %1" "\n\t"\
: "=d" ((uint32_t)addr)\
: "M" (op_code)\
)
#define SMEM_WREN 0x06
#define SMEM_WRITE 0x02
void fram_write(uint32_t addr, uint8_t *buf, uint16_t len) {
FRAM_SELECT();
spi_send_char(SMEM_WREN);
FRAM_DESELECT();
_load_op_code(SMEM_WRITE, addr);
FRAM_SELECT();
spi_send_32b(addr);
spi_send(buf, len);
FRAM_DESELECT();
}
在_load_op_code()内联汇编后,addr变量变得混乱 - 编译器使用为addr分配的寄存器作为其他操作的临时寄存器,并且我丢失了原始的addr值。 addr实际上是24位变量。这个代码有什么问题吗?
答案 0 :(得分:1)
addr的原始值丢失,因为它被带有SMEM_WRITE和3个未定义字节的asm语句覆盖。从GCC手册:
普通输出操作数必须是只写的; GCC假定指令前这些操作数中的值已经死亡,无需生成。扩展的asm支持输入输出或读写操作数。使用约束字符“+”表示此类操作数,并将其与输出操作数一起列出。