c - lpm rd,Z 总是在 gcc-avr 中的内联汇编上转换为 lpm rd,Z+

标签 c gcc avr-gcc gcc4 winavr

这是对 this 的后续问题. 我正在使用

__AVR_HAVE_LPMX__ 处理器 (avr25) 编写代码
  • GNU C (WinAVR 20100110) 版本 4.3.3 (avr)/由 GNU C 编译 版本 3.4.5 (mingw-vista special r3), GMP 版本 4.2.3, MPFR 版本 2.4.1。

当我在内联汇编中使用 lpm rd, Z 时,编译器总是将其转换为 lpm rd,Z+(摘自 lss 文件):

asm volatile("lpm r24,Z");
248:    84 91           lpm r24, Z+

这是不好的,如果它用于连续访问查找表。查找值可能是 0xff,因此这会不必要地增加 ZH (r31),从而破坏此 solution .

有什么规避这种行为的建议吗?

最佳答案

解法没有错;你的反汇编程序(avr-objdump -dbinutils 包的一部分)有问题。

参见 Atmel AVR instruction set manual 的第 97 页(PDF)。 lpm 指令变体编码为

1001 0101 1100 1000 = 0x95C8   lpm r0,Z
1001 000? ???? 0100 = 0x9??4   lpm r?,Z
1001 000? ???? 0101 = 0x9??5   lpm r?,Z+

假设我们比您的反汇编程序更信任 Atmel 文档,那么

84 91    lpm r24,Z

鉴于

85 91    lpm r24,Z+

事实上,avr-gcc (GCC) 4.8.2 使用 avr-gcc-4.8.2 -O2 -fomit- 将内联汇编编译为相同的两个字节 (84 91) frame-pointer -mmcu=avr25,并在汇编源文件中列为lpm r24,Z(使用-S选项);当编译为目标文件,并使用 avr-objdump -d 与 avr-objdump (GNU binutils) 2.23.1 反汇编时,指令仍然是 84 91 lpm r24,Z.

这让我相信这是 avr-objdump(GNU binutils 的一部分)中的错误。啊是的,reported here , 和 apparently fixed in binutils-2.23.1 2013 年 10 月。

简而言之,只有反汇编受到影响;反汇编在应该显示 Z 时错误地显示了 Z+。它不会影响生成的代码,只是人类可读的输出不正确。要修复,请升级到 binutils 版本 2.23.1 或更高版本。如果不能,请不要担心:您可以安全地忽略此错误,因为它只会影响人类可读的反汇编。

有问题吗?

关于c - lpm rd,Z 总是在 gcc-avr 中的内联汇编上转换为 lpm rd,Z+,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25720452/

相关文章:

c - gcc/cygwin如何获取DNS服务器?

c++ - Open Watcom 的优点和缺点

c - 如何从 char *functionName(int arrayname[SIZE]); 返回字符数组

c - 如何在 malloc() 之后成功 free() 指针

arrays - Arduino atmega2560代码大小

c++ - 我可以在不使用 new 的情况下在 C++ 中实现工厂方法模式吗?

c - 商店订购大于原始尺寸的类型 - C 规范

python - 使用 Cygwin 安装 pzmq

c - GCC 7.2 编译共享库而不是可执行文件

c - 这到底是怎么编译成 4kb 的?