Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: Глюк в IAR ARM 2.30А
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
zubr
Здравствуйте!
Хочу поделиться глюком, найденным мной:

unsigned short w;

w=0x55AA;
uart(w); //Вывод в UART - вижу 55AA
((unsigned char*)&w)[0]=0x33;
uart(w); //Вывод в UART - вижу 0033

Съел старший байт (обнулил) !!!

Если где-то в программе используется обращение к ((unsigned char*)&w)[1] то все нормально.
Отключал оптимизацию - не помогло.
А так вроде-бы нормальная конструкция для любого С... !?!?!
DASM
в данном случае переменная 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
zltigo
Цитата(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.
DASM
У меня 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-ую строку..
zltigo
Цитата(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


Претензии есть :-)
DASM
я вру что-ли ? Вот terminal IO вывод - "55AA 33". Хотя этот результат и по асму виден
zltigo
Цитата(DASM @ May 5 2006, 18:50) *
я вру что-ли ? Вот terminal IO вывод - "55AA 33". Хотя этот результат и по асму виден

Все аналогично :-) только результат "правильный" виден и так и сяк...
DASM
тогда не понял.. Вы считаете что после ((unsigned char*)&w)[0]=0x33;
unsigned short w должна стать равна 0x33 ???
zltigo
Цитата(DASM @ May 5 2006, 19:07) *
тогда не понял.. Вы считаете что после ((unsigned char*)&w)[0]=0x33;
unsigned short w должна стать равна 0x33 ???

Посмотрите внимательно. Выдается правильный результат 0x5533.
DASM
ну как может выдаваться 0x5533, если на момент вызова второго printf переменная w в Watch равна 0x0033 ???? И код у меня другой
Код
   20          ((unsigned char*)&w)[0]=0x33;
   \   0000001C   3300A0E3           MOV         R0,#+51
   \   00000020   0040A0E1          MOV         R4,R0
zltigo
Цитата(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\

Что еще?
DASM
ПОчему у нас разный код, вот в чем вопрос !!
zltigo
Цитата(DASM @ May 5 2006, 19:33) *
ПОчему у нас разный код, вот в чем вопрос !!

Без понятия. Работаю в своем обычном устаявшемся за пару десятилетий стиле, проблем с IAR не испытываю.
Свою командную строку со всеми ключами выдал.
DASM
положите если Вам несложно тогда весь проект с настройками (я скомпилировал в точности с Вашей ком. строкой, за исключением дополнительных -I , все равно код неверный.. Вобщем вопрос не снят
zltigo
Цитата(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;
        }
DASM
ну так нечестно =( У Вас может регистрового контента не хватило и он уже спокойно w в стеке разместил...
zltigo
Цитата(DASM @ May 5 2006, 23:09) *
ну так нечестно =( У Вас может регистрового контента не хватило и он уже спокойно w в стеке разместил...

Так я ASM приводил.....

А так (рабочий вариант) честно?
Код
void dummy()
{
    unsigned long w;
//-----^^^^^^^^^
    w=0x55AA;
    bprintf( "%4X", w );
    ((unsigned char*)&w)[0]=0x33;
    bprintf( "%4X", w );
}


А вот это фокус:
Код
void dummy()
{
  {
unsigned short w;
    w=0x55AA;
    bprintf( "%4X", w );
    ((unsigned char*)&w)[0]=(unsigned char)0x34;
    bprintf( "%4X", w );
  }
    
  {
unsigned short w;
    w=0x55AA;
    bprintf( "%4X", w );
    ((unsigned char*)&w)[0]=(unsigned char)0x35;
    bprintf( "%4X", w );
  }

  {
unsigned short w;
    w=0x55AA;
    bprintf( "%4X", w );
    ((unsigned char*)&w)[0]=(unsigned char)0x35;
    bprintf( "%4X", w );
  }
}


В общем можно багрепорт писать....

Ну а по warning - без вариантов всегда и везде выдается.
DASM
так повторили багу ? с long то все нормально, STRB нормально генерится и результаты тоже верные...
zltigo
Цитата(DASM @ May 5 2006, 23:54) *
так повторили багу ?

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

Ну а поповоду 'register' - разбирайтесь сами. Это РАБОТАЕТ всегда.
DASM
да мне то чего разбираться, таких хитрых конструкций не пишу и от иара ухожу =)) Главное дело принципа - с багом согласились и усе.
zltigo
Цитата(DASM @ May 6 2006, 00:05) *
да мне то чего разбираться

Ага, а 'бочку катить' безосновательно это можно :-( :
Цитата
А если в 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
DASM
стоп, какая бочка ??? IAR лажанулся, ADS нет... где бочка то ?
zltigo
Цитата(DASM @ May 6 2006, 00:14) *
стоп, какая бочка ??? IAR лажанулся, ADS нет... где бочка то ?

При явном указании 'register' ни IAR ни ADS не лажаюся и выдают warnig - лажается только DASM
не желающий видеть данный warning у IAR.
DASM
Очень интересно .. с Вашей командой строкой в ИАРе
"
Errors: none
Warnings: none
". М ы вторую страницу спорим, а Вы что-то утверждаете, не удосужившись скомпилировать просто main с этой лабудой/ И речь о наличии этого warning без указания register !
Для желающих повторить.
Код
int main()
{
        unsigned short w;
        w=0x55AA;
        printf( "%4X", w );
        ((unsigned char*)&w)[0]=0x33;
        printf( "%4X", w );
        return 0;
}

Ком строка
D:\EWARM4_31A\ARM\bin\iccarm.exe main.cpp -D LPC2000_IAR -lC d:\test -lA d:\test --remarks -o d:\1 -s0 --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:\EWARM4_31A\ARM\LIB\dl4tptinl8n.h -I D:\EWARM4_31A\ARM\INC
zltigo
Цитата(DASM @ May 6 2006, 00:26) *
а Вы что-то утверждаете, не удосужившись скомпилировать просто main с этой лабудой

Удосужился. Warning получается всегда и везде.

Компилим:
Код
      register unsigned short w;
//__^^^^^
        w=0x55AA;
        printf( "%4X", w );
        ((unsigned char*)&w)[0]=0x33;
        printf( "%4X", w );
        return 0;


Это именно помянутый Вами вариант:
Цитата
А если в ADS внагляк написать
register short int w,
то получаем недвусмысленное матюгательство...


Аналогичное ругательство выдаст и IAR.
DASM
без указания register ? В тоге мы что имеем ? Комилятор имеет право без нашей просьбы делать переменную register, согласен . Но потом IAR "забывает" об этом и выдает нам неверный результат. Так что лажа налицо
zltigo
Цитата(DASM @ May 6 2006, 00:31) *
Так что лажа налицо

Было два обинения
1. От автора топика - подтвердилось в определенных условиях.
2. Дополнительное Ваше по отсутствию 'warning' - НЕ ПОДТВЕРДИЛОСЬ.

И не надо прикрываясь '1', делать непонимающее лицо по поводу '2'.
DASM
Что не подтвердилось ? Я где-нибудь указывал про то, что выдает IAR в присутствии модификатора памяти register ? Да, я указал что ADS трактует это как error. Про warning у IAR при наличии модификатора register я не говорил. Говорилось лишь о том, что IAR сделал её таковой сам и облажался.
zltigo
Цитата(DASM @ May 6 2006, 01:00) *
Да, я указал что ADS трактует это как error.

Если-бы в указанном контесте перечислили еще 99 особенностей поведения ADS, то они несомненно
являлись-бы ЯВНЫМ противопоставлением IARу. Тем более в одном абзаце с 'жирной точкой':
Цитата
Мораль - пора завязывать с IAR
SpiritDance
Господа простите что вмешиваюсь у вас что работа закончилась?smile.gif)))
DASM
Не виновата я (с) Не каждый день обвиняют в подрыве продаж IAR, устоев капиталистического общества, растлении молодежи и мировом сионистком заговоре :-) Ладно, заканчиваем. Кстати у автора топика может какие-то вопросы остались ?
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.