lpm rd,Z всегда преобразуется в lpm rd,Z+ на встроенном ассемблере в gcc-avr

Это дополнительный вопрос к этому. Я пишу код для процессора __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), тем самым искажая это решение.

Любые предложения, чтобы обойти это поведение?


person Thomas    schedule 08.09.2014    source источник


Ответы (1)


В решении нет ничего плохого; ваш дизассемблер (avr-objdump -d, часть пакета binutils) глючит.

См. стр. 97 руководства по набору инструкций Atmel AVR (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 (GNU binutils) 2.23.1 с использованием avr-objdump -d инструкция по-прежнему 84 91 lpm r24,Z.

Это заставляет меня поверить, что это ошибка в avr-objdump (часть GNU binutils). Ах да, сообщено здесь, и по-видимому, исправлено в binutils-2.23.1 в октябре 2013 г.

Короче затрагивается только разборка; разборка неправильно показывает Z+, когда должно показывать Z. Это не влияет на сгенерированный код, только человекочитаемый вывод неверен. Чтобы это исправить, обновите binutils до версии 2.23.1 или новее. Если вы не можете, не волнуйтесь: вы можете спокойно игнорировать эту ошибку, так как она влияет только на разборку, читаемую человеком.

Вопросы?

person Nominal Animal    schedule 08.09.2014
comment
Это верно. В дизассемблере симулятора показывает: +0000011B: 9184 LPM R24,Z. Я должен узнать, какому инструменту доверять. Спасибо! - person Thomas; 09.09.2014