|
Что это фича или баг?, avr-gcc 4.1.2 WinAvr 20070525 |
|
|
|
Dec 1 2008, 07:46
|

Местный
  
Группа: Свой
Сообщений: 370
Регистрация: 7-11-06
Пользователь №: 22 035

|
Столкнулся с очень интересным эффектом. Есть два кода, с моей точки зрения, которые должны работать идентично. Но первый случай не работает, второй работает безупречно. Код tty ? (UDR1 = data) : (UDR0 = data);
disasm code: +000023EA: 91E010C5 LDS R30,0x10C5 Load direct from data space +000023EC: 91F010C6 LDS R31,0x10C6 Load direct from data space +000023EE: 0FE9 ADD R30,R25 Add without carry +000023EF: 1DF1 ADC R31,R1 Add with carry +000023F0: 8180 LDD R24,Z+0 Load indirect with
+000023F1: 938000CE STS 0x00CE,R24 Store direct to data space +000023F3: 918000CE LDS R24,0x00CE Load direct from data space Код if (tty > 0) UDR1 = data; else UDR0 = data;
disasm come: +000023E8: 91E010C5 LDS R30,0x10C5 Load direct from data space +000023EA: 91F010C6 LDS R31,0x10C6 Load direct from data space +000023EC: 0FE9 ADD R30,R25 Add without carry +000023ED: 1DF1 ADC R31,R1 Add with carry +000023EE: 8180 LDD R24,Z+0 Load indirect with
+000023EF: 938000CE STS 0x00CE,R24 Store direct to data space При дизасме в первом случае, вижу на мой взгляд абсолютно бесполезную строчку Код LDS R24,0x00CE Load direct from data space но которая(мне кажется) ломает функционал uart начисто (проявляется следующим образом: из регистра приёмника вычитывается байт, который был вычитан до этого. То есть вижу иногда в общем пакете по два одинаковых байта). Кто-нибудь может пояснить значение этой строчки??? Рботающий и неработающий коды отличаются только ей. И чем собственно коснтрукция ? : ; для компилятора отличается от if else?
|
|
|
|
|
 |
Ответов
|
Dec 1 2008, 08:21
|

Местный
  
Группа: Свой
Сообщений: 370
Регистрация: 7-11-06
Пользователь №: 22 035

|
Цитата(forever failure @ Dec 1 2008, 11:00)  В первом случае в условии проверка на ненулевое значение, а во втором - на положительное. Может в этом разница ? Да собственно говоря в if можно и на равенство 0 проверять, асм будет такой же (постоянство радует  ). Меня просто напрягает, свободное обращение с регистром уарта UDR. Ведь и запись и чтение этого регистра запускают определённые физические процессы в уарте. А тут захотелось ему, он взял и вычитал значение из этого регистра в R24. Неприятное явление. ЗЫ В IAR и тот и другой случаи работают нормально. Цитата(Непомнящий Евгений @ Dec 1 2008, 11:09)  ? : возвращает результат, if else - нет. Больше вроде бы ничем.
Собственно в строчке LDS R24,0x00CE , насколько я понял, и возвращается результат операции UDR1 = data. 0x00CE это адрес UDR регистра, я не понимаю как это строчка может сообщать о результате операции.  Цитата(_Pasha @ Dec 1 2008, 11:10)  Нескромный вопрос: tty у Вас volatile? Просто не могу себе представить ситуацию, когда селектором устройств является не volatile переменная... К моему стыду действительно не volatile. Эта переменная часть структуры, описывающей уарт Код typedef struct { /** \brief tty - One of the defines UART_CHANNEL_0 or UART_CHANNEL_1. Which defines a number of UART. */ uint8_t tty; ...... ..... ..... } UartDescriptor_t;
|
|
|
|
|
Dec 1 2008, 09:03
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Цитата(xelax @ Dec 1 2008, 12:21)  я не понимаю как это строчка может сообщать о результате операции.  Код tty ? (UDR1 = data) : (UDR0 = data); Выполняется (UDR1 = data) и результат выражения - это значение UDR1, которое надо предварительно прочитать, из-за того, что оно описано volatile. А то, что результат больше никому не нужен - это уже совсем другая история. Мораль: хочешь, чтобы оно просто записало в порт, так и скажи компилеру, а проктология - не компьютерная наука.  Так что это фича. И лишнее доказательство того, что компилер не может оградить программиста от ошибок.
|
|
|
|
|
Dec 1 2008, 09:28
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Цитата(Непомнящий Евгений @ Dec 1 2008, 13:15)  Т.е. получается что на один шаг оптимизатор срабатывает (выкидывая чтение в данном случае), а вот на два шага - в случае tty ? UDR1 = data : UDR0 = data - уже нет... Вот автор сказал, что ИАР выкинул лишнее чтение, а мне грустно: если компилер таким изящным манером исправил логическую ошибку программиста (согласитесь, ошибка ведь была), то где гарантия, что не бывает обратных ситуаций, т.е. абсолютно правильные с точки зрения логики действия программера цензурируются оптимизатором и это рождает ошибку. В общем, я все больше начинаю понимать gcc
|
|
|
|
|
Dec 1 2008, 09:54
|

Местный
  
Группа: Свой
Сообщений: 370
Регистрация: 7-11-06
Пользователь №: 22 035

|
Цитата(_Pasha @ Dec 1 2008, 12:28)  Вот автор сказал, что ИАР выкинул лишнее чтение, а мне грустно: если компилер таким изящным манером исправил логическую ошибку программиста (согласитесь, ошибка ведь была), то где гарантия, что не бывает обратных ситуаций, т.е. абсолютно правильные с точки зрения логики действия программера цензурируются оптимизатором и это рождает ошибку. В общем, я все больше начинаю понимать gcc  А собственно компилятор ошибок и не исправляет, если уж на то пошло. А скорее всего это строчки убираются в процессе оптимизации. Так что я бы не стал обвинять ни iar ни gcc. Просто как показала практика у iar оптимизация тщательней делается
|
|
|
|
|
Dec 1 2008, 10:44
|
Знающий
   
Группа: Свой
Сообщений: 771
Регистрация: 16-07-07
Из: Волгодонск
Пользователь №: 29 153

|
Цитата(gotty @ Dec 1 2008, 13:33)  Никакая оптимизация не должна выкидывать чтение volatile переменной. Ну тогда получается, что конструкции вида Код РЕГИСТР = значение; должны приводить к записи регистра и его последующему чтению. Т.е. запись регистра без чтения на С вообще невозможна
|
|
|
|
|
Dec 1 2008, 11:02
|
Знающий
   
Группа: Свой
Сообщений: 526
Регистрация: 24-08-07
Из: Беларусь, Минск
Пользователь №: 30 045

|
Цитата(Непомнящий Евгений @ Dec 1 2008, 12:44)  Ну тогда получается, что конструкции вида Код РЕГИСТР = значение; должны приводить к записи регистра и его последующему чтению. Т.е. запись регистра без чтения на С вообще невозможна  Надо различать конструкции. Оператор ?: подразумевает дальнейшее использование возвращаемого значения, а РЕГИСТР = значение - допускает.
|
|
|
|
|
Dec 1 2008, 11:51
|

фанат дивана
     
Группа: Свой
Сообщений: 3 387
Регистрация: 9-08-07
Из: Уфа
Пользователь №: 29 684

|
Цитата(gotty @ Dec 1 2008, 16:02)  Надо различать конструкции. Оператор ?: подразумевает дальнейшее использование возвращаемого значения, а РЕГИСТР = значение - допускает. Тогда по идее конструкция Код a = b ? func1() : func2(); должна сначала вызвать обе функции?
--------------------
Если бы я знал, что такое электричество...
|
|
|
|
|
Dec 1 2008, 12:07
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Цитата(AHTOXA @ Dec 1 2008, 15:51)  должна сначала вызвать обе функции?  А это тут при чем?  По теме Код (void) (tty ? UDR1 = data : UDR0 = data); Можете проверить, насколько это кошерно ? ЗЫ некошерно, уже проверил.  ЗЫ^2 последний WinAVR-20081118rc2 Код #include<avr/io.h> volatile uint8_t UR0,UR1,tty,data;
int main(void) { while(1) { tty ? UR1=data : UR0=data; } return(0); } ../test.c:9: error: lvalue required as left operand of assignment не оставляет шанса для кривотолков.
|
|
|
|
Сообщений в этой теме
xelax Что это фича или баг? Dec 1 2008, 07:46  Непомнящий Евгений Цитата(xelax @ Dec 1 2008, 11:18) 0x00CE ... Dec 1 2008, 08:23   xelax Цитата(Непомнящий Евгений @ Dec 1 2008, 11... Dec 1 2008, 09:12        xelax Цитата(gotty @ Dec 1 2008, 13:44) Никакая... Dec 1 2008, 10:51           xelax Цитата(_Pasha @ Dec 1 2008, 15:07) ../tes... Dec 1 2008, 12:30            _Pasha Цитата(xelax @ Dec 1 2008, 16:30) а так? ... Dec 1 2008, 12:38             _Pasha Цитата(_Pasha @ Dec 1 2008, 16:38) Понятн... Dec 1 2008, 15:12              ReAl Цитата(_Pasha @ Dec 1 2008, 17:12) Господ... Dec 11 2008, 09:13     Непомнящий Евгений Цитата(_Pasha @ Dec 1 2008, 12:28) Вот ав... Dec 1 2008, 10:30 Непомнящий Евгений Цитата(xelax @ Dec 1 2008, 10:46) И чем с... Dec 1 2008, 08:09 _Pasha Цитата(xelax @ Dec 1 2008, 11:46) но кото... Dec 1 2008, 08:10
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|