|
Сохранение регистров в fies.asm IAR_AVR, Как указать компилятору на использование? |
|
|
|
Mar 10 2008, 01:06
|

Местный
  
Группа: Свой
Сообщений: 479
Регистрация: 8-05-07
Из: г. Ставрополь. Северный Кавказ. Россия
Пользователь №: 27 606

|
Доброго времени суток Уважаемые! Прицепил к проэкту асм файл с програмкой проверки crc. Разъясните пожалуйста, как указать компилятору на неоюходимость сохранения используемых в асм файле регистров? Спасибо. Файл тут.
crc.rar ( 889 байт )
Кол-во скачиваний: 124
|
|
|
|
2 страниц
1 2 >
|
 |
Ответов
(1 - 14)
|
Mar 10 2008, 10:37
|

Просто Che
    
Группа: Свой
Сообщений: 1 567
Регистрация: 22-05-07
Из: ExUSSR
Пользователь №: 27 881

|
Цитата(Т.Достоевский @ Mar 10 2008, 03:06)  Разъясните пожалуйста, как указать компилятору на неоюходимость сохранения используемых в асм файле регистров? Попробую принять вашу телепатограмму У вас есть проект на Си и функция подсчета CRC на ассме. Вам их нужно подружить. Правильно? Если ответ положительный, то для начала функция на ассме должна удовлетворять требованиям ИАР. Для этого подробно изучаем один раз (я это сделал 8 лет назад и до сих пор пользуюсь) раздел руководства AVR® IAR C/C++ Compiler Reference Guide - "Assembler language interface". Мне помнится, у вас были проблемы с аглицким, но нужно попытаться. Могу расписать и подробней, но сначала вы отпишите, правильно ли я понял ваш вопрос
|
|
|
|
|
Mar 10 2008, 15:05
|

Местный
  
Группа: Свой
Сообщений: 479
Регистрация: 8-05-07
Из: г. Ставрополь. Северный Кавказ. Россия
Пользователь №: 27 606

|
Цитата(Baser @ Mar 10 2008, 13:37)  Попробую принять вашу телепатограмму У вас есть проект на Си и функция подсчета CRC на ассме. Вам их нужно подружить. Правильно?... Наверное да. Файл прикручен. Только непонятно как сохранять регистры которые используютъся в функции С из которой вызывается АСМ вставка использующая те-же регистры. Компилятор есстественно сохраняет регистры, которые используются во вложенной С функции, но с АСМ функцией так не прокатило. То-есть как указать компилятору, что в АСМ функции используются такие-то регистры? Например: Код for(i=0;i>100;i++) crc_asm(* pointer); // <- вот сдесь может портится(и портится) i Цитата(Rst7 @ Mar 10 2008, 14:18)  Не пойму, какие проблемы это на Си написать? Use it.
|
|
|
|
|
Mar 10 2008, 15:59
|

Просто Che
    
Группа: Свой
Сообщений: 1 567
Регистрация: 22-05-07
Из: ExUSSR
Пользователь №: 27 881

|
Цитата(Т.Достоевский @ Mar 10 2008, 17:05)  ...из которой вызывается АСМ вставка... Так вы все-таки определитесь, что используете: асм вставку или функцию на асме. Это разные вещи. В файле у вас подобие функции, но как вы передаете параметры, не понятно. Код EXTERN rx_buff ... ldi r30,rx_buff Это вы так пытаетесь передать указатель?? Если вы хотите применить именно асм вставку, то там все в ручную, компилятор текста на асме не видит. Все на совести программиста. Цитата(Т.Достоевский @ Mar 10 2008, 17:05)  То-есть как указать компилятору, что в АСМ функции используются такие-то регистры? Например: Код for(i=0;i>100;i++) crc_asm(* pointer); // <- вот сдесь может портится(и портится) i Если функция, то нужно выполнять требования ИАР по передаче параметров: Calling convention. Все регистры делятся на PRESERVED & SCRATCH. SCRATCH (рабочие) R0–R3, R16–R23, and R30–R31 - их можно применять в подпрограммах без сохранения. PRESERVED (сохраняемые) R4–R15 and R24–R27 - если их применяют в подпрограмме, они должны быть сохранены и потом восстановлены. Параметры в/из функций передаются через регистры и через стек. Первый параметр передается через R19:R18:R17:R16. Второй параметр через R23:R22:R21:R20. Остальные (если есть) через стек. Впрочем, это хорошо расписано в хелпе. Кстати, есть программы-переводчики, напр. наш PROMT, которые даже в Lite версии отлично переводят. Вот вам рабочий пример функции на асме в си программе: func.asm Код ;===============================================================; ; Delay 100 mks * time (max: 6.55 sec; Clock: 7.3728 MHz) ; ; __version_1 void Wait100mks(unsigned int time); ; ;===============================================================; PUBLIC Wait100mks Wait100mks: ldi r18, 244
wait2: dec r18 brne wait2
subi r16, 1 sbci r17, 0 mov r18, r16 or r18, r17 brne Wait100mks ret defines.h Код extern __version_1 void Wait100mks(unsigned int time); code.c Код while (1) // Wait Watchdog RESET { poGreenLED = 1; Wait100mks(1000); // 100 ms poGreenLED = 0; Wait100mks(2000); // 200 ms } Двухбайтовый unsigned int time передается через R17:R16. Компилятор об этом знает, поскольку функция имеет один параметр. Это видно в тексте на си и компилятор эти регистры не применяет.
|
|
|
|
|
Mar 10 2008, 16:23
|

Местный
  
Группа: Свой
Сообщений: 479
Регистрация: 8-05-07
Из: г. Ставрополь. Северный Кавказ. Россия
Пользователь №: 27 606

|
Спасибо. По англицки читаю. Про согдлашение по передаче параметров вкурсе. Повторяю вопрос Код main() { unsigned char i; for(i=0;i>100;i++) crc_asm(* pointer); // <- вот сдесь может портится(и портится) i } Как сделать что-бы i не портился в АСМ функции? Например crc_asm() использует ВСЕ доступные регистры, а main() только 1, в котором хранится i. Очень бы хотелось, что-бы ИАР САМ решил что из регистров надо сохранять. А то выходит, что в АСМ функции придётся сохранять ВСЕ используемые в ней же регистры, или ковырять листинг всей main() на предмет выискивания регистра в котором хранится i .
|
|
|
|
|
Mar 10 2008, 16:51
|

Местный
  
Группа: Свой
Сообщений: 479
Регистрация: 8-05-07
Из: г. Ставрополь. Северный Кавказ. Россия
Пользователь №: 27 606

|
 Вот что бывает если нет конкуренции Подымал сдесь тему скорость реакции на С тут. Та-же фигня была при вызове функции из прерывания. В функции используется только 1а переменная(r16) а пролог тупейше сохраняет ВСЕ регистры!!! Вот вам и 1.1 раза по сравнению с АСМ. Скорее бы Кейл АВРом занялся, а то ИАР какой-то тошнотик. Перепишу ка это всё на АСМ.
|
|
|
|
|
Mar 10 2008, 17:31
|

Местный
  
Группа: Свой
Сообщений: 479
Регистрация: 8-05-07
Из: г. Ставрополь. Северный Кавказ. Россия
Пользователь №: 27 606

|
Цитата(Сергей Борщ @ Mar 10 2008, 20:12)  нафига компилятор будет при каждом вызове функции сохранять какой-то из регистров, если он не портится в вызываемой функции. Нет уж - ваша функция знает, какие регистры портит - пусть она их (только нужные и никакие другие) и сохраняет. Нихрена он(ИАР) не знает какие надо сохранять. А если функция портит все, а вызвавшаая её функция и вся программа использует только 1 или 2 !? Зачем сохранять всё, когда можно и нужно только эти 2 ? ИАР прекрасно это делает если всё это сделано на С. Если вызывать функцию через указатель то-же не видит, и сохраняет ВСЕ регистры, а не только те что используются в вызываемой функции. Пробовал дефайнить по разному, надеялся что увидит, не увидил. Вот думаю а если как __интринсик, или ещё как, ну что-бы понял как свою С функцию? Пока отвечал Сергею пропустил. Цитата(Baser @ Mar 10 2008, 20:25)  ...под ИАРом использую только инлайн-функции (макросы). Можно поподробней ? Цитата p.s. А если настолько лень в асм функции самому сохранить в стеке регистры, то пишите функции на Си, тогда компилятор сделает это за вас - на то но и Си компилятор  Очень уж много сохранять придётся. Согласен, что мои простые асм функции проще переписать на С. Но вопрос не праздный, пригодится!
|
|
|
|
|
Mar 10 2008, 18:37
|

Йа моск ;)
     
Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610

|
Цитата Use it. Вот именно к Вам это и относится. Что такого в функциях, написанных на асме (я имею в виду файл, который подключен к сообщению), что делает невозможным прямое написание их на Си и, как результат, не парить моск вопросом связывания Си<->асм? Цитата В функции используется только 1а переменная(r16) а пролог тупейше сохраняет ВСЕ регистры!!! Вот вам и 1.1 раза по сравнению с АСМ.Скорее бы Кейл АВРом занялся, а то ИАР какой-то тошнотик. И будет сохранять. Такой принцип построения компилятора. И другой компилятор действовать будет точно так же (т.е. сохранять scratch-регистры). Способ борьбы - не использовать вложенные функции в прерываниях или писать процедуры прерывания на ассемблере. Цитата Но вопрос не праздный, пригодится! Почему Вы принципиально не хотите прочитать раздел, посвященный интерфейсу сишных и асмовских функций? Вдумчиво прочитать. Там все написано - есть регистры, которые можно изменять (scratch-регистры) и которые нужно приводить на выходе из процедуры в тот же вид, что и на входе. Все. Список тех и других регистров зависит от компилятора, например, в IAR AVR и GCC AVR они разные, и находится этот список в доке по компилятору.
--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
|
|
|
|
|
Mar 10 2008, 19:31
|

Местный
  
Группа: Свой
Сообщений: 479
Регистрация: 8-05-07
Из: г. Ставрополь. Северный Кавказ. Россия
Пользователь №: 27 606

|
Цитата(Rst7 @ Mar 10 2008, 21:37)  ...Список тех и других регистров зависит от компилятора, например, в IAR AVR и GCC AVR они разные, и находится этот список в доке по компилятору. А разве в GCC не RTL? RTL это кажется стандарт? С GCC не работал, но там по описанию, он сам раскидывает по регистрам, и и соответственно знает какие использовал, и таих вопросов возникнуть не должно. Интересно, почему ИАР этим брезгует? ЗЫ. Программку уже переписал на асм. Цитата Вот именно к Вам это и относится... Ну нету у меня чем possible to use Цитата Почему Вы принципиально не хотите прочитать раздел... Прочёл внимательно.
|
|
|
|
|
Mar 10 2008, 21:19
|

Просто Che
    
Группа: Свой
Сообщений: 1 567
Регистрация: 22-05-07
Из: ExUSSR
Пользователь №: 27 881

|
Цитата(Т.Достоевский @ Mar 10 2008, 19:31)  (Baser @ Mar 10 2008, 20:25) ...под ИАРом использую только инлайн-функции (макросы).
Можно поподробней ? Можно... Как я уже писал, в ИАРе лучше не применять функции в обработчиках прерывания, т.к. компилятор не считает нужным отслеживать применяемые в функции регистры и сохраняет ВСЕ scratch-регистры. А нужда применить бывает. Пример - то же вычисление CRC для приема и передачи в нескольких местах. Поэтому я эту функцию пишу как макрос и далее спокойно применяю в различных прерываниях столько, сколько мне нужно: Код #define RS_ByteCRC(byte) \ { \ (byte) ^= CRC16.C[0]; \ (byte) ^= ((byte) << 4); \ CRC16.C[0] = CRC16.C[1] ^((byte) >> 4) ^ ((byte) << 3); \ CRC16.C[1] = (byte) ^ (((byte) >> 4) >> 1); \ } ... RS_ByteCRC(data); ... При этом препроцессор просто копирует этот код энное кол-во раз. Но оптимизатор у ИАРа очень хороший! Он находит все эти одинаковые куски кода и сам заменяет их на ОДНУ функцию. В результате получаем то, что написали бы на асме, но только написанное на Си. Вот такой ход из-за угла
|
|
|
|
|
Mar 11 2008, 06:43
|

Йа моск ;)
     
Группа: Модераторы
Сообщений: 4 345
Регистрация: 7-07-05
Из: Kharkiv-city
Пользователь №: 6 610

|
Цитата А разве в GCC не RTL? RTL это кажется стандарт? С GCC не работал, но там по описанию, он сам раскидывает по регистрам, и и соответственно знает какие использовал, и таих вопросов возникнуть не должно. Вы хотя бы поняли, что написали? Цитата Интересно, почему ИАР этим брезгует? Чем???
--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|