Генерирует ли компилятор промежуточный ассемблер?

Мои исходные файлы *.ino, но после компиляции в папке больше нет других файлов. Генерирует ли компилятор промежуточный ассемблер, и если да, то где он их оставляет? Или машинный код где-нибудь доступен?

, 👍5

Обсуждение

1) Если вы переключитесь на сборку Makefile или каким-либо другим способом сможете настроить аргументы, вы можете попросить avr-gcc создать вывод ассемблера. 2) Поочередно вы можете использовать avr-objdump для разборки двоичного файла (или с помощью objcopy, hex), чтобы вернуться к мнемонике сборки. С оригинальным незашифрованным двоичным файлом elf objdump может печатать много символов (обычный способ создания файла списка), но с необработанным двоичным или шестнадцатеричным файлом они безвозвратно теряются., @Chris Stratton

@ChrisStratton: Спасибо. Можете ли вы подробнее остановиться на 1)? Я знаю, что файлы makefile обычно используются разработчиками программного обеспечения, но у меня нет никакого опыта работы с ними., @Joris Groosman

Существуют различные файлы, которые вы можете найти в Интернете, чтобы создать проект Arduino с большим контролем деталей. Не в состоянии выкопать для вас хоть одну прямо сейчас. Также могут быть способы настройки команд IDE, но у IDE так много других проблем, что я не уверен, что это стоит того, чтобы беспокоиться., @Chris Stratton

Вы можете найти файлы makefile, совместимые с Arduino, в репозитории embedxcode по адресу http://embedxcode.weebly.com Вы, вероятно, посмотрите на arduino15avr.mk в частности, досье. Вы можете изменить этот файл, чтобы сохранить вывод ассемблера и разместить его там, где вы хотите., @MAC


2 ответа


6

Мои исходные файлы *.ino, но после компиляции в папке больше нет других файлов.

Правильный. Среда IDE Arduino выполняет компиляцию в отдельном временном каталоге, местоположение которого вы можете увидеть, если включите подробную компиляцию в параметрах среды IDE.

Генерирует ли компилятор промежуточный ассемблер, и если да, то где он их оставляет?

По умолчанию GCC (который использует Arduino IDE) не оставляет промежуточные файлы языка ассемблера на диске. Вы должны передать аргумент --save-temps, чтобы он оставил их в текущем каталоге, или --save-temps=obj, чтобы сохранить их в выходном каталоге.

Или машинный код где-нибудь доступен?

Машинный код доступен в файлах .elf и .hex, созданных в каталоге temprary.

,

1

ДА.

Компиляция Arduino настроена с оптимизацией времени связи (LTO), и файлы сборки, созданные во время компиляции C, не содержат никакого кода сборки-только промежуточное представление, используемое позже на этапе LTO для создания фактического кода сборки. Нам нужно последнее.

Это довольно приятно, но так происходит, что в самый последний раз, когда ассемблер вызывается во всем процессе компиляции, он выводится из этапа LTO и преобразуется в объектный файл всего приложения.

Чтобы получить доступ к этому файлу сборки, выполните следующие действия (в Windows):

  1. Открыть %LOCALAPPDATA%\Arduino15\packages\arduino\hardware\avr\1.8.3\platform.local.txt (создайте его, если он не существует). Добавьте следующую строку

    compiler.c.elf.extra_flags=-save-temps=obj -fverbose-asm
    

    Если там уже есть такая строка, просто добавьте указанные выше опции (справа от =).

    Примечание. Если вы не можете найти папку, найдите следующие файлы: boards.txt, platform.txt, programmers.txt. Если вы найдете эти файлы в нескольких местах, тот, который вы хотите, должен находиться в вашем домашнем каталоге (т. е. Не в программных файлах или /Приложениях или /usr) и должен быть, по крайней мере, частично, связан с версией Arduino, которую вы используете (если у вас установлено несколько версий).

  2. Создайте скетч снова.

  3. Найдите файл с именем %TEMP%\cc*.ltrans.s. Каждая сборка создаст новый такой файл. Если вы отсортируете их по метке времени, самая новая будет для самой последней сборки.

Примечание: Переменные среды, обозначенные знаками%, действительны в диалоговых окнах Windows. Вы можете напрямую вставить такой путь, например, в диалоговое окно Открыть или Сохранить как..., и он будет работать. Пути с глобусами (*) будут действовать как фильтры (IIRC).

Чтобы узнать, какой именно файл cc*.s был сгенерирован, добавьте опцию verbose в окончательный проход генератора двоичных файлов:

compiler.c.elf.extra_flags=-save-temps=obj -fverbose-asm -v

Перестройте и скопируйте все выходные данные из окна состояния компиляции в Arduino, например, в Notepad++, и выполните поиск ar.exe. Единственная строка, содержащая ar.exe заканчивается именем этого файла cc:

 c:/users/[...omitted...]/avr/bin/as.exe -mmcu=avr6 -mno-skip-bug 
    -o C:\Users\[...]\AppData\Local\Temp\cc3XhU2F.ltrans0.ltrans.o
    C:\Users\[...]\AppData\Local\Temp\cc3XhU2F.ltrans0.ltrans.s

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

.LBE33:
.LBE32:
.LBB34:
.LBB35:
 ;  C:\Users\[...]\Documents\Arduino\sketch_jul01a\sketch_jul01a.ino:29:   pinMode(ledPin, OUTPUT);
    .file 4 "C:\\Users\\[...]\\Documents\\Arduino\\sketch_jul01a\\sketch_jul01a.ino"
    .loc 4 29 0
    ldi r22,lo8(1)   ; ,
    ldi r24,lo8(13)  ; ,
    call pinMode     ; 
.LVL55:
 ;  C:\Users\[...]\Documents\Arduino\sketch_jul01a\sketch_jul01a.ino:30:   pinMode(relayPin, OUTPUT);
    .loc 4 30 0
    ldi r22,lo8(1)   ; ,
    ldi r24,lo8(12)  ; ,
    call pinMode     ; 
.LVL56:
 ;  C:\Users\[...]\Documents\Arduino\sketch_jul01a\sketch_jul01a.ino:31:   pinMode(ldrPin, INPUT);
    .loc 4 31 0
    ldi r22,0    ; 
    ldi r24,lo8(54)  ; ,
    call pinMode     ; 
.LVL57:
.LBE35:
.LBE34:
.LBB36:
.LBB37:

Этот подход также работает в Linux и macOS, за исключением того, что пути немного отличаются, а расширение пути использует другой синтаксис. Два файла, вызывающих озабоченность, все еще находятся platform.local.txt - файл, который вы должны создать, так как он сначала не существует, и файлы ${TEMP}/cc*.ltrans.s.

,