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

时间:2014-09-08 08:50:36

标签: 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-file):

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

如果在连续访问查找表时使用它是不好的。查找值可能为0xff,因此会不必要地增加ZHr31),从而破坏此solution

有什么建议可以规避这种行为?

1 个答案:

答案 0 :(得分:1)

解决方案没有错;你的反汇编程序(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使用84 91将内联汇编编译为相同的两个字节(avr-gcc-4.8.2 -O2 -fomit-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 hereapparently fixed in binutils-2.23.1在2013年10月。

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

有问题吗?