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

 
 
 
Reply to this topicStart new topic
> Компилятор ICC AVR, Помогите разобраться
lolful
сообщение Sep 16 2008, 05:56
Сообщение #1


Частый гость
**

Группа: Свой
Сообщений: 106
Регистрация: 27-11-07
Из: Пермь
Пользователь №: 32 732



Логка программы. В определенном месте кода ждать пока функция не вернет "1".
Пишу:
Код
while(!URXFind_("OK", 2));
И что же происходит? Функция возвращает "1" в тот момент, когда не должна. Сейчас поясню.
Далее исправляю эту сточку на:
Код
while(!(temp = URXFind_("OK", 2)));
...и все начинает работать так, как надо. Когда надо функция возвращает "1", когда надо - "0". Что это за подводный камень? Ума не приложу как такое имеет место быть...
Go to the top of the page
 
+Quote Post
zhevak
сообщение Sep 16 2008, 06:06
Сообщение #2


Знающий
****

Группа: Свой
Сообщений: 723
Регистрация: 29-08-05
Из: Березовский
Пользователь №: 8 065



Забавный случай. Но хотелось бы видеть

1. Прототип функции URXFind_(), конкретно, что она возвращает -- bool или число?
2. Ассемблерный код обоих фрагментов.


--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
Go to the top of the page
 
+Quote Post
Палыч
сообщение Sep 16 2008, 06:11
Сообщение #3


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Возможно, это - "гримасы" оптимизации. Посмотрите ассемблерный код, который генерится в первом и втором случае. Наверное будет ясно в чем дело
Go to the top of the page
 
+Quote Post
lolful
сообщение Sep 16 2008, 06:23
Сообщение #4


Частый гость
**

Группа: Свой
Сообщений: 106
Регистрация: 27-11-07
Из: Пермь
Пользователь №: 32 732



Код
unsigned char URXFind_(unsigned char* buf, unsigned char len, unsigned char* pos);
В первом посте намеренно упустил 3й параметр. В коде он присутствует. Функция возвращает 1 или 0.

Код

while(!URXFind_("OK", 2, &temp));

0240           L51:
0240                   .dbline 125
0240           L52:
0240                   .dbline 125
0240 22E0              ldi R18,2
0242 30E0              ldi R19,0
0244 00E0              ldi R16,<L54
0246 10E0              ldi R17,>L54
0248 0E940000          xcall _URXFind_
024C 402F              mov R20,R16
024E 4423              tst R20
0250 B9F3              breq L51
0252                   .dbline 126
0252 88E0              ldi R24,8
0254 28B0              in R2,0x8
0256 2826              eor R2,R24
0258 28B8              out 0x8,R2
025A                   .dbline 127
025A 01E0              ldi R16,1


Код
while(!(temp = URXFind_("OK", 2, &temp)));

0240           L51:
0240                   .dbline 125
0240           L52:
0240                   .dbline 125
0240 22E0              ldi R18,2
0242 30E0              ldi R19,0
0244 00E0              ldi R16,<L54
0246 10E0              ldi R17,>L54
0248 0E940000          xcall _URXFind_
024C 0030              cpi R16,0
024E 0107              cpc R16,R17
0250 B9F3              breq L51
0252           X5:
0252                   .dbline 126
0252 88E0              ldi R24,8
0254 28B0              in R2,0x8
0256 2826              eor R2,R24
0258 28B8              out 0x8,R2
025A                   .dbline 127
025A 01E0              ldi R16,1
Go to the top of the page
 
+Quote Post
zhevak
сообщение Sep 16 2008, 07:21
Сообщение #5


Знающий
****

Группа: Свой
Сообщений: 723
Регистрация: 29-08-05
Из: Березовский
Пользователь №: 8 065



Здесь вопросов не возникает. Возвращаемый байт четко определяется на ноль в последовательности mov-tst-breq. Может быть Вы возвращаете не 0x00, а символ нуля '0' ?
Код

while(!URXFind_("OK", 2, &temp));

0240           L51:
0240                   .dbline 125
...
0248 0E940000          xcall _URXFind_
024C 402F              mov R20,R16
024E 4423              tst R20
0250 B9F3              breq L51

Таким образом, прога бегает по кругу до тех пор, пока функция возвращает ноль (0x00).
Все в полном соответствии с си-шным текстом.

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

while(!(temp = URXFind_("OK", 2, &temp)));

0240           L51:
0240                   .dbline 125
0248 0E940000          xcall _URXFind_
024C 0030              cpi R16,0
024E 0107              cpc R16,R17
0250 B9F3              breq L51


Скорее всего, Вы что-то не то возвращаете из функции URXFind_().
Либо сами далее разбирайтесь, либо аоказывайте ее сишный код.

Сообщение отредактировал zhevak - Sep 16 2008, 07:22


--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
Go to the top of the page
 
+Quote Post
lolful
сообщение Sep 16 2008, 07:32
Сообщение #6


Частый гость
**

Группа: Свой
Сообщений: 106
Регистрация: 27-11-07
Из: Пермь
Пользователь №: 32 732



temp - это unsigned char. Функция возвращает именно число 0 или 1, а не их ASCII-код.
Но проблема то в том, что в первом случае чушь происходит, а во втором - все отлично работает.

PS Ой-ой! Что это тут написано! temp = URXFind_("OK", 2, &temp) - temp как параметр и как возвращаемое значение. Так не должно быть, хотя на работу это не влияет.

Ладно, буду сам разбираться. Придется вспоминать ассемблер...

Сообщение отредактировал lolful - Sep 16 2008, 07:33
Go to the top of the page
 
+Quote Post
Палыч
сообщение Sep 16 2008, 07:36
Сообщение #7


Гуру
******

Группа: Свой
Сообщений: 2 399
Регистрация: 10-05-06
Из: г. Новочеркасск
Пользователь №: 16 954



Цитата(zhevak @ Sep 16 2008, 10:21) *
Скорее всего, Вы что-то не то возвращаете из функции URXFind_().
Наверное, так и есть. Поскольку ассемблерные коды отличаются только числом регистров, проверяемых на ноль: в первом случае - один регистр (R16, байт), во втором - два (R16 и R17, слово). Поскольку функция URXFind_() возвращает байт, то проверки R16 должно было бы хватать. Поскольку проверки одного байта не хватает, то с функцией URXFind_() что-то не в порядке...
Go to the top of the page
 
+Quote Post
zhevak
сообщение Sep 16 2008, 07:42
Сообщение #8


Знающий
****

Группа: Свой
Сообщений: 723
Регистрация: 29-08-05
Из: Березовский
Пользователь №: 8 065



Цитата(lolful @ Sep 16 2008, 13:32) *
temp - это unsigned char. Функция возвращает именно число 0 или 1, а не их ASCII-код.


Обратите внимание, во втором случае ветвление зависит от двубайтовой переменной
Код
024C 0030              cpi R16,0
024E 0107              cpc R16,R17

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

Удачи!

ЗЫ. Отключите всю оптимизацию нафиг, на данном этапе она только вредит.


--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
Go to the top of the page
 
+Quote Post
lolful
сообщение Sep 16 2008, 07:46
Сообщение #9


Частый гость
**

Группа: Свой
Сообщений: 106
Регистрация: 27-11-07
Из: Пермь
Пользователь №: 32 732



Бррр...Я перепутал местами ассемблерный код, когда писал 2й пост...

Вобщем вот к чему я пришел. Если написать
Код
while(!(unsigned char)(URXFind_("OK\r\n", 2, &temp)));
...то все работает. Видать компилятор думает, что функция возвратит не unsigned char, а нечто вроде int и лезет в регистр, который занят чем-то. Таким образом в обоих регистрах почти 100% вероятность того, что там будет не 0. Ошибка банальна - я не прописал прототип в заголовочном файле. Дурак. twak.gif
Go to the top of the page
 
+Quote Post
zhevak
сообщение Sep 16 2008, 07:50
Сообщение #10


Знающий
****

Группа: Свой
Сообщений: 723
Регистрация: 29-08-05
Из: Березовский
Пользователь №: 8 065



Цитата(lolful @ Sep 16 2008, 13:46) *
Бррр...Я перепутал местами ассемблерный код, когда писал 2й пост...
....
вероятность того, что там будет не 0. Ошибка банальна - я не прописал прототип в заголовочном

Бывает. smile.gif

Цитата
Дурак. twak.gif

эт-лишнее.


--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
Go to the top of the page
 
+Quote Post
lolful
сообщение Sep 16 2008, 07:52
Сообщение #11


Частый гость
**

Группа: Свой
Сообщений: 106
Регистрация: 27-11-07
Из: Пермь
Пользователь №: 32 732



Цитата(zhevak @ Sep 16 2008, 13:50) *
эт-лишнее.

Не-не. Я не отчаиваюсь. biggrin.gif В следующий раз буду умнее.

Спасибо всем за помощь.

Сообщение отредактировал lolful - Sep 16 2008, 07:55
Go to the top of the page
 
+Quote Post

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

 


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


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