这是对 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 -d
,binutils
包的一部分)有问题。
参见 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=avr25lpm 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/