|
|
  |
проблемы в S-CPY, оптимизация в IAR |
|
|
|
Nov 7 2005, 06:59
|
Местный
  
Группа: Свой
Сообщений: 298
Регистрация: 29-08-05
Пользователь №: 8 064

|
При отладке на максимальной оптимизации по размеру наблюдаю следующие действия компилятора: Код ReadKeyb = work_keyb_cod ^ COL_MASK; work_keyb_cod = ReadKeyb; //Detect Code Row CodeCount = 0x00; while (!(ReadKeyb & 0x80)) { CodeCount++; ReadKeyb <<= 1; } компилятором интерпритируется верно как: ReadKeyb = work_keyb_cod ^ COL_MASK; 00007A 2701 EOR R16,R17 work_keyb_cod = ReadKeyb; 00007C 8305 STD Z+5,R16 CodeCount = 0x00; 00007E D08C RCALL ?Subroutine1
... CodeCount = 0x00; ?Subroutine1: 000198 E010 LDI R17,0x00 00019A CFE9 RJMP ?Subroutine4 ... ?Subroutine4: 00016E C002 RJMP 0x174 ... CodeCount++; 000170 9513 INC R17 ReadKeyb <<= 1; 000172 0F00 LSL R16 while (!(ReadKeyb & 0x80)) 000174 FB07 BST R16,7 000176 F7E6 BRTC 0x170 ...
тот же кусок с оптимизацией по скорости ReadKeyb = work_keyb_cod ^ COL_MASK; 00008A 2701 EOR R16,R17 work_keyb_cod = ReadKeyb; 00008C 8305 STD Z+5,R16 CodeCount = 0x00; 00008E E010 LDI R17,0x00 000090 C002 RJMP 0x096 CodeCount++; 000092 9513 INC R17 ReadKeyb <<= 1; 000094 0F00 LSL R16 while (!(ReadKeyb & 0x80)) 000096 FB07 BST R16,7 000098 F7E6 BRTC 0x92 Здесь тоже все правильно. Вопрос в другом - если при компиляции курсор "мыши" находиться в окне Disassembly то выполнение безобидной команды CodeCount = 0x00; ,в первом случае, приводит к вываливанию IAR, без каких либо недопустимых операций. Вот он был, а вот его нет :-). В чем может быть причина такого поведения ? Не было ли у кого подобных аномалий? И еще вопрос возникший в процессе изучения проблемы: где-то читал на этом форуме что порты в IAR объявлены как volatile - но просмотрев ioxxx.h и iomacro.h ничего подобного не встретил, так ли это ? когда переменная обьявлена volatile компилятор считает что она может изменяться независимо от него. С этим понятно, но вот что интересно: обьявляю ReadKeyb как volatile и вижу: Код ReadKeyb = work_keyb_cod ^ COL_MASK; 00009C 2710 EOR R17,R16 00009E 8318 ST Y,R17 work_keyb_cod = ReadKeyb; 0000A0 8108 LD R16,Y 0000A2 8305 STD Z+5,R16 CodeCount = 0x00; 0000A4 E000 LDI R16,0x00 0000A6 C004 RJMP 0x0B0 CodeCount++; 0000A8 9503 INC R16 ReadKeyb <<= 1; 0000AA 8118 LD R17,Y 0000AC 0F11 LSL R17 0000AE 8318 ST Y,R17 while (!(ReadKeyb & 0x80)) 0000B0 8118 LD R17,Y 0000B2 FF17 SBRS R17,7 0000B4 CFF9 RJMP 0x0A8 т.е компилятор честно прячет переменную в SRAM, дабы использовать её возможно измененное значение. из этого можно сделать вывод - volatile не только полезно, но и вредно. т.е. когда нужен оптимальный код применение volatile может его раздуть, но иногда это необходимая мера. Есть ли какие-то методы определения - делать volatile или нет ? Ведь каждый раз анализировать код утомительно...
|
|
|
|
|
Nov 7 2005, 08:01
|
Местный
  
Группа: Свой
Сообщений: 298
Регистрация: 29-08-05
Пользователь №: 8 064

|
Цитата(KRS @ Nov 7 2005, 10:42)  volatile нужно использовать когда перменная может поменять свое сотояние в перрывании или by hardware во всех остальных случаях компилер и сам прекрасно разберется.
Вообще я заметил что так лучше не только с volatile, а и с обычными перменными в памяти, загрузить копию во временную перменную, проделать необходимые действия и сохранить обратно, код намного оптимальнее получается т.е. все IO пространство если оно может меняться должно быть объявлено как volatile. А как тогда это описать ? или делать дополнительную переменную ? Цитата Вообще я заметил что так лучше не только с volatile, а и с обычными перменными в памяти, загрузить копию во временную перменную, проделать необходимые действия и сохранить обратно, код намного оптимальнее получается На максимальной оптимизации он так и делает  Ну или мне пока везет...
|
|
|
|
|
Nov 7 2005, 08:19
|
Местный
  
Группа: Свой
Сообщений: 298
Регистрация: 29-08-05
Пользователь №: 8 064

|
ну вот например io8535.h Код SFR_B(PINA, 0x19) /* Input Pins, Port A */ в iomacro.h Код #define SFR_B(_NAME, _ADDR) SFR_B_BITS(_NAME, _ADDR, \ Bit0,Bit1,Bit2,Bit3,Bit4,Bit5,Bit6,Bit7)
#define SFR_B_BITS(_NAME, _ADDR, _A,_B,_C,_D,_E,_F,_G,_H) \ __io union { \ unsigned char _NAME; /* The sfrb as 1 byte */ \ struct { /* The sfrb as 8 bits */ \ __BYTEBITS(_NAME, _A,_B,_C,_D,_E,_F,_G,_H) \ }; \ } @ _ADDR; и volatile нигде нет встречается только вот здесь, где же искать ? Код #define SFR_B_BITS_EXT(_NAME, _ADDR, _A,_B,_C,_D,_E,_F,_G,_H) \ __near __no_init volatile union { \ unsigned char _NAME; /* The sfrb as 1 byte */ \ struct { /* The sfrb as 8 bits */ \ __BYTEBITS(_NAME, _A,_B,_C,_D,_E,_F,_G,_H) \ }; \ } @ _ADDR;
|
|
|
|
|
Nov 7 2005, 09:29
|

Профессионал
    
Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555

|
Цитата(&-rey @ Nov 7 2005, 11:19)  ну вот например io8535.h Код SFR_B(PINA, 0x19) /* Input Pins, Port A */ в iomacro.h Код #define SFR_B(_NAME, _ADDR) SFR_B_BITS(_NAME, _ADDR, \ Bit0,Bit1,Bit2,Bit3,Bit4,Bit5,Bit6,Bit7)
#define SFR_B_BITS(_NAME, _ADDR, _A,_B,_C,_D,_E,_F,_G,_H) \ __io union { \ unsigned char _NAME; /* The sfrb as 1 byte */ \ struct { /* The sfrb as 8 bits */ \ __BYTEBITS(_NAME, _A,_B,_C,_D,_E,_F,_G,_H) \ }; \ } @ _ADDR; и volatile нигде нет встречается только вот здесь, где же искать ? Код #define SFR_B_BITS_EXT(_NAME, _ADDR, _A,_B,_C,_D,_E,_F,_G,_H) \ __near __no_init volatile union { \ unsigned char _NAME; /* The sfrb as 1 byte */ \ struct { /* The sfrb as 8 bits */ \ __BYTEBITS(_NAME, _A,_B,_C,_D,_E,_F,_G,_H) \ }; \ } @ _ADDR; Дело в том что часть портов находится в области к которй можно обратится командами in и out они объявлены с модификатором __io он сам по себе volatile а в новых девайсах где таких портов не хватает и они расположены в области sram они объявляются как volatile через макрос SFR_B_BITS_EXT
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|