Перейти к содержанию
    

WinAVR криво собирает код...

Я б выбрал для симуляции другой камень типа м168, чтоб разрешить jmp

 

Никакого криминала, чистая математика.

Пользовался rjmp, представляя себе простую модель перехода +/- 2кслов с 13-разр РС. И никаких проблем, пока не увидел, что пишет objdump :)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Было бы просто замечательно, если бы кто-то из глубоко вникших в AVR-GCC, посоветовал, как отключить (избежать, обойти) эту фичу с переходами "вне пространства адресов".
2) -mno-wrap

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Уважаемый Сергей Борщ!

Я прочитал в документации про опцию -mno-wrap - это, как я надеялся, и есть решение проблемы. НО! я так и не смог ею воспользоваться! не смотря на то, что вызов avr-gcc.exe --target-help подтверждает поддержку этой опции, компиляция всегда завершается ошибкой:

make all

Building file: ../bground.c

Invoking: AVR Compiler

avr-gcc -Wall -g3 -Os -fpack-struct -fshort-enums -std=gnu99 -funsigned-char -funsigned-bitfields -mno-wrap -mmcu=atmega8 -DF_CPU=8000000UL -MMD -MP -MF"bground.d" -MT"bground.d" -c -o"bground.o" "../bground.c"

cc1.exe: error: unrecognized command line option "-mno-wrap"

make: *** [bground.o] Error 1

не будете ли вы так любезны пояснить, в чем мое заблуждение?

 

P.S. работаю с WinAVR 20091303

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Я прочитал в документации про опцию -mno-wrap - это, как я надеялся, и есть решение проблемы. НО! я так и не смог ею воспользоваться! не смотря на то, что вызов avr-gcc.exe --target-help подтверждает поддержку этой опции, компиляция всегда завершается ошибкой:
Вообще-то это ключ ассемблера, в мануалах он описан в binutils/as

 

-mmcu= пробрасывается из gcc всем вызываемым проходам, видать и этот тоже, хотя он нужен только ассемблеру, так что надо явно указать -Wa,-mno-wrap

 

Возможно, без этого ключа ассемблер форимрует такую запись в объектнике, что линкер после вычисления разности текущего адреса и адреса перехода игнорирует не влазящие в поле смещения в команде биты, если они все единички, т.е. если "сворачивание" проходит. А с этим ключом такого не делает и линкер ругается на превышение диапазона.

Я не разбирался, так как для меня эта тема не актуальна.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вообще-то это ключ ассемблера, в мануалах он описан в binutils/as

 

-mmcu= пробрасывается из gcc всем вызываемым проходам, видать и этот тоже, хотя он нужен только ассемблеру, так что надо явно указать -Wa,-mno-wrap

 

Возможно, без этого ключа ассемблер форимрует такую запись в объектнике, что линкер после вычисления разности текущего адреса и адреса перехода игнорирует не влазящие в поле смещения в команде биты, если они все единички, т.е. если "сворачивание" проходит. А с этим ключом такого не делает и линкер ругается на превышение диапазона.

Я не разбирался, так как для меня эта тема не актуальна.

если его передать ассемблеру явно -Wa,-mno-wrap - вообще никаких изменений не наблюдается - код получается 100% прежним. судя по всему, no-wrap понимается как использование "медленных" инструкций "дальних" переходов JMP/CALL, которые в меге8 не присутствуют... но ведь цепочка коротких RJMP вкупе с одним RCALL ничем не хуже! я надеюсь, что это действительно так... хотя вот здесь, похоже, над такой идеей посмеиваются... (извините за мой промптовый английский)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

если его передать ассемблеру явно -Wa,-mno-wrap - вообще никаких изменений не наблюдается - код получается 100% прежним
Да, действительно, объектники совпадают побитово.

 

судя по всему, no-wrap понимается как использование "медленных" инструкций "дальних" переходов JMP/CALL, которые в меге8 не присутствуют... но ведь цепочка коротких RJMP вкупе с одним RCALL ничем не хуже! я надеюсь, что это действительно так...
Это всё-таки ключ ассемблера, с одной стороны, а он в генерации кода "от себя" не замечен. С другой - для объектов из разных модулей вообще неизвестно кто кроме линкера (но у него этого *) ключа нет) и как должен промежуточные переходы вставлять.

 

 

*) при том, что мне эта тема малоинтересна :-) в попытках что-то понять обнаружил у линкера интересный ключ:

--pmem-wrap-around=<val> Make the linker relaxation machine assume that a program counter wrap-around occures at address <val>. Supported values are 8k, 16k, 32k and 64k.
Т.е. когда он при --relax заменяет jump -> rjmp, call -> rcall - разрешить ему делать сворачивание по заданному модулю.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

*) при том, что мне эта тема малоинтересна :-) в попытках что-то понять обнаружил у линкера интересный ключ:

 

В аврстудии при настройке avrasm есть аналогичный параметр, но менее гибкий (только на 4к), насколько это позволено в инструкции rjmp/rcall

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

ARV, а Proteus версии у вас какой? Пробегавший мимо 7.4 SP3 Build 6792 нормально съел *.hex с:

        PORTD ^= 1;
ae4:    82 b3           in    r24, 0x12; 18
ae6:    89 27           eor    r24, r25
ae8:    82 bb           out    0x12, r24; 18
aea:    bc ca           rjmp    .-2696  ; 0x64 <main+0x6>

Т.е. "rjmp .-2696" его нисколько не смутил, простенькая программа работала.

Однако, если я увеличивал размер кода nop'ами (вставлял nop до rjmp), то в какой-то момент он переставал запускать симуляцию, и при этом ошибку не выдавал в чем дело (в логе 10 штук ОК и на инициализации МК полный превед...) :wassat:

Изменено пользователем SysRq

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

протеус у меня точно такой же.

я активно применяю возможности форматированного ввода-вывода, а это однозначно прибавляет до 2-3К кода, поэтому порой буквально один новый оператор в программе приводит к тому, что вход в main оказывается "далеко" от кода инициализации (секции .init*), avr-gcc генерирует "хитрые" переходы, которые протеус отвергает. я понимаю, что виноват протеус, но, блин, надо же как-то выкрутиться... теоретически можно как-то поколдовать скриптами линкера, изменив порядок следования модулей, но ведь это решение не универсальное...

 

off: протеус - как наркотик: один вред, а подсаживает с первой пробы, всерьез и надолго :(

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Т.е. "rjmp .-2696" его нисколько не смутил,

О чем Вы поете? Оно ж пишет rjmp в байтах, а не в словах! А нам, чтобы добиться глюка, надо получить адрес > 4096 байт. В противном случае вообще ни один rjmp не работал бы.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

с -mno-wrap вообще странность какая-то... вот сейчас выбрал target Atmega32, в которой имеются и RJMP и JMP. по умолчанию всюду используются трехсловные JMP. куда опцию -mno-wrap не лепил - и в командную строку avr-gcc, и непосредственно ассемблеру передавал через -Wa - ноль эффекта! результаты 100% одинаковые всегда.

-relax успешно заменяет JMP на RJMP, оставляя при этом одно слово пустым, т.е. скорость исполнения возрастает...

 

кстати, глюка-то в GCC и нет - выше было рассказано, как оно работает... это протеусу не нравится, когда с адреса, скажем, 0x100 происходит RJMP .-2000... протеус уверен, что в результате попадем в точку где-то дааааалеко за имеющимися 8 или 32К... т.е. не учитывает аппаратное маскирование старших битов PC...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

-relax успешно заменяет JMP на RJMP, оставляя при этом одно слово пустым, т.е. скорость исполнения возрастает...
Это в векторах, там по другому нельзя. А в остальном коде можно команды сдвинуть и размер прошивки уменьшается.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

... Народ !!! У меня еще прикольнее...

 

Понадобилось мне написать код для маленького и простого 2313... 2 кб...

 

Я обычно как делаю : в процессе отладки когда памяти становится "мало-мало" беру *.lss файл и

оптимизирую код уже сам - в ручную...

 

Последняя версия, то биш 20090313 сжал мне в 900 байт...

 

20080610 более старый в 950 байт...

 

а самый старый 20070525 сжал и "дал" самый с моей точки зрения хороший и грамотный код в 760 байт.

Работоспособный ! Отлично оптимизированный. и *.lss файл ровный без "глюков"... а самый последний

20090313 наворочал и код кривой, и коментарии не в попад...

Мне вот интересно стало, это что ? Типа как с "виндой" что-ли много памяти - Атмеги64 и 128-е и дальше

разжижают мозги создателям компиляторов ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Атмеги64 и 128-е и дальше разжижают мозги создателям компиляторов ?

Ну не компиляторов а в основном одного компилятора, да и его создателей особо и не найдешь - абстрактному среднему писателю GCC лишь-бы непрерывно монстреющий Linux собирался и более ничего особо не надо :(.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

... Народ !!! У меня еще прикольнее...

 

Понадобилось мне написать код для маленького и простого 2313... 2 кб...

 

Я обычно как делаю : в процессе отладки когда памяти становится "мало-мало" беру *.lss файл и

оптимизирую код уже сам - в ручную...

 

Последняя версия, то биш 20090313 сжал мне в 900 байт...

 

20080610 более старый в 950 байт...

 

а самый старый 20070525 сжал и "дал" самый с моей точки зрения хороший и грамотный код в

...

1) winavr он же GCC, перешёл с версии 3.xxx на версию 4.xxx

2) GCC имеет свой цикл разработки. существуют 2 основных ветки:

а) текущий релиз. в нём архитектуру не меняют, только правят баги и делают небольшие косметические правки. понятно, что со временем эта версия вылизывается практически до идеала. однако т.к. заложенные подходы в компилятор являются немного устаревшими принципиально новые вещи в этой ветке не реализуются.

б) ветка разработки, в неё добавляют самые последние технологии компиляторостроения, закладывается достаточно большой запас прочности и потенциал для развития, учитываются современные технологии процессоров и.т.п. Однако т.к. эта ветка самая "свежая", когда она становится "текущим релизом" в ней есть места, которые на практике надо дорабатывать. С временем она раскрывает весь свой потенциал, пока разрабатывают уже новые подходы и т.д.

3) приоритеты в новых компиляторах немного меняются. например в современных контроллерах много флеша, поэтому размер кода обычно не так критичен как скорость выполнения, более линейных код.

4) мега8 стоит практически столько-же как и т2313, а может уже и меньше. а возможностей гораздо больше.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...