Пишу код в WinAVR-20100110 :
Код
#include <avr/io.h>
#include <inttypes.h>
#include <avr/interrupt.h> // задает макросы sei() , cli()
#define KeyMask (1<<Btn1)|(1<<Btn2)
volatile register int8_t a asm ("r16");
int main (void)
{
sei();
a |= 1;
while(1)
{
asm ("nop ");
if (~(PINB)&(KeyMask))
{
PORTB=KeyMask;
a |= 0x02;
}
}
}
#include <inttypes.h>
#include <avr/interrupt.h> // задает макросы sei() , cli()
#define KeyMask (1<<Btn1)|(1<<Btn2)
volatile register int8_t a asm ("r16");
int main (void)
{
sei();
a |= 1;
while(1)
{
asm ("nop ");
if (~(PINB)&(KeyMask))
{
PORTB=KeyMask;
a |= 0x02;
}
}
}
После компиляции с оптимзацией = s , на выходе соответственно код привожу с опушенной инициализацией :
Код
+00000011: 9478 SEI Global Interrupt Enable
+00000012: E02C LDI R18,0x0C Load immediate
+00000013: 0000 NOP No operation
+00000014: B386 IN R24,0x16 In from I/O location
+00000015: E090 LDI R25,0x00 Load immediate
+00000016: 9580 COM R24 One's complement
+00000017: 9590 COM R25 One's complement
+00000018: 708C ANDI R24,0x0C Logical AND with immediate
+00000019: 7090 ANDI R25,0x00 Logical AND with immediate
+0000001A: 2B89 OR R24,R25 Logical OR
+0000001B: F3B9 BREQ PC-0x08 Branch if equal
+0000001C: BB28 OUT 0x18,R18 Out to I/O location
+0000001D: CFF5 RJMP PC-0x000A Relative jump
+00000012: E02C LDI R18,0x0C Load immediate
+00000013: 0000 NOP No operation
+00000014: B386 IN R24,0x16 In from I/O location
+00000015: E090 LDI R25,0x00 Load immediate
+00000016: 9580 COM R24 One's complement
+00000017: 9590 COM R25 One's complement
+00000018: 708C ANDI R24,0x0C Logical AND with immediate
+00000019: 7090 ANDI R25,0x00 Logical AND with immediate
+0000001A: 2B89 OR R24,R25 Logical OR
+0000001B: F3B9 BREQ PC-0x08 Branch if equal
+0000001C: BB28 OUT 0x18,R18 Out to I/O location
+0000001D: CFF5 RJMP PC-0x000A Relative jump
Т.е. компилятор проигнорировал квалификатор Volatile и убрал все операции с рег. r16 !
Вопрос : это особенность данного компилятора или я чегото незнаю о работе оноименного квалификатора ?