|
Глюк в IAR ARM 2.30А |
|
|
|
May 5 2006, 13:54
|
Группа: Новичок
Сообщений: 1
Регистрация: 2-05-06
Пользователь №: 16 667
|
Здравствуйте! Хочу поделиться глюком, найденным мной:
unsigned short w;
w=0x55AA; uart(w); //Вывод в UART - вижу 55AA ((unsigned char*)&w)[0]=0x33; uart(w); //Вывод в UART - вижу 0033
Съел старший байт (обнулил) !!!
Если где-то в программе используется обращение к ((unsigned char*)&w)[1] то все нормально. Отключал оптимизацию - не помогло. А так вроде-бы нормальная конструкция для любого С... !?!?!
|
|
|
|
|
May 5 2006, 14:10
|
Гуру
Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493
|
в данном случае переменная w стала регистровой.. Если объявить её глобально - то всё работает. А вот какого ляда компилятор позволил операции взятия адреса к такой переменной.. (собственно адрес он и не брал, просто проигнорировал сей факт) - это действительно свинство. Если написать например такой код Код void foo (unsigned char* p) { *p = 1; }
int main() { unsigned short w; w=0x55AA; *((unsigned char*)&w)=0x33; foo ((unsigned char*)&w); return 0; } То все становится нормально, компилятор будет держать w в стеке... А без "foo" он этого не понял =( А вот компилятор ADS1.2 сделал все нормально... Код main PROC STMFD sp!,{r3,lr} LDR r0,|L1.40| STRH r0,[sp,#0] MOV r0,#0x33 STRB r0,[sp,#0] MOV r0,#0 LDMFD sp!,{r3,pc} |L1.40| DCD 0x000055aa ENDP А если в ADS внагляк написать register short int w, то получаем недвусмысленное матюгательство ""main.cpp", line 19: Error: C3022E: 'register' attribute for 'w' ignored when address taken main.cpp: 0 warnings, 1 error, 0 serious errors Мораль - пора завязывать с IAR
|
|
|
|
|
May 5 2006, 15:22
|
Гуру
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244
|
Цитата(zubr @ May 5 2006, 16:54) Здравствуйте! Хочу поделиться глюком, найденным мной: Жуткие вещи рассказываете.. Привожу к повторяемому виде: unsigned short w; w=0x55AA; printf( "%4X", w ); ((unsigned char*)&w)[0]=0x33; printf( "%4X", w ); IAR 4.31A работает правильно при любых вариантах оптимизации. Цитата register short int w, то получаем недвусмысленное матюгательство ""main.cpp", line 19: Error: C3022E: 'register' attribute for 'w' ignored when address taken main.cpp: 0 warnings, 1 error, 0 serious errors Естественно на такое безобразие IAR ругается не менее однозначно Warning [Pe138] : taking the address of a register variable is not allowed .... Цитата Мораль - пора завязывать с IAR Windows MUSTDIE, тьфу, IAR... А может проще: 1. Не подавлять warnings; 2. Надо завязывать с использованием антикварного компилятора 2.30.
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
May 5 2006, 15:37
|
Гуру
Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493
|
У меня 4.31.1.239. Во-первых никакого warning не дал. Во-вторых приведенный Вами вариант с printf тоже распечатал с ошибкой. Вот код Код 15 int main() 16 { \ main: \ 00000000 10402DE9 STMDB SP!,{R4,LR} ;; Push 17 unsigned short w; 18 w=0x55AA; \ 00000004 AA00A0E3 MOV R0,#+170 \ 00000008 550C80E3 ORR R0,R0,#0x5500 \ 0000000C 0040A0E1 MOV R4,R0 19 printf( "%4X", w ); \ 00000010 0410A0E1 MOV R1,R4 \ 00000014 080F8FE2 ADR R0,??main_0 ;; "%4X" \ 00000018 ........ _BLF printf,??printf??rA 20 ((unsigned char*)&w)[0]=0x33; \ 0000001C 3300A0E3 MOV R0,#+51 \ 00000020 0040A0E1 MOV R4,R0 21 printf( "%4X", w ); \ 00000024 0410A0E1 MOV R1,R4 \ 00000028 030F8FE2 ADR R0,??main_0 ;; "%4X" \ 0000002C ........ _BLF printf,??printf??rA Смотрим 20-ую строку..
|
|
|
|
|
May 5 2006, 15:48
|
Гуру
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244
|
Цитата(DASM @ May 5 2006, 18:37) У меня 4.31. Во-первых никакого warning не дал. Во-вторых приведенный Вами вариант с printf тоже распечатал с ошибкой Абсолютно такой-же IAR 4.31A и распечатал (оптимизация по скорости полная через 'галочку' в IDE и без оптимизации) правильно и warning выдал (ну надо warnings включить :-) ). Собственно пишу местами достаточно изощренный код, но на ошибку компилятора наступал только один раз, да и ту поправили еще в патче к 4.30. Ну а код у меня такой: Код LDR R1,??command_0+0x18 ;; 0x55aa MOV R0,SP STRH R1,[R0, #+10] ADR R4,??command_0+0x1C ;; "%4X" MOV R0,R4 _BLF bprintf,??bprintf??rT MOV R0,SP MOV R1,#+51 STRB R1,[R0, #+10] LDRH R1,[R0, #+10] MOV R0,R4 ??command_19: _BLF bprintf,??bprintf??rT Претензии есть :-)
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
May 5 2006, 16:30
|
Гуру
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244
|
Цитата(DASM @ May 5 2006, 19:16) ну как может выдаваться 0x5533, если на момент вызова второго printf переменная w в Watch равна 0x0033 ???? Ассемблерный код получившийся у меня я приводил. Отличия видны? Warning я тоже приводил. О наличии оного у IAR можете справиться по номеру. Командная строка компилятора: Код iccarm.exe D:\ARM_WORK\mt38\MAIN\command.c -D LPC2000_IAR -lC D:\ARM_WORK\mt38\Debug\List\ -lA D:\ARM_WORK\mt38\Debug\List\ --remarks -o D:\ ARM_WORK\mt38\Debug\Obj\ -s9 --debug --cpu_mode thumb --endian little --cpu ARM7TDMI-S --stack_align 4 --interwork --warnings_affect_exit_code --no_path_in_file_macros -e --require_prototypes --fpu None --dlib_config D:\IAR\Embedded Workbench\arm\LIB\dl4tptinl8n.h -I D:\ARM_WORK\mt38\..\COMMON\ RTOS\portable\IAR\LPC2000\ -I D:\ARM_WORK\mt38\..\COMMON\RTOS\include\ -I D:\ARM_WORK\mt38\..\COMMON\include\ -I D:\ARM_WORK\mt38\MAIN\include\ -I D:\IAR\Embedded Workbench\arm\INC\ Что еще?
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
|
May 5 2006, 19:53
|
Гуру
Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244
|
Цитата(DASM @ May 5 2006, 19:38) положите если Вам несложно тогда весь проект с настройками (я скомпилировал в точности с Вашей ком. строкой, за исключением дополнительных -I , все равно код неверный.. Вобщем вопрос не снят Весь - сложно. Отдельный тестовый не делался а упомянутые строки были засунуты в текущую сборку базы для очередной железки. В принципе, можете всунуть (в command() ) в когда-то давно присланный Вам для разборок с MT-Link проект. Код case 'xx': { unsigned short w; w=0x55AA; bprintf( "%4X", w ); ((unsigned char*)&w)[0]=0x33; bprintf( "%4X", w ); break; }
--------------------
Feci, quod potui, faciant meliora potentes
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|