При отладке на максимальной оптимизации по размеру наблюдаю следующие действия компилятора:
Код
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 или нет ?
Ведь каждый раз анализировать код утомительно...