вторник, 18 июня 2019 г.

Настройка IDE Arduino для генерации листинга на ассемблере

Порой возникает необходимость в изучении кода, генерируемого компилятором. Это помогает понять, что получается "на выходе" при использовании тех или иных функций, приемов, алгоритмов. Существуют специализированные инструменты - дизассемблеры, преобразующие машинный код в текст на языке ассемблера, но это в основном платные программы. Мне же в большинстве случаев вполне хватает результатов программы avr-objdump, которой и посвящена эта публикация.


avr-objdump - это программа, отображающая различную информацию из объектных файлов. Параметры, с которыми она вызывается, определяют, какая именно информация должна быть отображена. Например, для дизассемблирования объектного файла может быть использована следующая команда:

avr-objdump -d file_name.elf

Кому-то может больше понравиться дизассемблированный код с фрагментами исходного кода, где это возможно. Пример вызова для получения такого результата:

avr-objdump -S file_name.elf

Полный список возможных параметров вы можете найти по ссылке: http://ccrma.stanford.edu/planetccrma/man/man1/avr-objdump.1.html

Хорошо, где взять avr-objdump и объектный файл? Первый входит в состав IDE Arduino и расположен в каталоге Arduino_dir\hardware\tools\avr\bin\, где Arduino_dir - это путь установки IDE Arduino.

Что касается объектных (elf) файлов, то они создаются средой разработки при компиляции проекта и находятся во временной папке скетча. Найти их можно следующим образом:

1. Если у вас еще не включен вывод сообщений при компиляции скетчей, то перейдите в окно настроек IDE Arduino и установите соответствующую опцию:



2. После компиляции скетча в последних строках, выводимых средой разработки, вы увидите примерно следующее:


Выделенный фрагмент - это временный каталог для текущего скетча, в него помещаются все файлы, генерируемые в ходе компиляции, в том числе объектный файл.

Остается перейти в этот каталог и скопировать elf файл в Arduino_dir\hardware\tools\avr\bin\. Теперь, когда у нас avr-objdump и объектный файл находятся в одном каталоге (конечно, это необязательно, если в командах указывать полный путь к файлам), запускаем командную строку и вводим одну из приведенных ранее команд для дизассемблирования с поправкой на имя файла. В моем случае команда выглядит так:

avr-objdump.exe -S sketch_jun18a.ino.elf

В интерпретаторе командной строки необязательно вводить имя файла целиком: достаточно ввести несколько первых символов, затем нажимать TAB, пока интерпретатор не подставит нужное имя.

Итак, выполняем введенную команду и видим весьма объемный результат ее работы:


Для вывода результата работы avr-objdump в файл воспользуемся перенаправлением вывода:

avr-objdump.exe -S sketch_jun18a.ino.elf > my_file.asm

При выполнении данной команды в каталоге с avr-objdump.exe будет создан файл my_file.asm, в который будет сохранен результат работы команды:


Данный способ дизассемблирования скетчей вполне рабочий, но его использование можно упростить после небольшой настройки IDE Arduino, о чем будет рассказано далее.

Я для генерации ассемблерного листинга использую команду меню Скетч->Экспорт бинарного файла среды разработки Ардуино. При таком способе результат дизассемблирования сохраняется в каталог скетча (вместе с hex файлом), не приходится лазить по временным папкам. Для настройки IDE Arduino на генерацию ассемблерного листинга выполним следующие действия:

1. Переходим в каталог Arduino_dir\hardware\arduino\avr\ и открываем файл platform.txt в текстовом редакторе.

2. Находим команды для сохранения hex файла и добавляем после них следующую строку:

recipe.hooks.savehex.postsavehex.1.pattern="{compiler.path}/elf2asm.bat" "{compiler.path}avr-objdump" "{build.path}/{build.project_name}.elf" "{sketch_path}/{build.project_name}.asm"

Здесь мы используем так называемый хук, который выполняется после сохранения hex файла. Описание всех доступных хуков и самого файла platform.txt доступны по ссылке https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5-3rd-party-Hardware-specification. Ниже скриншот моего файла platform.txt после внесения указанных изменений:


3. Переходим в каталог Arduino_dir\hardware\tools\avr\bin\, создаем файл с именем elf2asm.bat и вставляем в него следующий текст:

%1 -S %2 > %3

Параметр -S определяет генерацию смешанного листинга. Использование bat файла обусловлено тем, что мы не можем использовать перенаправление вывода непосредственно в файле platform.txt.

На этом настройка IDE Arduino завершена. Можно переключиться в нее и проверить корректность работы, выбрав команду "Экспорт бинарного файла" в меню "Скетч". В каталоге со скетчем должен появиться файл с расширением asm. Приведенный способ дизассемблирования скетча пригодится нам в следующей публикации для анализа кода и продолжения темы обработки прерываний.

2 комментария:

  1. Классная статья. Я не знал о таком. Подскажите, пожалуйста, а как asm файл от avr-objdump скомпилироватьв hex.

    ОтветитьУдалить
  2. HEX — формат файла, предназначенного для представления произвольных двоичных данных в текстовом виде. Андрюха, чтобы скомпилировать(преобразовать)в hex asm файл от avr-objdump и что угодно от чего угодно, зайди сюда - https://sites.google.com/site/excelmidi/any-for-many-all-for-everyone/%D0%BD%D0%B0%D1%87%D0%B0%D0%BB%D0%BE-%D0%BF%D1%80%D0%BE%D0%B3%D1%80%D0%B0%D0%BC%D0%BC%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F-%D0%B2-%D0%B2%D0%B8%D0%BD%D0%B4%D0%BE%D0%B2%D1%81-11 там есть исходник для этого дела :). Но зачем это тебе? Возможно, тебе нужен не hex, а bin?

    ОтветитьУдалить