реклама на сайте
подробности

 
 
2 страниц V   1 2 >  
Reply to this topicStart new topic
> Сохранение регистров в fies.asm IAR_AVR, Как указать компилятору на использование?
fmdost
сообщение Mar 10 2008, 01:06
Сообщение #1


Местный
***

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



Доброго времени суток Уважаемые!
Прицепил к проэкту асм файл с програмкой проверки crc. Разъясните пожалуйста, как указать компилятору на неоюходимость сохранения используемых в асм файле регистров?
Спасибо.
Файл тут.Прикрепленный файл  crc.rar ( 889 байт ) Кол-во скачиваний: 124
Go to the top of the page
 
+Quote Post
Baser
сообщение Mar 10 2008, 10:37
Сообщение #2


Просто Che
*****

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



Цитата(Т.Достоевский @ Mar 10 2008, 03:06) *
Разъясните пожалуйста, как указать компилятору на неоюходимость сохранения используемых в асм файле регистров?

Попробую принять вашу телепатограмму smile.gif
У вас есть проект на Си и функция подсчета CRC на ассме. Вам их нужно подружить. Правильно?

Если ответ положительный, то для начала функция на ассме должна удовлетворять требованиям ИАР.
Для этого подробно изучаем один раз (я это сделал 8 лет назад и до сих пор пользуюсь) раздел руководства AVR® IAR C/C++ Compiler Reference Guide - "Assembler language interface". Мне помнится, у вас были проблемы с аглицким, но нужно попытаться.

Могу расписать и подробней, но сначала вы отпишите, правильно ли я понял ваш вопрос smile.gif
Go to the top of the page
 
+Quote Post
Rst7
сообщение Mar 10 2008, 11:18
Сообщение #3


Йа моск ;)
******

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



Не пойму, какие проблемы это на Си написать?


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post
fmdost
сообщение Mar 10 2008, 15:05
Сообщение #4


Местный
***

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



Цитата(Baser @ Mar 10 2008, 13:37) *
Попробую принять вашу телепатограмму smile.gif
У вас есть проект на Си и функция подсчета CRC на ассме. Вам их нужно подружить. Правильно?...

Наверное да. Файл прикручен. Только непонятно как сохранять регистры которые используютъся в функции С из которой вызывается АСМ вставка использующая те-же регистры. Компилятор есстественно сохраняет регистры, которые используются во вложенной С функции, но с АСМ функцией так не прокатило.
То-есть как указать компилятору, что в АСМ функции используются такие-то регистры?
Например:
Код
for(i=0;i>100;i++)
  crc_asm(* pointer); // <- вот сдесь может портится(и портится) i


Цитата(Rst7 @ Mar 10 2008, 14:18) *
Не пойму, какие проблемы это на Си написать?

Use it.
Go to the top of the page
 
+Quote Post
Baser
сообщение Mar 10 2008, 15:59
Сообщение #5


Просто 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. Компилятор об этом знает, поскольку функция имеет один параметр. Это видно в тексте на си и компилятор эти регистры не применяет.
Go to the top of the page
 
+Quote Post
fmdost
сообщение Mar 10 2008, 16:23
Сообщение #6


Местный
***

Группа: Свой
Сообщений: 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 .
Go to the top of the page
 
+Quote Post
Baser
сообщение Mar 10 2008, 16:35
Сообщение #7


Просто Che
*****

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



Цитата(Т.Достоевский @ Mar 10 2008, 18:23) *
Как сделать что-бы i не портился в АСМ функции?

Дык вроде я ответил smile.gif
Чтобы i не портился, функция crc_asm(* pointer) должна сохранять (сама, то бишь ВЫ сами) все используемые в ней PRESERVED регистры R4–R15 and R24–R27. Все остальные регистры функция может портить (окромя, конечно stack pointer - R29:R28).
Go to the top of the page
 
+Quote Post
fmdost
сообщение Mar 10 2008, 16:51
Сообщение #8


Местный
***

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



bb-offtopic.gif Вот что бывает если нет конкуренции bb-offtopic.gif
Подымал сдесь тему скорость реакции на С тут. Та-же фигня была при вызове функции из прерывания. В функции используется только 1а переменная(r16) а пролог тупейше сохраняет ВСЕ регистры!!! Вот вам и 1.1 раза по сравнению с АСМ.
Скорее бы Кейл АВРом занялся, а то ИАР какой-то тошнотик.
Перепишу ка это всё на АСМ.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Mar 10 2008, 17:12
Сообщение #9


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



Цитата(Т.Достоевский @ Mar 10 2008, 18:23) *
Спасибо. По англицки читаю. Про согдлашение по передаче параметров вкурсе.
Повторяю вопрос
Повторяем ответ - читайте вдумчиво про соглашение о передаче параметров. Есть регистры, которые можно портить в функции - они сохраняются в вызывающей функции. Есть регистры, которые надо сохранять в вызываемой функции. Подумайте сами логически - нафига компилятор будет при каждом вызове функции сохранять какой-то из регистров, если он не портится в вызываемой функции. Нет уж - ваша функция знает, какие регистры портит - пусть она их (только нужные и никакие другие) и сохраняет.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
Baser
сообщение Mar 10 2008, 17:25
Сообщение #10


Просто Che
*****

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



Цитата(Т.Достоевский @ Mar 10 2008, 18:51) *
Та-же фигня была при вызове функции из прерывания. В функции используется только 1а переменная(r16) а пролог тупейше сохраняет ВСЕ регистры!!!

Насчет вызова функций в обработчике прерываний, то тут соглашусь с вами, ИАР это как-то запустил.
Мне тоже не удалось его заставить сохранять только используемые регистры. Поэтому в прерываниях под ИАРом использую только инлайн-функции (макросы).

Но что касается всего остального, то тут вы не правы sad.gif

p.s. А если настолько лень в асм функции самому сохранить в стеке регистры, то пишите функции на Си, тогда компилятор сделает это за вас - на то он и Си компилятор biggrin.gif
Go to the top of the page
 
+Quote Post
fmdost
сообщение Mar 10 2008, 17:31
Сообщение #11


Местный
***

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



Цитата(Сергей Борщ @ Mar 10 2008, 20:12) *
нафига компилятор будет при каждом вызове функции сохранять какой-то из регистров, если он не портится в вызываемой функции. Нет уж - ваша функция знает, какие регистры портит - пусть она их (только нужные и никакие другие) и сохраняет.

Нихрена он(ИАР) не знает какие надо сохранять. А если функция портит все, а вызвавшаая её функция и вся программа использует только 1 или 2 !? Зачем сохранять всё, когда можно и нужно только эти 2 ? ИАР прекрасно это делает если всё это сделано на С.
Если вызывать функцию через указатель то-же не видит, и сохраняет ВСЕ регистры, а не только те что используются в вызываемой функции.
Пробовал дефайнить по разному, надеялся что увидит, не увидил. Вот думаю а если как __интринсик, или ещё как, ну что-бы понял как свою С функцию?

Пока отвечал Сергею пропустил.
Цитата(Baser @ Mar 10 2008, 20:25) *
...под ИАРом использую только инлайн-функции (макросы).

Можно поподробней ?
Цитата
p.s. А если настолько лень в асм функции самому сохранить в стеке регистры, то пишите функции на Си, тогда компилятор сделает это за вас - на то но и Си компилятор biggrin.gif

Очень уж много сохранять придётся.
Согласен, что мои простые асм функции проще переписать на С. Но вопрос не праздный, пригодится!
Go to the top of the page
 
+Quote Post
Rst7
сообщение Mar 10 2008, 18:37
Сообщение #12


Йа моск ;)
******

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



Цитата
Use it.


Вот именно к Вам это и относится. Что такого в функциях, написанных на асме (я имею в виду файл, который подключен к сообщению), что делает невозможным прямое написание их на Си и, как результат, не парить моск вопросом связывания Си<->асм?

Цитата
В функции используется только 1а переменная(r16) а пролог тупейше сохраняет ВСЕ регистры!!! Вот вам и 1.1 раза по сравнению с АСМ.Скорее бы Кейл АВРом занялся, а то ИАР какой-то тошнотик.


И будет сохранять. Такой принцип построения компилятора. И другой компилятор действовать будет точно так же (т.е. сохранять scratch-регистры). Способ борьбы - не использовать вложенные функции в прерываниях или писать процедуры прерывания на ассемблере.

Цитата
Но вопрос не праздный, пригодится!


Почему Вы принципиально не хотите прочитать раздел, посвященный интерфейсу сишных и асмовских функций? Вдумчиво прочитать. Там все написано - есть регистры, которые можно изменять (scratch-регистры) и которые нужно приводить на выходе из процедуры в тот же вид, что и на входе. Все. Список тех и других регистров зависит от компилятора, например, в IAR AVR и GCC AVR они разные, и находится этот список в доке по компилятору.


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post
fmdost
сообщение Mar 10 2008, 19:31
Сообщение #13


Местный
***

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



Цитата(Rst7 @ Mar 10 2008, 21:37) *
...Список тех и других регистров зависит от компилятора, например, в IAR AVR и GCC AVR они разные, и находится этот список в доке по компилятору.

А разве в GCC не RTL? RTL это кажется стандарт? С GCC не работал, но там по описанию, он сам раскидывает по регистрам, и и соответственно знает какие использовал, и таих вопросов возникнуть не должно.
Интересно, почему ИАР этим брезгует?
ЗЫ. Программку уже переписал на асм.

Цитата
Вот именно к Вам это и относится...

Ну нету у меня чем possible to use

Цитата
Почему Вы принципиально не хотите прочитать раздел...

Прочёл внимательно.
Go to the top of the page
 
+Quote Post
Baser
сообщение Mar 10 2008, 21:19
Сообщение #14


Просто 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);
...

При этом препроцессор просто копирует этот код энное кол-во раз. Но оптимизатор у ИАРа очень хороший! Он находит все эти одинаковые куски кода и сам заменяет их на ОДНУ функцию. В результате получаем то, что написали бы на асме, но только написанное на Си.
Вот такой ход из-за угла smile.gif
Go to the top of the page
 
+Quote Post
Rst7
сообщение Mar 11 2008, 06:43
Сообщение #15


Йа моск ;)
******

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



Цитата
А разве в GCC не RTL? RTL это кажется стандарт? С GCC не работал, но там по описанию, он сам раскидывает по регистрам, и и соответственно знает какие использовал, и таих вопросов возникнуть не должно.


Вы хотя бы поняли, что написали?

Цитата
Интересно, почему ИАР этим брезгует?


Чем???


--------------------
"Практика выше (теоретического) познания, ибо она имеет не только достоинство всеобщности, но и непосредственной действительности." - В.И. Ленин
Go to the top of the page
 
+Quote Post

2 страниц V   1 2 >
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 20th July 2025 - 18:51
Рейтинг@Mail.ru


Страница сгенерированна за 0.01515 секунд с 7
ELECTRONIX ©2004-2016