Дизассемблер в Proteus: как получить текстовый файл?

Всем привет! Есть вопрос по Proteus. Кто знает, как скопировать/получить текстовый файл дизассемблера? То что выдаёт Протеус, скопировать не получается:

Содержимое папки Temp\VSM Studio.…\Debug:


Из этих файлов “выковырять” то что мне надо не смог.

P.S. Речь пока хотя-бы про WinAVR…

Никак, если в виде текста. А что, Ghidra этот твой процессор не понимает, что-ли?

Скинь файлики для дизассемблирования (vvb@nym.hush.com) , желательно .o или .elf. Лучше, кочнено, .o. И название процессора. А я попробую листинг получить из гидры. Может быть получится, кто знает. Файлики крошечные.

а использовать IDAPRO не вариант ?
p.s. не вникал что вы там делаете, просто предложил))) если не понятно про что я, добавьте еще Hex-Rays к поисковому запросу

Задал ваш вопрос для Arduino UNO ИИ получил довольно подробный ответ. Задавал вопрос, т.к. пользовался только методоми 1 или 3 из ответа.

Вопрос:

Как в программе Proteus с проектом на Arduino UNO получить полный ассемблерный листинг программы отдельным файлом?

Ответ ИИ

В самой среде Proteus нет одной волшебной кнопки «Экспортировать в ассемблер» для Arduino-проектов (так как Proteus использует скрытый инструментарий avr-gcc для компиляции .ino файлов в .hex).

Однако получить полный ассемблерный листинг можно несколькими способами. Выбор способа зависит от того, что именно вам нужно: просто посмотреть код при отладке или получить физический текстовый файл .asm / .lst.

Ниже приведены 3 рабочих метода.


Способ 1. Использование утилиты avr-objdump (Самый надежный)

Когда Proteus компилирует проект Arduino, он создает не только файл прошивки .hex, но и отладочный файл .elf (обычно он остается в папке с проектом или во временной папке). Из файла .elf можно «вытащить» полный ассемблерный листинг.

  1. Соберите проект в Proteus (Build Project).

  2. Найдите в папке с вашим проектом файл с расширением .elf (его имя совпадает с именем проекта).

  3. Вам понадобится утилита avr-objdump.exe. Она входит в состав Arduino IDE (путь примерно такой: C:\Program Files (x86)\Arduino\hardware\tools\avr\bin\avr-objdump.exe) или в пакете AVR Toolchain.

  4. Откройте командную строку (cmd) в папке с .elf файлом и выполните команду:

avr-objdump.exe -S -C -h -d имя_проекта.elf > listing.asm

Расшифровка флагов:

  • -S (заглавная) — смешивает ассемблерный код с исходным C/C++ кодом (очень удобно для анализа).

  • -C — декодирует (demangle) имена функций C++ (в Arduino много скрытых C++ функций, без этого флага их имена будут нечитаемыми).

  • -h — выводит заголовки секций памяти.

  • -d — дизассемблирует только секции с кодом.

  • > listing.asm — перенаправляет вывод в текстовый файл.

Итог: Вы получите файл listing.asm, который можно открыть в Блокноте, Notepad++ или любой IDE.


Способ 2. Просмотр ассемблера прямо во время отладки в Proteus

Если вам не нужен отдельный файл, а вы просто хотите видеть ассемблерные инструкции при пошаговой отладке симуляции:

  1. Загрузите прошивку в модель ATmega328P (Arduino UNO) в Proteus.

  2. Запустите симуляцию и поставьте точку останова (Breakpoint) на нужной строке C++ кода.

  3. Когда симуляция остановится, откройте окно исходного кода (Source Code).

  4. В меню окна исходного кода найдите опцию Show Assembly (Показать ассемблер) или нажмите правой кнопкой мыши по коду и выберите соответствующий пункт (в разных версиях Proteus это может быть в контекстном меню или на панели инструментов отладчика).

  5. Теперь рядом с каждой строкой C++ кода вы будете видеть соответствующие ей ассемблерные инструкции и значения регистров.


Способ 3. Через Arduino IDE (Альтернативный и очень удобный)

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

  1. В Arduino IDE зайдите в Файл → Настройки (File → Preferences).

  2. Поставьте галочку Показывать подробный вывод при компиляции (Show verbose output during: compilation).

  3. Скомпилируйте скетч. В нижнем окне лога появится путь к временной папке, где лежит скомпилированный .elf файл.

  4. Скопируйте этот .elf файл в удобное место.

  5. С помощью avr-objdump (как в Способе 1) сделайте из него .asm файл.

  6. В Proteus просто укажите путь к готовому .hex файлу (который тоже остался во временной папке Arduino IDE) в свойствах микросхемы ATmega328P.


Способ 4. Настройка флагов компилятора внутри Proteus (Для продвинутых)

Если вы принципиально хотите, чтобы Proteus сам генерировал .lst файл при нажатии кнопки Build, нужно передать компилятору avr-gcc специальные флаги.

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

  1. В окне редактора исходного кода (Source Code) перейдите в меню SourceCompiler Configuration (или нажмите правой кнопкой мыши по проекту в дереве проекта → Properties / Build settings).

  2. Найдите поле Compiler Flags (Флаги компилятора) или Additional Options.

  3. Добавьте туда следующую строку:
    -Wa,-ahlms=listing.lst

  4. Сохраните и пересоберите проект.

  5. После успешной сборки в папке с проектом появится файл listing.lst, содержащий полный листинг (исходник + ассемблер + адреса).

Резюме: Если вам нужен файл для анализа, изучения или сдачи лабораторной — Способ 1 (или 3) является стандартом индустрии для микроконтроллеров AVR. Если нужно просто отладить конкретный участок кода — используйте Способ 2.

Спасибо, но мне надо именно дизасм. того, что выдаёт Proteus. И, чтобы я мог редактировать полученный файл.
А так, нет проблем сделать то же, что ты говоришь в Arduino IDE, но это не будет 100% тот же файл.

Спасибо @BABOS , но мой ответ будет тот же, что и постом выше.

Спасибо за подробный ответ. По совету ИИ гугла, пробовал редактировать Makefile, но пока ничего не получилось(но, может это я что-то не так делал, т.к. плохо разбираюсь в написании Makefile).
Возможно, из того, что Вы предложили, мне подойдёт 1 и 4 способ.
В течении дня/ночи , попробую, отпишусь.

Способ 4 дал результат, хотя не совсем то, что нужно. Это ужe полный листинг, а не asm. Синтаксис кода asm несколько отличается от того, что я привёл в начале темы, как бы свой “диалект”)). Так же много того, чего нет в примере кода из #1: дополнительные метки, строчки…
Пример куска кода:

         	.LFB6:
  20               	.LM1:
  21               	.LVL0:
  22               	/* prologue: function */
  23               	/* frame size = 0 */
  24               	.LM2:
  25 0000 9AB3      		in r25,58-32
  26 0002 9F60      		ori r25,lo8(15)
  27 0004 9ABB      		out 58-32,r25
  28               	.LBB290:
  29               	.LBB291:
  30               	.LBB292:
  31               	.LBB293:
  32               	.LM3:
  33 0006 41E0      		ldi r20,lo8(1)
  34 0008 942F      		mov r25,r20
  35               	.LVL1:
  36               	/* #APP */
  37               	 ;  83 "c:/winavr-20100110/lib/gcc/../../avr/include/util/delay_basic.h" 1
  38 000a 9A95      		1: dec r25
  39 000c 01F4      		brne 1b
  40               	 ;  0 "" 2
  41               	/* #NOAPP */

Думаю, что HEX получается сразу из .elf, поэтому и используется такое название - диз- ассемблер - т.е. получается, как бы лишняя работа.

Подопции игнорируются, можно просто писать -Wa, -a=Listing.lst , и, ничего не изменится.
Ещё раз спасибо, но пока вопрос 100% не решённый. Будет время - ещё поковыряюсь

В Proteus не дизассемблер, а дешифратор машинных кодов …

Возможно, но когда я жму на эту кнопку


Появляется код, который мне нужен(см.#1).
Конечно, на этом варианте свет клином не сошёлся. Просто удобно - когда работаешь в Proteus, и всё под рукой…

Должен признать, что 1-й способ(objdump.exe), я, по невнимательности, забраковал, подумав, что код , выдаваемый утилитой из Ардуино ИДЕ, отличается от кода в Proteus.
Однако, посмотрев более внимательно, понял, что это тот же самый код, но просто немного по другому написан, и, более полный. Отсутствуют повторения, которые Протеус иногда выдаёт, а на месте прочерков недостающие участки кода.


Тот же код

       PORTA &= 0xF0;
  98:	9b b3       	in	r25, 0x1b	; 27
  9a:	90 7f       	andi	r25, 0xF0	; 240
  9c:	9b bb       	out	0x1b, r25	; 27
        char_data  <<=  4;
        PORTA  |= char_data >> 4;
  9e:	9b b3       	in	r25, 0x1b	; 27
  a0:	8f 70       	andi	r24, 0x0F	; 15
  a2:	98 2b       	or	r25, r24
  a4:	9b bb       	out	0x1b, r25	; 27
    can be achieved.
*/
void
_delay_loop_1(uint8_t __count)
{
	__asm__ volatile (
  a6:	84 2f       	mov	r24, r20
  a8:	8a 95       	dec	r24
  aa:	f1 f7       	brne	.-4      	; 0xa8 <LCD_Char+0x52>
         _delay_us(1);
	PORTA |= (1<<EN);	/* Enable Pulse */
  ac:	dd 9a       	sbi	0x1b, 5	; 27
    milliseconds can be achieved.
 */

Ещё сбивают с толку скобки, которые открываются, но потом не закрываются))
В общем , пока остановлюсь на этом. Конечно, хотелось бы более комфортного решения, но и это не плохо.
Всем спасибо.