aivs 0 12 марта, 2013 Опубликовано 12 марта, 2013 · Жалоба Написал тестовую программу на Ассемблере и Си для Attiny2313. Программа элементарна, при нажатии на кнопку загорается светодиод, при отпускании гасится. Вот код на ассемблере: ;########################################## ;## Нажатие на кнопку включает светодиод ## ;########################################## .include "/usr/share/avra/includes/tn2313def.inc" ; Подключаем файл описаний .list ; Включаем листинг .def temp = R16 ; Определение главного рабочего регистра .cseg ; Выбор сегмента программного кода .org 0 ; Установка текущего адреса на 0 ldi temp, RAMEND ; Записываем адрес вершины стека в регистр temp out SPL, temp ; Записываем адрес вершины стека из регистра temp в регистр стека ldi temp, 0 ; Записываем 0 в регистр temp out DDRD, temp ; Записываем 0 из регистра temp в DDRD (порт PD на ввод - кнопка) ldi temp, 0b11111111; Записываем 11111111 в регистр temp out DDRB, temp ; Записываем 11111111 из регистра temp в DDRB (порт PB на вывод - LED) out PORTB, temp ; Записываем 11111111 из temp в PORTB (тушим светодиод) out PORTD, temp ; Записываем 11111111 из temp в PORTD (включаем внутр. резистры) ;--------------- Основной цикл ---------------------; main: in temp, PIND ; Читаем содержимое порта PD out PORTB, temp ; Записываем содержимое temp в порт PB rjmp main ; Переход к началу программы Затем я дизассемблирил HEX файл, получился точно такой же код: 00000000 <.sec1>: 0: 0f ed ldi r16, 0xDF ; 223 2: 0d bf out 0x3d, r16 ; 61 4: 00 e0 ldi r16, 0x00 ; 0 6: 01 bb out 0x11, r16 ; 17 8: 0f ef ldi r16, 0xFF ; 255 a: 07 bb out 0x17, r16 ; 23 c: 08 bb out 0x18, r16 ; 24 e: 02 bb out 0x12, r16 ; 18 10: 00 b3 in r16, 0x10 ; 16 12: 08 bb out 0x18, r16 ; 24 14: fd cf rjmp .-6 ; 0x10 Вот код на Си: /**************************************** * Prog1.c * Нажатие на кнопку включает светодиод ****************************************/ #include <avr/io.h> #include <avr/iotn2313.h> void main(void) { DDRB = 0b11111111; // Во всех разрядах регистра DDRB единицы --> все разряды PB работают на вывод (LED) PORTB = 0b11111111; // Во всех разрядах PB единицы и все разряды регистра DDRB работаю на вывод --> тушим Led DDRD = 0b00000000; // Во всех разрядах регистра DDRD нули --> все разряды PD работают на ввод (кнопка) PORTD = 0b11111111; // Во всех разрядах PD единицы и все разряды регистра DDRD работаю на ввод --> подключаем внутренние резистры // Вечный цикл while (1) { PORTB = PIND; } } После дизассемблера вид такой: 00000000 <.sec1>: 0: 12 c0 rjmp .+36 ; 0x26 2: 17 c0 rjmp .+46 ; 0x32 4: 16 c0 rjmp .+44 ; 0x32 6: 15 c0 rjmp .+42 ; 0x32 8: 14 c0 rjmp .+40 ; 0x32 a: 13 c0 rjmp .+38 ; 0x32 c: 12 c0 rjmp .+36 ; 0x32 e: 11 c0 rjmp .+34 ; 0x32 10: 10 c0 rjmp .+32 ; 0x32 12: 0f c0 rjmp .+30 ; 0x32 14: 0e c0 rjmp .+28 ; 0x32 16: 0d c0 rjmp .+26 ; 0x32 18: 0c c0 rjmp .+24 ; 0x32 1a: 0b c0 rjmp .+22 ; 0x32 1c: 0a c0 rjmp .+20 ; 0x32 1e: 09 c0 rjmp .+18 ; 0x32 20: 08 c0 rjmp .+16 ; 0x32 22: 07 c0 rjmp .+14 ; 0x32 24: 06 c0 rjmp .+12 ; 0x32 26: 11 24 eor r1, r1 28: 1f be out 0x3f, r1 ; 63 2a: cf ed ldi r28, 0xDF ; 223 2c: cd bf out 0x3d, r28 ; 61 2e: 02 d0 rcall .+4 ; 0x34 30: 09 c0 rjmp .+18 ; 0x44 32: e6 cf rjmp .-52 ; 0x0 34: 8f ef ldi r24, 0xFF ; 255 36: 87 bb out 0x17, r24 ; 23 38: 88 bb out 0x18, r24 ; 24 3a: 11 ba out 0x11, r1 ; 17 3c: 82 bb out 0x12, r24 ; 18 3e: 80 b3 in r24, 0x10 ; 16 40: 88 bb out 0x18, r24 ; 24 42: fd cf rjmp .-6 ; 0x3e 44: f8 94 cli 46: ff cf rjmp .-2 ; 0x46 Меня интересует, что это за множество переходов в начале, для чего их делает компилятор? Компилирую так: avr-gcc -O2 -Os -mmcu=attiny2313 -o Prog1.elf Prog1..c avr-objcopy -R .eeprom -O ihex Prog1.elf Prog1.hex Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
haker_fox 61 12 марта, 2013 Опубликовано 12 марта, 2013 · Жалоба Меня интересует, что это за множество переходов в начале, для чего их делает компилятор? Похоже на таблицу векторов прерываний. З.Ы. Компилировать лучше с использованием специального скрипта - Makefile. Редко компилятору нужно задавать менее двух - трех ключей. Следовательно их много, и проще воспользоваться предназначенным для этого файлом, где все это удобно и четко прописано. Оптимизации в подавляющем большинстве достаточно -Os. Возможно она удалит неиспользуемую таблицу векторов. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
arttab 0 13 марта, 2013 Опубликовано 13 марта, 2013 · Жалоба а если еще оптимизацию по размеру включить... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Палыч 10 13 марта, 2013 Опубликовано 13 марта, 2013 · Жалоба Похоже на таблицу векторов прерываний. ... Возможно она удалит неиспользуемую таблицу векторов. Это таблица векторов прерываний и есть. Оптимизация не удалит строки в неиспользуемой части таблицы, поскольку это - своеобразная защита "от дурака" на случай если программист случайно разрешит какое-либо прерывание, а соответствующий обработчик написать забудет. Конечно, при столь маленькой программе "лишние" несколько десятков байт в программе "смотрятся" несколько удивительно, но: 1. При "нормальной" программе эти "лишние" байты - капля в море. 2. Программа на языке высокого уровня при любой оптимизации будет несколько "хуже" программы на ассемблере. Но время на разработку, отладку и сопровождение ПО уменьшается в разы. Отдельные части программы можно написать и на ассемблере (если это необходимо). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aivs 0 13 марта, 2013 Опубликовано 13 марта, 2013 (изменено) · Жалоба То что код на Си всегда будет больше чем на ассемблере это понятно. Конкретно эту таблицу векторов прерываний как удалить из этой прошраммы? Или если дайте почитать про так написать Makefile с нужными опциМи компиляции. Свои примеры приветствуются! Изменено 13 марта, 2013 пользователем aivs Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Сергей Борщ 143 13 марта, 2013 Опубликовано 13 марта, 2013 · Жалоба Конкретно эту таблицу векторов прерываний как удалить из этой программы? 1)Взять тут файл стартапа. 2)Отредактировать его, выкинув лишнее. 3)Ассемблировать. 4)Слинковать с основным модулем добавив линкеру ключ -nostartfiles. 5)Немного дописать основную программу 6)Убить кучу времени пытаясь понять, почему она перестала работать 7)Понять, что в п.2 удалили лишнее :) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg_spb 0 13 марта, 2013 Опубликовано 13 марта, 2013 · Жалоба +1 Сейчас как раз идёт активное обсуждение добавления нового ключика к компилятору чтобы он сам использовал свободные вектора под код или данные для своего усмотрения. Есть даже нечто рабочее в виде патча. Но до коммита в транк ещё видимо очень далеко. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Ruslan1 17 13 марта, 2013 Опубликовано 13 марта, 2013 · Жалоба Написал тестовую программу на Ассемблере и Си для Attiny2313. Программа элементарна, при нажатии на кнопку загорается светодиод, при отпускании гасится. Вот код на ассемблере: ..... Затем я дизассемблирил HEX файл, получился точно такой же код: .... Для начала, нужно вернуться к истокам и разобраться, почему "Дизасемблированный HEX файл" из "программы на Ассемблере" дает "точно такой же код". После этого нужно ответить на вопрос, почему дизассемблированный HEX файл, полученный в результате компиляции из C, содержит другие команды чем исходный Си текст. И только после этого можно приступать к решению проблемы, которую Вы подняли. Это базовые знания. Без этого понимания сложно что-то делать. Повторять чужое-можно, делать свое хорошего качества и понимать почему результат такой- не получится. Кстати, еще полезно задуматься о том, а зачем Вам эта оптимизация по размеру? как самоцель? Оптимизация должна быть аргументированная и производиться с какой-то целью (например, для достижения необходимой скорости реакции, времени выполнения, размера программы). Просто так оптимизировать чтобы было оптимально- это бесконечный и никому не нужный процесс. 2. Программа на языке высокого уровня при любой оптимизации будет несколько "хуже" программы на ассемблере. Но время на разработку, отладку и сопровождение ПО уменьшается в разы. Отдельные части программы можно написать и на ассемблере (если это необходимо). Например, у компиляторов есть такая интересная оптимизация как "Procedural Abstraction". Так оно иногда такие хитрые финты выкидывает по многократному использованию кода, что в здравом уме на ассме долго думать придется чтобы такой компактности достичь :) Про "в разы меньше времени на Си чем на ассме"- это Вы не правы. Не в разы, а в тысячи и миллионы раз легче, особенно если речь идет о сопровождении (Само собой, я не говорю о лампочке). Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
aivs 0 13 марта, 2013 Опубликовано 13 марта, 2013 · Жалоба Оптимизация ради обучения, цель - знания. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
SyncLair 0 13 марта, 2013 Опубликовано 13 марта, 2013 · Жалоба 1)Взять тут файл стартапа. 2)Отредактировать его, выкинув лишнее. 3)Ассемблировать. 4)Слинковать с основным модулем добавив линкеру ключ -nostartfiles. 5)Немного дописать основную программу 6)Убить кучу времени пытаясь понять, почему она перестала работать 7)Понять, что в п.2 удалили лишнее :) полностью поддерживаю, особенно пункт 7 вас должен натокнуть на мысль о том что не стоит оптимизировать что-либо пока вы не достигли размера flash. Вам для чего выйгрыш в нескольких десятках байт? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
vvs157 0 13 марта, 2013 Опубликовано 13 марта, 2013 · Жалоба а в тысячи и миллионы раз легче, особенно если речь идет о сопровождении (Само собой, я не говорю о лампочке).То есть Вы утверждаете, что потратите час на написание или сопровожддение некого кода на С, а тот же код на асме (применительно к 8 бит Атмелу, а не GUI или СУБД больших машинах) будет отработан за 10е6 часов то есть 114 лет? Что-то неверится. Применительно к "мелким" 8 бит МК может и не нескольких раз не набраться. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
adnega 11 13 марта, 2013 Опубликовано 13 марта, 2013 · Жалоба То есть Вы утверждаете, что потратите час на написание или сопровожддение некого кода на С, а тот же код на асме (применительно к 8 бит Атмелу, а не GUI или СУБД больших машинах) будет отработан за 10е6 часов то есть 114 лет? Что-то неверится. Применительно к "мелким" 8 бит МК может и не нескольких раз не набраться. Скорее так: нужно по-быстрому поменять несколько мест в нескольких программах (объемом 10К строк). Может алгоритм поменять, может тип данных, структурку и т.п. На C такие действия тривиальны, на ASM врагу не пожелаешь)) Да, и к Ctrl-C, Ctrl-V вариант C дружественнее... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Артём__ 0 13 марта, 2013 Опубликовано 13 марта, 2013 · Жалоба пункт 7 вас должен натокнуть на мысль о том что не стоит оптимизировать что-либо пока вы не достигли размера flash. Не стоит отпимизировать... Гораздо лучше вести проект с выключенной оптимизацией и когда он достигнет размера flash (килобайт 100-200) вдруг возникнет необходимость ещё в десятке-другом кБ, а его и нет... И вы окажетесь с проектом на несколько десятков тысяч строк кода, который неизвестно как себя поведёт при включённой оптимизации. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
arttab 0 14 марта, 2013 Опубликовано 14 марта, 2013 · Жалоба оптимизация на С, С++ дает хорошую экономию места, но некоторые места (например дрыганье выводами) приходиться "защищать" от оптимизации, иначе компилятор может выкинуть часть кода. с ассемблерном много возни, особенно на переходы с близких на дальние. были проекты до 8К асм с каруселькой на 7 процессов Итого: если плохо знаешь свой инструментарий, то будет плохо, иначе наоборот Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
MaxiMuz 0 23 апреля, 2013 Опубликовано 23 апреля, 2013 · Жалоба Например, у компиляторов есть такая интересная оптимизация как "Procedural Abstraction". Так оно иногда такие хитрые финты выкидывает по многократному использованию кода, что в здравом уме на ассме долго думать придется чтобы такой компактности достичь :) а можно про эту штуку поподробнее ? есть ли она на avr-gcc и если да, то где она включается ? Спасибо) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться