这是this的后续问题。 我正在使用
为__AVR_HAVE_LPMX__
处理器(avr25)编写代码
当我在内联汇编中使用lpm rd, Z
时,编译器总是将其转换为lpm rd,Z+
(摘自lss-file):
asm volatile("lpm r24,Z");
248: 84 91 lpm r24, Z+
如果在连续访问查找表时使用它是不好的。查找值可能为0xff
,因此会不必要地增加ZH
(r31
),从而破坏此solution。
有什么建议可以规避这种行为?
答案 0 :(得分:1)
解决方案没有错;你的反汇编程序(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使用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 here和apparently fixed in binutils-2.23.1在2013年10月。
简而言之,只有拆卸受到影响;当反汇编应显示Z+
时,反汇编会错误地显示Z
。它不会影响生成的代码,只有人类可读的输出不正确。要修复,请升级到binutils 2.23.1或更高版本。如果您不能,请不要担心:您可以安全地忽略此错误,因为它只会影响人类可读的反汇编。
有问题吗?